Posts: 13
Threads: 2
Joined: Jan 2014
Reputation:
0
01-10-2014, 02:00
(This post was last modified: 01-10-2014, 02:00 by LiL-Joker-69.)
Hey.
I need an plugin for my Server which displays a permanent Message for rules like:
Noscope,Hardscope,dragscope=Kick/Bann
at the left buttom.
Ty
Posts: 299
Threads: 1
Joined: Aug 2013
Reputation:
10
do you mean like a message on the hud?? If so use the Server Ad Plugin: http://www.itsmods.com/forum/Thread-Rele...verAd.html
Posts: 3,704
Threads: 147
Joined: Jan 2011
Reputation:
119
He wants iPrintLn, ServerAd is a bit spammish plugin.
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
Posts: 299
Threads: 1
Joined: Aug 2013
Reputation:
10
(01-10-2014, 04:34)SailorMoon Wrote: He wants iPrintLn, ServerAd is a bit spammish plugin.
uhm i think he wants it to stay on the screen but i guess he'll tell us
Posts: 8
Threads: 1
Joined: Apr 2013
Reputation:
1
01-11-2014, 14:36
(This post was last modified: 01-11-2014, 14:36 by frst_.)
Easy. it's working also on the teknomw3.
PHP Code: using Addon; using System; using System.Threading;
namespace plugin_test { public class plugin_test : CPlugin {
public override void OnServerLoad() { ServerPrint("Plugin Spam by frst_ loaded."); ThreadPool.QueueUserWorkItem(new WaitCallback(this.onSpam)); }
private void onSpam(object x) { while (true) { base.iPrintLn("Noscope,Hardscope,dragscope=Kick/Bann", null); SafeSleep(120); // seconds } }
public static void SafeSleep(int AmountSec) { int num = 0; while (num != AmountSec) { num++; Thread.Sleep(0x3e8); } } } }
Posts: 299
Threads: 1
Joined: Aug 2013
Reputation:
10
(01-11-2014, 14:36)frst_ Wrote: Easy. it's working also on the teknomw3.
PHP Code: using Addon; using System; using System.Threading;
namespace plugin_test { public class plugin_test : CPlugin {
public override void OnServerLoad() { ServerPrint("Plugin Spam by frst_ loaded."); ThreadPool.QueueUserWorkItem(new WaitCallback(this.onSpam)); }
private void onSpam(object x) { while (true) { base.iPrintLn("Noscope,Hardscope,dragscope=Kick/Bann", null); SafeSleep(120); // seconds } }
public static void SafeSleep(int AmountSec) { int num = 0; while (num != AmountSec) { num++; Thread.Sleep(0x3e8); } } } }
Threading tends to cause crashes on you server.
This wont cause crashes.
Spam.cs
PHP Code: using Addon; using System;
namespace message { public class message : CPlugin { public override void OnPlayerConnect(ServerClient client) { // Display a message to the client every 30 seconds. Timing.OnInterval(30000, client, () => { iPrintLn("Noscope,Hardscope,dragscope = Kick/Bann", client);
// Let the timer know to keep going. Return false to remove/stop the timer. return true; }); }
} }
Timing.cs: Credit: @ master131
PHP Code: using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; namespace Addon { // ***** Uncomment if using .NET Framework 2.0 .NET Framework 3.0, or .NET Framework 3.5 ***** // ***** Yes, all of it, seriously. ***** /* public delegate TResult Func<TResult>(); public delegate void Action(); public delegate void Action<T1, T2>(T1 arg1, T2 arg2); public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3); public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); public delegate void Action<T1, T2, T3, T4, T5, T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); public delegate void Action<T1, T2, T3, T4, T5, T6, T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); */ enum ParameterType { Entity = 1, String = 2, Vector = 4, Float = 5, Integer = 6 } class Parameter { private static readonly IntPtr EntityAddress = (IntPtr)0x01918900; private static readonly IntPtr ClientAddress = (IntPtr)0x4A0FE90; private readonly object _value; private readonly ParameterType _type; internal Parameter(object value, ParameterType type) { _value = value; _type = type; } public ParameterType Type { get { return _type; } } public object Value { get { return _value; } } public bool IsPlayer { get { return _type == ParameterType.Entity && (int)_value < 18; } } public bool IsEntity { get { return _type == ParameterType.Entity && (int)_value >= 18; } } public T As<T>() { if (typeof(T) == typeof(Entity)) return (T)(object)GetEntity(); if (typeof(T) == typeof(ServerClient)) return (T)(object)GetClient(); if (typeof(T) == typeof(bool) && _type == ParameterType.Integer) return (T)(object)((int)_value != 0); return (T)Convert.ChangeType(_value, typeof(T)); } public static implicit operator Parameter(string value) { return new Parameter(value, ParameterType.String); } public static implicit operator Parameter(int value) { return new Parameter(value, ParameterType.Integer); } public static implicit operator Parameter(float value) { return new Parameter(value, ParameterType.Float); } public static implicit operator Parameter(Vector value) { return new Parameter(value, ParameterType.Vector); } public static implicit operator Parameter(ServerClient client) { return new Parameter(client.ClientNum, ParameterType.Entity); } public static implicit operator Parameter(Entity entity) { return new Parameter(entity.EntityNum, ParameterType.Entity); } private Entity GetEntity() { // Get the constructor for the Entity class. var entityConstructors = typeof(Entity).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); // Invoke the constructor with no arguments. var entity = (Entity)entityConstructors[0].Invoke(null); // Call the internal SetInformation method with a pointer to the Entity. typeof(Entity).GetMethod("SetInformation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(entity, new object[] { GetEntityFromNum((int)_value) }); return entity; } private ServerClient GetClient() { // Get the constructor for the Client class. var clientConstructors = typeof(ServerClient).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); // Invoke the constructor with no arguments. var client = (ServerClient)clientConstructors[0].Invoke(null); // Call the internal SetInformation method with a pointer to the Entity. typeof(ServerClient).GetMethod("SetInformation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(client, new object[] { GetClientFromNum((int)_value) }); return client; } private static IntPtr GetEntityFromNum(int entityNum) { return (IntPtr)(EntityAddress.ToInt32() + entityNum * 0x274); } private static IntPtr GetClientFromNum(int clientNum) { return (IntPtr)(ClientAddress.ToInt32() + clientNum * 0x78690); } } static class Timing { class ServerTimer { public int Interval { get; set; } public long Time { get; set; } public ServerClient Target { get; set; } public Delegate Function { get; set; } } class ServerNotify { public int TargetNum { get; set; } public bool HasTarget { get; set; } public Delegate Function { get; set; } } [StructLayout(LayoutKind.Sequential)] struct Vec3 { public float X; public float Y; public float Z; public static implicit operator Vec3(Vector vector) { return new Vec3 { X = vector.X, Y = vector.Y, Z = vector.Z }; } public static implicit operator Vector(Vec3 vector) { return new Vector(vector.X, vector.Y, vector.Z); } } private static readonly byte[] ScrAddStringStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x57, // push edi 0xC7, 0x45, 0xFC, 0xD0, 0x11, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F11D0 0x8B, 0x7D, 0x08, // mov edi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5F, // pop edi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrAddObjectStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x56, // push esi 0xC7, 0x45, 0xFC, 0x50, 0x11, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F1150 0x8B, 0x75, 0x08, // mov esi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5E, // pop esi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrAddVectorStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x57, // push edi 0xC7, 0x45, 0xFC, 0xF0, 0x12, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F12F0 0x8B, 0x7D, 0x08, // mov edi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5F, // pop edi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrNotifyNumStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0xC7, 0x45, 0xFC, 0x00, 0xFD, 0x4E, 0x00, // mov dword ptr [ebp-4], 4EFD00 0x8B, 0x45, 0x0C, // mov eax, [ebp+C] 0xFF, 0x75, 0x14, // push [ebp+14] 0xFF, 0x75, 0x10, // push [ebp+10] 0xFF, 0x75, 0x08, // push [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x83, 0xC4, 0x0C, // add esp, C 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static byte[] VmExecuteHookStub = new byte[] { 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, <handler> 0xFF, 0xD0, // call eax 0x83, 0xC4, 0x0C, // add esp, 0Ch 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x83, 0xE4, 0xF8, // and esp, 0FFFFFFF8h 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, <dest> 0xFF, 0xE0, // jmp eax }; [DllImport("kernel32.dll", SetLastError = true)] static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type); private const uint MEM_COMMIT = 0x1000; private const uint MEM_RESERVE = 0x2000; private const uint PAGE_EXECUTE_READWRITE = 0x40; private const uint MB_ICONERROR = 0x10; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void GameScriptNotifyHandlerDelegate(int entity, uint type, IntPtr variableStack); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrAddFloatDelegate(float value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrAddIntegerDelegate(int value); [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private delegate void ScrAddStringDelegate(string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrGetEntityIdDelegate(int entityNum, int entityShift); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrAddObjectDelegate(int num); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrAddVectorDelegate(ref Vec3 vector); [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private delegate int ScrPrepareNotifyDelegate(string message, int zero, int messageLength); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrNotifyNumDelegate(int entNum, int entShift, int prepareResult, int paramCount); private static readonly IntPtr VirtualMachineExecuteAddress = (IntPtr)0x4EF610; private static readonly IntPtr GameScriptStringTablePointer = (IntPtr)0x1C122A4; private static readonly IntPtr GameScriptObjectTypeArray = (IntPtr)0x1D39804; private static readonly IntPtr GameScriptObjectToEntityLo = (IntPtr)0x1D39802; private static readonly IntPtr ScrAddFloatAddress = (IntPtr)0x4F1070; private static readonly IntPtr ScrAddIntegerAddress = (IntPtr)0x4F1020; private static readonly IntPtr ScrGetEntityIdAddress = (IntPtr)0x4EA450; private static readonly IntPtr ScrPrepareNotifyAddress = (IntPtr)0x4E7650; private static readonly List<ServerTimer> Timers = new List<ServerTimer>(); private static readonly Stopwatch Stopwatch = new Stopwatch(); private static readonly Dictionary<string, List<ServerNotify>> NotifyHandlers = new Dictionary<string, List<ServerNotify>>(); private static ScrAddFloatDelegate _scrAddFloatFunc; private static ScrAddIntegerDelegate _scrAddIntegerFunc; private static ScrAddStringDelegate _scrAddStringFunc; private static ScrGetEntityIdDelegate _scrGetEntityIdFunc; private static ScrAddObjectDelegate _scrAddObjectFunc; private static ScrAddVectorDelegate _scrAddVectorFunc; private static ScrPrepareNotifyDelegate _scrPrepareNotifyFunc; private static ScrNotifyNumDelegate _scrNotifyNumFunc; private static GCHandle _gch; private static IntPtr _scrNotifyStack = IntPtr.Zero; private static IntPtr _scrAddStringFuncAddress = IntPtr.Zero; private static IntPtr _scrAddObjectFuncAddress = IntPtr.Zero; private static IntPtr _scrAddVectorFuncAddress = IntPtr.Zero; private static IntPtr _scrNotifyNumFuncAddress = IntPtr.Zero; static Timing() { HookGameScriptNotifyHandler(); Stopwatch.Start(); } private static void PushFloat(float value) { if (_scrAddFloatFunc == null) _scrAddFloatFunc = (ScrAddFloatDelegate)Marshal.GetDelegateForFunctionPointer(ScrAddFloatAddress, typeof(ScrAddFloatDelegate)); _scrAddFloatFunc(value); } private static void PushInteger(int value) { if (_scrAddIntegerFunc == null) _scrAddIntegerFunc = (ScrAddIntegerDelegate)Marshal.GetDelegateForFunctionPointer(ScrAddIntegerAddress, typeof(ScrAddIntegerDelegate)); _scrAddIntegerFunc(value); } private static void PushString(string value) { if (_scrAddStringFuncAddress == IntPtr.Zero) { _scrAddStringFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddStringStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddStringFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddStringStub, 0, _scrAddStringFuncAddress, ScrAddStringStub.Length); _scrAddStringFunc = (ScrAddStringDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddStringFuncAddress, typeof(ScrAddStringDelegate)); } _scrAddStringFunc(value); } private static void PushEntity(int entityNum) { if (_scrGetEntityIdFunc == null) _scrGetEntityIdFunc = (ScrGetEntityIdDelegate)Marshal.GetDelegateForFunctionPointer(ScrGetEntityIdAddress, typeof(ScrGetEntityIdDelegate)); if (_scrAddObjectFuncAddress == IntPtr.Zero) { _scrAddObjectFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddObjectStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddObjectFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddObjectStub, 0, _scrAddObjectFuncAddress, ScrAddObjectStub.Length); _scrAddObjectFunc = (ScrAddObjectDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddObjectFuncAddress, typeof(ScrAddObjectDelegate)); } int result = _scrGetEntityIdFunc(entityNum, entityNum >> 16); _scrAddObjectFunc(result); } private static void PushVector(Vector vector) { if (_scrAddVectorFuncAddress == IntPtr.Zero) { _scrAddVectorFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddVectorStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddVectorFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddVectorStub, 0, _scrAddVectorFuncAddress, ScrAddVectorStub.Length); _scrAddVectorFunc = (ScrAddVectorDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddVectorFuncAddress, typeof(ScrAddVectorDelegate)); } Vec3 vec = vector; _scrAddVectorFunc(ref vec); } public static void Notify(Entity entity, string message, params Parameter[] parameters) { Notify(entity.EntityNum, message, parameters); } public static void Notify(ServerClient client, string message, params Parameter[] parameters) { Notify(client.ClientNum, message, parameters); } private static void Notify(int entNum, string message, params Parameter[] parameters) { if (_scrPrepareNotifyFunc == null) _scrPrepareNotifyFunc = (ScrPrepareNotifyDelegate)Marshal.GetDelegateForFunctionPointer(ScrPrepareNotifyAddress, typeof(ScrPrepareNotifyDelegate)); if (_scrNotifyNumFuncAddress == IntPtr.Zero) { _scrNotifyNumFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrNotifyNumStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrNotifyNumFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrNotifyNumStub, 0, _scrNotifyNumFuncAddress, ScrNotifyNumStub.Length); _scrNotifyNumFunc = (ScrNotifyNumDelegate)Marshal.GetDelegateForFunctionPointer(_scrNotifyNumFuncAddress, typeof(ScrNotifyNumDelegate)); } Array.Reverse(parameters); foreach (var param in parameters) { switch (param.Type) { case ParameterType.Float: PushFloat(Convert.ToSingle(param.Value)); break; case ParameterType.Integer: PushInteger(Convert.ToInt32(param.Value)); break; case ParameterType.String: PushString(Convert.ToString(param.Value)); break; case ParameterType.Entity: PushEntity(Convert.ToInt32(param.Value)); break; case ParameterType.Vector: PushVector((Vector)param.Value); break; } } int result = _scrPrepareNotifyFunc(message, 0, message.Length + 1); _scrNotifyNumFunc(entNum, entNum >> 16, result, parameters.Length); } private static void HookGameScriptNotifyHandler() { var handler = new GameScriptNotifyHandlerDelegate(GameScriptNotifyHandlerHook); _gch = GCHandle.Alloc(handler); // Prevent GC from relocating/freeing function. var handlerAddress = Marshal.GetFunctionPointerForDelegate(handler); var hookStub = VirtualAlloc(IntPtr.Zero, (UIntPtr)VmExecuteHookStub.Length, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); BitConverter.GetBytes(handlerAddress.ToInt32()).CopyTo(VmExecuteHookStub, 16); BitConverter.GetBytes(VirtualMachineExecuteAddress.ToInt32() + 6).CopyTo(VmExecuteHookStub, 32); Marshal.Copy(VmExecuteHookStub, 0, hookStub, VmExecuteHookStub.Length); SetJmpHook(VirtualMachineExecuteAddress, hookStub); } private static void SetJmpHook(IntPtr original, IntPtr destination) { uint oldProtect; VirtualProtect(original, (UIntPtr)5, PAGE_EXECUTE_READWRITE, out oldProtect); var hook = new byte[5]; hook[0] = 0xE9; BitConverter.GetBytes((destination.ToInt32() - original.ToInt32()) - 5).CopyTo(hook, 1); Marshal.Copy(hook, 0, original, hook.Length); VirtualProtect(original, (UIntPtr)5, oldProtect, out oldProtect); } private static int GetObjectType(int @object) { return Marshal.ReadInt32(GameScriptObjectTypeArray, 8 * @object); } private static IntPtr GetVariableStackValueFromIndex(int index) { return (IntPtr)(_scrNotifyStack.ToInt32() + -8 * index); } private static object[] GetParameters(int argumentCount) { var param = new object[argumentCount]; for (int i = 0; i < argumentCount; i++) { var paramType = (ParameterType)Marshal.ReadInt32(GetVariableStackValueFromIndex(i), 4); object value = null; switch (paramType) { case ParameterType.Integer: value = Marshal.ReadInt32(GetVariableStackValueFromIndex(i)); break; case ParameterType.String: int stringIndex = Marshal.ReadInt16(GetVariableStackValueFromIndex(i)); value = Marshal.PtrToStringAnsi((IntPtr)(Marshal.ReadInt32(GameScriptStringTablePointer) + 12 * stringIndex + 4)); break; case ParameterType.Float: value = Marshal.PtrToStructure(GetVariableStackValueFromIndex(i), typeof(float)); break; case ParameterType.Entity: int entityObjectId = Marshal.ReadInt32(GetVariableStackValueFromIndex(i)); value = ScriptObjectIDToEntityNum(entityObjectId); break; case ParameterType.Vector: value = (Vector)(Vec3)Marshal.PtrToStructure(Marshal.ReadIntPtr(GetVariableStackValueFromIndex(i)), typeof(Vec3)); break; } param[i] = new Parameter(value, paramType); } return param; } private static int ScriptObjectIDToEntityNum(int scriptObjectId) { var loword = (uint)(Marshal.ReadInt16(GameScriptObjectToEntityLo, 8 * scriptObjectId)); var hiword = (uint)(Marshal.ReadInt32(GameScriptObjectTypeArray, 8 * scriptObjectId) >> 8); return (int)((hiword << 16) | (loword & 0xFFFF)); } private static int GetNotifyArgumentCount() { int argumentCount = 0; if (Marshal.ReadInt32(_scrNotifyStack, 4) != 8) { for (int i = _scrNotifyStack.ToInt32(); Marshal.ReadInt32((IntPtr)i, 4) != 8; i -= 8) argumentCount++; } return argumentCount; } private static void DispatchMessage(int targetEntityNum, string message) { foreach (var handler in NotifyHandlers[message]) { // Check if the handler specified a client or entity, if so, check the client num. if (handler.HasTarget && handler.TargetNum != targetEntityNum) continue; var handlerParams = handler.Function.Method.GetParameters(); // Check if the handler function has parameters. if (handlerParams.Length > 0) { // Calculate the number of arguments. int argumentCount = GetNotifyArgumentCount(); // Get the parameters. object[] parameters = GetParameters(argumentCount); // Fix the parameters if the user omitted some of them. var fixedParameters = new object[handlerParams.Length]; Array.Copy(parameters, fixedParameters, fixedParameters.Length); // Dynamically invoke the function. handler.Function.DynamicInvoke(fixedParameters); } else { // Perform a dynamic invoke with no arguments. handler.Function.DynamicInvoke(); } } } private static void HandleNotifyEvent(int entity, uint type) { if (type == 0) return; // Get the current message address. var messageAddress = (IntPtr)(Marshal.ReadInt32(GameScriptStringTablePointer) + 12 * type + 4); if (messageAddress == IntPtr.Zero) return; int targetEntityNum = -1; // Check if the script object type is an entity/client. if (GetObjectType(entity) == 21) { // Convert the script object ID to an entity/client num. targetEntityNum = ScriptObjectIDToEntityNum(entity); } // Get the current message. string message = Marshal.PtrToStringAnsi(messageAddress); // Check the message is valid and notify the handlers. if (string.IsNullOrEmpty(message) || !NotifyHandlers.ContainsKey(message)) return; try { DispatchMessage(targetEntityNum, message); } catch (Exception ex) { // Catch any errors and display it as a message box since there's no way to // log it without a plugin instance. MessageBox(IntPtr.Zero, ex.ToString(), "HandleNotifyEvent failed.", MB_ICONERROR); } } private static void GameScriptNotifyHandlerHook(int entity, uint type, IntPtr variableStack) { _scrNotifyStack = variableStack; HandleNotifyEvent(entity, type); } public static void OnInterval(int interval, ServerClient target, Func<bool> function) { Timers.Add(new ServerTimer { Interval = interval, Function = function, Target = target }); } public static void OnInterval(int interval, Func<bool> function) { Timers.Add(new ServerTimer { Interval = interval, Function = function }); } public static void AfterDelay(int delay, ServerClient target, Action action) { Timers.Add(new ServerTimer { Interval = -1, Time = Stopwatch.ElapsedMilliseconds + delay, Function = action, Target = target }); } public static void AfterDelay(int delay, Action action) { Timers.Add(new ServerTimer { Interval = -1, Time = Stopwatch.ElapsedMilliseconds + delay, Function = action }); } public static void ProcessFrame(List<ServerClient> clients) { var currentTime = Stopwatch.ElapsedMilliseconds; foreach (var timer in Timers.ToArray()) { if (currentTime < timer.Time) continue; if (timer.Target != null && clients.FindIndex(sc => sc.XUID == timer.Target.XUID) == -1) { Timers.Remove(timer); continue; } object returnValue = timer.Function.DynamicInvoke(); if (timer.Interval == -1 || timer.Function.Method.ReturnType == typeof(bool) && !(bool)returnValue) { Timers.Remove(timer); } else { timer.Time = currentTime + timer.Interval; } } } private static void OnNotify(string type, Delegate action, bool hasTarget, int targetNum) { var serverNotify = new ServerNotify { Function = action, HasTarget = hasTarget, TargetNum = targetNum }; if (NotifyHandlers.ContainsKey(type)) NotifyHandlers[type].Add(serverNotify); else NotifyHandlers.Add(type, new List<ServerNotify>(new[] { serverNotify })); } public static void OnNotify(string type, Action action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, ServerClient client, Action action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, Entity entity, Action action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } } }
Posts: 8
Threads: 1
Joined: Apr 2013
Reputation:
1
(01-11-2014, 18:05)Casper Wrote: (01-11-2014, 14:36)frst_ Wrote: Easy. it's working also on the teknomw3.
PHP Code: using Addon; using System; using System.Threading;
namespace plugin_test { public class plugin_test : CPlugin {
public override void OnServerLoad() { ServerPrint("Plugin Spam by frst_ loaded."); ThreadPool.QueueUserWorkItem(new WaitCallback(this.onSpam)); }
private void onSpam(object x) { while (true) { base.iPrintLn("Noscope,Hardscope,dragscope=Kick/Bann", null); SafeSleep(120); // seconds } }
public static void SafeSleep(int AmountSec) { int num = 0; while (num != AmountSec) { num++; Thread.Sleep(0x3e8); } } } }
Threading tends to cause crashes on you server.
This wont cause crashes. ![Smile Smile](https://www.itsmods.com/forum/images/smilies/smile.gif)
Spam.cs
PHP Code: using Addon; using System;
namespace message { public class message : CPlugin { public override void OnPlayerConnect(ServerClient client) { // Display a message to the client every 30 seconds. Timing.OnInterval(30000, client, () => { iPrintLn("Noscope,Hardscope,dragscope = Kick/Bann", client);
// Let the timer know to keep going. Return false to remove/stop the timer. return true; }); }
} }
Timing.cs: Credit: @master131
PHP Code: using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; namespace Addon { // ***** Uncomment if using .NET Framework 2.0 .NET Framework 3.0, or .NET Framework 3.5 ***** // ***** Yes, all of it, seriously. ***** /* public delegate TResult Func<TResult>(); public delegate void Action(); public delegate void Action<T1, T2>(T1 arg1, T2 arg2); public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3); public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); public delegate void Action<T1, T2, T3, T4, T5, T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); public delegate void Action<T1, T2, T3, T4, T5, T6, T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); public delegate void Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); */ enum ParameterType { Entity = 1, String = 2, Vector = 4, Float = 5, Integer = 6 } class Parameter { private static readonly IntPtr EntityAddress = (IntPtr)0x01918900; private static readonly IntPtr ClientAddress = (IntPtr)0x4A0FE90; private readonly object _value; private readonly ParameterType _type; internal Parameter(object value, ParameterType type) { _value = value; _type = type; } public ParameterType Type { get { return _type; } } public object Value { get { return _value; } } public bool IsPlayer { get { return _type == ParameterType.Entity && (int)_value < 18; } } public bool IsEntity { get { return _type == ParameterType.Entity && (int)_value >= 18; } } public T As<T>() { if (typeof(T) == typeof(Entity)) return (T)(object)GetEntity(); if (typeof(T) == typeof(ServerClient)) return (T)(object)GetClient(); if (typeof(T) == typeof(bool) && _type == ParameterType.Integer) return (T)(object)((int)_value != 0); return (T)Convert.ChangeType(_value, typeof(T)); } public static implicit operator Parameter(string value) { return new Parameter(value, ParameterType.String); } public static implicit operator Parameter(int value) { return new Parameter(value, ParameterType.Integer); } public static implicit operator Parameter(float value) { return new Parameter(value, ParameterType.Float); } public static implicit operator Parameter(Vector value) { return new Parameter(value, ParameterType.Vector); } public static implicit operator Parameter(ServerClient client) { return new Parameter(client.ClientNum, ParameterType.Entity); } public static implicit operator Parameter(Entity entity) { return new Parameter(entity.EntityNum, ParameterType.Entity); } private Entity GetEntity() { // Get the constructor for the Entity class. var entityConstructors = typeof(Entity).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); // Invoke the constructor with no arguments. var entity = (Entity)entityConstructors[0].Invoke(null); // Call the internal SetInformation method with a pointer to the Entity. typeof(Entity).GetMethod("SetInformation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(entity, new object[] { GetEntityFromNum((int)_value) }); return entity; } private ServerClient GetClient() { // Get the constructor for the Client class. var clientConstructors = typeof(ServerClient).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); // Invoke the constructor with no arguments. var client = (ServerClient)clientConstructors[0].Invoke(null); // Call the internal SetInformation method with a pointer to the Entity. typeof(ServerClient).GetMethod("SetInformation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(client, new object[] { GetClientFromNum((int)_value) }); return client; } private static IntPtr GetEntityFromNum(int entityNum) { return (IntPtr)(EntityAddress.ToInt32() + entityNum * 0x274); } private static IntPtr GetClientFromNum(int clientNum) { return (IntPtr)(ClientAddress.ToInt32() + clientNum * 0x78690); } } static class Timing { class ServerTimer { public int Interval { get; set; } public long Time { get; set; } public ServerClient Target { get; set; } public Delegate Function { get; set; } } class ServerNotify { public int TargetNum { get; set; } public bool HasTarget { get; set; } public Delegate Function { get; set; } } [StructLayout(LayoutKind.Sequential)] struct Vec3 { public float X; public float Y; public float Z; public static implicit operator Vec3(Vector vector) { return new Vec3 { X = vector.X, Y = vector.Y, Z = vector.Z }; } public static implicit operator Vector(Vec3 vector) { return new Vector(vector.X, vector.Y, vector.Z); } } private static readonly byte[] ScrAddStringStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x57, // push edi 0xC7, 0x45, 0xFC, 0xD0, 0x11, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F11D0 0x8B, 0x7D, 0x08, // mov edi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5F, // pop edi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrAddObjectStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x56, // push esi 0xC7, 0x45, 0xFC, 0x50, 0x11, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F1150 0x8B, 0x75, 0x08, // mov esi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5E, // pop esi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrAddVectorStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0x57, // push edi 0xC7, 0x45, 0xFC, 0xF0, 0x12, 0x4F, 0x00, // mov dword ptr [ebp-4], 4F12F0 0x8B, 0x7D, 0x08, // mov edi, [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x5F, // pop edi 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static readonly byte[] ScrNotifyNumStub = new byte[] { 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x51, // push ecx 0xC7, 0x45, 0xFC, 0x00, 0xFD, 0x4E, 0x00, // mov dword ptr [ebp-4], 4EFD00 0x8B, 0x45, 0x0C, // mov eax, [ebp+C] 0xFF, 0x75, 0x14, // push [ebp+14] 0xFF, 0x75, 0x10, // push [ebp+10] 0xFF, 0x75, 0x08, // push [ebp+8] 0xFF, 0x55, 0xFC, // call [ebp-4] 0x83, 0xC4, 0x0C, // add esp, C 0x8B, 0xE5, // mov esp, ebp 0x5D, // pop ebp 0xC3 // retn }; private static byte[] VmExecuteHookStub = new byte[] { 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0x8B, 0x44, 0x24, 0x0C, // mov eax, [esp+0Ch] 0x50, // push eax 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, <handler> 0xFF, 0xD0, // call eax 0x83, 0xC4, 0x0C, // add esp, 0Ch 0x55, // push ebp 0x8B, 0xEC, // mov ebp, esp 0x83, 0xE4, 0xF8, // and esp, 0FFFFFFF8h 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, <dest> 0xFF, 0xE0, // jmp eax }; [DllImport("kernel32.dll", SetLastError = true)] static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type); private const uint MEM_COMMIT = 0x1000; private const uint MEM_RESERVE = 0x2000; private const uint PAGE_EXECUTE_READWRITE = 0x40; private const uint MB_ICONERROR = 0x10; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void GameScriptNotifyHandlerDelegate(int entity, uint type, IntPtr variableStack); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrAddFloatDelegate(float value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrAddIntegerDelegate(int value); [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private delegate void ScrAddStringDelegate(string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int ScrGetEntityIdDelegate(int entityNum, int entityShift); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrAddObjectDelegate(int num); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrAddVectorDelegate(ref Vec3 vector); [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private delegate int ScrPrepareNotifyDelegate(string message, int zero, int messageLength); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ScrNotifyNumDelegate(int entNum, int entShift, int prepareResult, int paramCount); private static readonly IntPtr VirtualMachineExecuteAddress = (IntPtr)0x4EF610; private static readonly IntPtr GameScriptStringTablePointer = (IntPtr)0x1C122A4; private static readonly IntPtr GameScriptObjectTypeArray = (IntPtr)0x1D39804; private static readonly IntPtr GameScriptObjectToEntityLo = (IntPtr)0x1D39802; private static readonly IntPtr ScrAddFloatAddress = (IntPtr)0x4F1070; private static readonly IntPtr ScrAddIntegerAddress = (IntPtr)0x4F1020; private static readonly IntPtr ScrGetEntityIdAddress = (IntPtr)0x4EA450; private static readonly IntPtr ScrPrepareNotifyAddress = (IntPtr)0x4E7650; private static readonly List<ServerTimer> Timers = new List<ServerTimer>(); private static readonly Stopwatch Stopwatch = new Stopwatch(); private static readonly Dictionary<string, List<ServerNotify>> NotifyHandlers = new Dictionary<string, List<ServerNotify>>(); private static ScrAddFloatDelegate _scrAddFloatFunc; private static ScrAddIntegerDelegate _scrAddIntegerFunc; private static ScrAddStringDelegate _scrAddStringFunc; private static ScrGetEntityIdDelegate _scrGetEntityIdFunc; private static ScrAddObjectDelegate _scrAddObjectFunc; private static ScrAddVectorDelegate _scrAddVectorFunc; private static ScrPrepareNotifyDelegate _scrPrepareNotifyFunc; private static ScrNotifyNumDelegate _scrNotifyNumFunc; private static GCHandle _gch; private static IntPtr _scrNotifyStack = IntPtr.Zero; private static IntPtr _scrAddStringFuncAddress = IntPtr.Zero; private static IntPtr _scrAddObjectFuncAddress = IntPtr.Zero; private static IntPtr _scrAddVectorFuncAddress = IntPtr.Zero; private static IntPtr _scrNotifyNumFuncAddress = IntPtr.Zero; static Timing() { HookGameScriptNotifyHandler(); Stopwatch.Start(); } private static void PushFloat(float value) { if (_scrAddFloatFunc == null) _scrAddFloatFunc = (ScrAddFloatDelegate)Marshal.GetDelegateForFunctionPointer(ScrAddFloatAddress, typeof(ScrAddFloatDelegate)); _scrAddFloatFunc(value); } private static void PushInteger(int value) { if (_scrAddIntegerFunc == null) _scrAddIntegerFunc = (ScrAddIntegerDelegate)Marshal.GetDelegateForFunctionPointer(ScrAddIntegerAddress, typeof(ScrAddIntegerDelegate)); _scrAddIntegerFunc(value); } private static void PushString(string value) { if (_scrAddStringFuncAddress == IntPtr.Zero) { _scrAddStringFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddStringStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddStringFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddStringStub, 0, _scrAddStringFuncAddress, ScrAddStringStub.Length); _scrAddStringFunc = (ScrAddStringDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddStringFuncAddress, typeof(ScrAddStringDelegate)); } _scrAddStringFunc(value); } private static void PushEntity(int entityNum) { if (_scrGetEntityIdFunc == null) _scrGetEntityIdFunc = (ScrGetEntityIdDelegate)Marshal.GetDelegateForFunctionPointer(ScrGetEntityIdAddress, typeof(ScrGetEntityIdDelegate)); if (_scrAddObjectFuncAddress == IntPtr.Zero) { _scrAddObjectFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddObjectStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddObjectFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddObjectStub, 0, _scrAddObjectFuncAddress, ScrAddObjectStub.Length); _scrAddObjectFunc = (ScrAddObjectDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddObjectFuncAddress, typeof(ScrAddObjectDelegate)); } int result = _scrGetEntityIdFunc(entityNum, entityNum >> 16); _scrAddObjectFunc(result); } private static void PushVector(Vector vector) { if (_scrAddVectorFuncAddress == IntPtr.Zero) { _scrAddVectorFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrAddVectorStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrAddVectorFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrAddVectorStub, 0, _scrAddVectorFuncAddress, ScrAddVectorStub.Length); _scrAddVectorFunc = (ScrAddVectorDelegate)Marshal.GetDelegateForFunctionPointer(_scrAddVectorFuncAddress, typeof(ScrAddVectorDelegate)); } Vec3 vec = vector; _scrAddVectorFunc(ref vec); } public static void Notify(Entity entity, string message, params Parameter[] parameters) { Notify(entity.EntityNum, message, parameters); } public static void Notify(ServerClient client, string message, params Parameter[] parameters) { Notify(client.ClientNum, message, parameters); } private static void Notify(int entNum, string message, params Parameter[] parameters) { if (_scrPrepareNotifyFunc == null) _scrPrepareNotifyFunc = (ScrPrepareNotifyDelegate)Marshal.GetDelegateForFunctionPointer(ScrPrepareNotifyAddress, typeof(ScrPrepareNotifyDelegate)); if (_scrNotifyNumFuncAddress == IntPtr.Zero) { _scrNotifyNumFuncAddress = VirtualAlloc(IntPtr.Zero, (UIntPtr)ScrNotifyNumStub.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (_scrNotifyNumFuncAddress == IntPtr.Zero) return; Marshal.Copy(ScrNotifyNumStub, 0, _scrNotifyNumFuncAddress, ScrNotifyNumStub.Length); _scrNotifyNumFunc = (ScrNotifyNumDelegate)Marshal.GetDelegateForFunctionPointer(_scrNotifyNumFuncAddress, typeof(ScrNotifyNumDelegate)); } Array.Reverse(parameters); foreach (var param in parameters) { switch (param.Type) { case ParameterType.Float: PushFloat(Convert.ToSingle(param.Value)); break; case ParameterType.Integer: PushInteger(Convert.ToInt32(param.Value)); break; case ParameterType.String: PushString(Convert.ToString(param.Value)); break; case ParameterType.Entity: PushEntity(Convert.ToInt32(param.Value)); break; case ParameterType.Vector: PushVector((Vector)param.Value); break; } } int result = _scrPrepareNotifyFunc(message, 0, message.Length + 1); _scrNotifyNumFunc(entNum, entNum >> 16, result, parameters.Length); } private static void HookGameScriptNotifyHandler() { var handler = new GameScriptNotifyHandlerDelegate(GameScriptNotifyHandlerHook); _gch = GCHandle.Alloc(handler); // Prevent GC from relocating/freeing function. var handlerAddress = Marshal.GetFunctionPointerForDelegate(handler); var hookStub = VirtualAlloc(IntPtr.Zero, (UIntPtr)VmExecuteHookStub.Length, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); BitConverter.GetBytes(handlerAddress.ToInt32()).CopyTo(VmExecuteHookStub, 16); BitConverter.GetBytes(VirtualMachineExecuteAddress.ToInt32() + 6).CopyTo(VmExecuteHookStub, 32); Marshal.Copy(VmExecuteHookStub, 0, hookStub, VmExecuteHookStub.Length); SetJmpHook(VirtualMachineExecuteAddress, hookStub); } private static void SetJmpHook(IntPtr original, IntPtr destination) { uint oldProtect; VirtualProtect(original, (UIntPtr)5, PAGE_EXECUTE_READWRITE, out oldProtect); var hook = new byte[5]; hook[0] = 0xE9; BitConverter.GetBytes((destination.ToInt32() - original.ToInt32()) - 5).CopyTo(hook, 1); Marshal.Copy(hook, 0, original, hook.Length); VirtualProtect(original, (UIntPtr)5, oldProtect, out oldProtect); } private static int GetObjectType(int @object) { return Marshal.ReadInt32(GameScriptObjectTypeArray, 8 * @object); } private static IntPtr GetVariableStackValueFromIndex(int index) { return (IntPtr)(_scrNotifyStack.ToInt32() + -8 * index); } private static object[] GetParameters(int argumentCount) { var param = new object[argumentCount]; for (int i = 0; i < argumentCount; i++) { var paramType = (ParameterType)Marshal.ReadInt32(GetVariableStackValueFromIndex(i), 4); object value = null; switch (paramType) { case ParameterType.Integer: value = Marshal.ReadInt32(GetVariableStackValueFromIndex(i)); break; case ParameterType.String: int stringIndex = Marshal.ReadInt16(GetVariableStackValueFromIndex(i)); value = Marshal.PtrToStringAnsi((IntPtr)(Marshal.ReadInt32(GameScriptStringTablePointer) + 12 * stringIndex + 4)); break; case ParameterType.Float: value = Marshal.PtrToStructure(GetVariableStackValueFromIndex(i), typeof(float)); break; case ParameterType.Entity: int entityObjectId = Marshal.ReadInt32(GetVariableStackValueFromIndex(i)); value = ScriptObjectIDToEntityNum(entityObjectId); break; case ParameterType.Vector: value = (Vector)(Vec3)Marshal.PtrToStructure(Marshal.ReadIntPtr(GetVariableStackValueFromIndex(i)), typeof(Vec3)); break; } param[i] = new Parameter(value, paramType); } return param; } private static int ScriptObjectIDToEntityNum(int scriptObjectId) { var loword = (uint)(Marshal.ReadInt16(GameScriptObjectToEntityLo, 8 * scriptObjectId)); var hiword = (uint)(Marshal.ReadInt32(GameScriptObjectTypeArray, 8 * scriptObjectId) >> 8); return (int)((hiword << 16) | (loword & 0xFFFF)); } private static int GetNotifyArgumentCount() { int argumentCount = 0; if (Marshal.ReadInt32(_scrNotifyStack, 4) != 8) { for (int i = _scrNotifyStack.ToInt32(); Marshal.ReadInt32((IntPtr)i, 4) != 8; i -= 8) argumentCount++; } return argumentCount; } private static void DispatchMessage(int targetEntityNum, string message) { foreach (var handler in NotifyHandlers[message]) { // Check if the handler specified a client or entity, if so, check the client num. if (handler.HasTarget && handler.TargetNum != targetEntityNum) continue; var handlerParams = handler.Function.Method.GetParameters(); // Check if the handler function has parameters. if (handlerParams.Length > 0) { // Calculate the number of arguments. int argumentCount = GetNotifyArgumentCount(); // Get the parameters. object[] parameters = GetParameters(argumentCount); // Fix the parameters if the user omitted some of them. var fixedParameters = new object[handlerParams.Length]; Array.Copy(parameters, fixedParameters, fixedParameters.Length); // Dynamically invoke the function. handler.Function.DynamicInvoke(fixedParameters); } else { // Perform a dynamic invoke with no arguments. handler.Function.DynamicInvoke(); } } } private static void HandleNotifyEvent(int entity, uint type) { if (type == 0) return; // Get the current message address. var messageAddress = (IntPtr)(Marshal.ReadInt32(GameScriptStringTablePointer) + 12 * type + 4); if (messageAddress == IntPtr.Zero) return; int targetEntityNum = -1; // Check if the script object type is an entity/client. if (GetObjectType(entity) == 21) { // Convert the script object ID to an entity/client num. targetEntityNum = ScriptObjectIDToEntityNum(entity); } // Get the current message. string message = Marshal.PtrToStringAnsi(messageAddress); // Check the message is valid and notify the handlers. if (string.IsNullOrEmpty(message) || !NotifyHandlers.ContainsKey(message)) return; try { DispatchMessage(targetEntityNum, message); } catch (Exception ex) { // Catch any errors and display it as a message box since there's no way to // log it without a plugin instance. MessageBox(IntPtr.Zero, ex.ToString(), "HandleNotifyEvent failed.", MB_ICONERROR); } } private static void GameScriptNotifyHandlerHook(int entity, uint type, IntPtr variableStack) { _scrNotifyStack = variableStack; HandleNotifyEvent(entity, type); } public static void OnInterval(int interval, ServerClient target, Func<bool> function) { Timers.Add(new ServerTimer { Interval = interval, Function = function, Target = target }); } public static void OnInterval(int interval, Func<bool> function) { Timers.Add(new ServerTimer { Interval = interval, Function = function }); } public static void AfterDelay(int delay, ServerClient target, Action action) { Timers.Add(new ServerTimer { Interval = -1, Time = Stopwatch.ElapsedMilliseconds + delay, Function = action, Target = target }); } public static void AfterDelay(int delay, Action action) { Timers.Add(new ServerTimer { Interval = -1, Time = Stopwatch.ElapsedMilliseconds + delay, Function = action }); } public static void ProcessFrame(List<ServerClient> clients) { var currentTime = Stopwatch.ElapsedMilliseconds; foreach (var timer in Timers.ToArray()) { if (currentTime < timer.Time) continue; if (timer.Target != null && clients.FindIndex(sc => sc.XUID == timer.Target.XUID) == -1) { Timers.Remove(timer); continue; } object returnValue = timer.Function.DynamicInvoke(); if (timer.Interval == -1 || timer.Function.Method.ReturnType == typeof(bool) && !(bool)returnValue) { Timers.Remove(timer); } else { timer.Time = currentTime + timer.Interval; } } } private static void OnNotify(string type, Delegate action, bool hasTarget, int targetNum) { var serverNotify = new ServerNotify { Function = action, HasTarget = hasTarget, TargetNum = targetNum }; if (NotifyHandlers.ContainsKey(type)) NotifyHandlers[type].Add(serverNotify); else NotifyHandlers.Add(type, new List<ServerNotify>(new[] { serverNotify })); } public static void OnNotify(string type, Action action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, false, -1); } public static void OnNotify(string type, ServerClient client, Action action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, ServerClient client, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, client.ClientNum); } public static void OnNotify(string type, Entity entity, Action action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } public static void OnNotify(string type, Entity entity, Action<Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter, Parameter> action) { OnNotify(type, action, true, entity.EntityNum); } } }
No need to lie, the code works stably
Posts: 299
Threads: 1
Joined: Aug 2013
Reputation:
10
Threading crashes the servers. Its no lie its the truth.
Posts: 76
Threads: 5
Joined: Sep 2012
Reputation:
2
Also tekno and Retail MW3 are different in terms of addon support and modding capabilities. Threading causes problems on Retail. Tekno isnt supported here anyways so...
|