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
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
He wants iPrintLn, ServerAd is a bit spammish plugin.
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
(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
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); } } } }
(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); } } }
(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.
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
Threading crashes the servers. Its no lie its the truth.
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...
|