commit 87925b052e0e75bcf8d42d838344caf1f5cb4f38 Author: zombie343 Date: Fri Dec 29 23:47:01 2017 -0500 first commit of repeat plugin diff --git a/README.md b/README.md new file mode 100644 index 0000000..375ef24 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# Repeat! + +An Ashita FFXI plugin used to repeat commands at a specified interval. This is an improvement to the addon called repeater. + +Repeater Command Listing: /rp, /repeat or /repeater are all valid: + + /rp [set|unset] [command] - Set or Unset command to be repeated. + /rp [cycle] - Number of milliseconds to wait before repeating. + /rp [jitter] - Specify max. random addition to cycle time. Default: 0 + /rp [start|stop] - Starts or Stops repeating of previously set command. + /rp debug - Toggles debug prints messages."); + +Note: Cycle duration must be within 1s and 3600s (1000ms to 3600000ms) +Note: Jitter duration must be within 0s and 3600s (1ms to 3600000ms; 0 = disabled). + +Example: + +/rp set command /dance4 motion +/rp cycle 10000 +/rp start + +This will execute the command "/dance4 motion" every 10,000ms (10 seconds). + +If you require a randomized interval between command executions, you can simply specify an additional amount of time, called jitter, to randomly be added to your cycle time: + +/rp jitter 3000 + +This will execute the command periodically, ranging between 10 and 13 seconds. \ No newline at end of file diff --git a/Release/Repeat.dll b/Release/Repeat.dll new file mode 100644 index 0000000..52a3b78 Binary files /dev/null and b/Release/Repeat.dll differ diff --git a/Repeat.cpp b/Repeat.cpp new file mode 100644 index 0000000..6c6c320 --- /dev/null +++ b/Repeat.cpp @@ -0,0 +1,694 @@ +/** + * Ashita - Copyright (c) 2014 - 2016 atom0s [atom0s@live.com] + * + * This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to + * Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * + * By using Ashita, you agree to the above license and its terms. + * + * Attribution - You must give appropriate credit, provide a link to the license and indicate if changes were + * made. You must do so in any reasonable manner, but not in any way that suggests the licensor + * endorses you or your use. + * + * Non-Commercial - You may not use the material (Ashita) for commercial purposes. + * + * No-Derivatives - If you remix, transform, or build upon the material (Ashita), you may not distribute the + * modified material. You are, however, allowed to submit the modified works back to the original + * Ashita project in attempt to have it added to the original project. + * + * You may not apply legal terms or technological measures that legally restrict others + * from doing anything the license permits. + * + * No warranties are given. + */ + +#include "Repeat.h" + +/** + * Constructor and Deconstructor + */ +Repeat::Repeat(void) + : m_AshitaCore(nullptr) + , m_LogManager(nullptr) + , m_PluginId(0) + , m_Direct3DDevice(nullptr) +{ } +Repeat::~Repeat(void) +{ } + + +/** + * Returns the plugins information structure. + * + * @returns {plugininfo_t} The plugin information structure of the plugin. + */ +plugininfo_t Repeat::GetPluginInfo(void) +{ + return *g_PluginInfo; +} + +/** + * Invoked when the plugin is loaded, allowing it to prepare for usage. + * + * @param {IAshitaCore*} core - The Ashita core object to interact with the various Ashita managers. + * @param {ILogManager*} log - The log manager used to interact with the current log file. + * @param {uint32_t} id - The plugins id, or its module base, that identifies it other than its name. + * @returns {bool} True on success, false otherwise. (If false, the plugin will not be loaded.) + * + * @notes + * + * Plugins must return true here or they will be considered invalid and unload immediately. + * Returning false means that the plugin failed to initialize and should not be used. + */ +bool Repeat::Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) +{ + // Store the variables for later usage.. + this->m_AshitaCore = core; + this->m_LogManager = log; + this->m_PluginId = id; + this->_userdelayinms = 0; + this->_jitter = 0; + this->doJitter = false; + this->_debug = false; + this->command = ""; + this->Start(); + return true; +} + +/** + * Invoked when the plugin is being unloaded, allowing it to cleanup its resources. + * + * @notes + * + * Plugins should use this function to cleanup non-Direct3D related objects. + * - Delete created font objects. + * - Delete created Gui objects. + * - Internal memory allocations. + */ +void Repeat::Release(void) +{ + this->Stop(); +} + +/** + * Invoked when a command is being processed by the game client. + * + * Note: + * Please note, this handles all things done via the game in terms of commands + * and chat. All / commands as well as normal chat you type, macros, etc. will + * be processed through here. You should only use this to handle / commands. + * + * If you wish to handle other bits of outgoing text before the client sees it, + * then use the HandleOutgoingText callback instead. + * + * @param {const char*} command - The raw command string being processed. + * @param {uint32_t} type - The type of the command being processed. (See Ashita::CommandInputType enumeration.) + * @returns {bool} True if handled and should be blocked, false otherwise. + * + * @notes + * + * Plugins can handle and block input from being sent to the game in this function. Returning + * true will block the current command from happening at all within the client. Plugins should + * only return true when the command passed to this function is being handled by the plugin. + */ +bool Repeat::HandleCommand(const char* given_command, int32_t type) +{ + //UNREFERENCED_PARAMETER(type); + std::string arg; + const char* com = given_command + GetArg(given_command, &arg); + if ((_strnicmp(given_command, "/rp", 3)) + && (_stricmp(arg.c_str(), "/repeat")) && (_stricmp(arg.c_str(), "/repeater"))) + { + return false; + } + if (strlen(com) < 2) return true; + if ((_stricmp(arg.c_str(), "/rp") == 0) + || (_stricmp(arg.c_str(), "/repeat") == 0) || (_stricmp(arg.c_str(), "/repeater") == 0)) + { + com++; + com += GetArg(com, &arg); + } + /* + m_AshitaCore->GetChatManager()->Write("Repeater Command Listing: /repeater or /rp are both valid:"); + m_AshitaCore->GetChatManager()->Write("/rp [set|unset] [command] - Set or Unset command to be repeated"); + m_AshitaCore->GetChatManager()->Write("/rp [cycle] - Number of milliseconds to wait before repeating."); + m_AshitaCore->GetChatManager()->Write("/rp [jitter] [on|off] - Toggle or turn on/off small differences in cycle time."); + m_AshitaCore->GetChatManager()->Write("/rp [start|stop] - Starts or Stops repeating of previously set command"); + m_AshitaCore->GetChatManager()->Write("/rp debug on/off - When enabled, debug prints will be visible."); + */ + + if (_stricmp(arg.c_str(), "set") == 0) + { + if (strlen(com) < 2) return true; + command = com + 1; + m_AshitaCore->GetChatManager()->Writef("Setting command to: %s", command.c_str()); + return true; + } + else if (_stricmp(arg.c_str(), "unset") == 0) + { + command = ""; + this->m_AshitaCore->GetChatManager()->Write("Clearing command."); + return true; + } + else if (_stricmp(arg.c_str(), "cycle") == 0) + { + if (strlen(com) < 2) return true; + com++; + com += GetArg(com, &arg); + if (!IsNumber(arg.c_str())) return true; + _userdelayinms = stoi(arg.c_str()); + _userdelayinms = max(_userdelayinms, 1000); + _userdelayinms = min(_userdelayinms, 3600000); + if (doJitter) + this->m_AshitaCore->GetChatManager()->Writef("Commands will be executed every %i milliseconds with random jitter!", _userdelayinms); + else + this->m_AshitaCore->GetChatManager()->Writef("Commands will be executed every %i milliseconds!", _userdelayinms); + return true; + } + else if (_stricmp(arg.c_str(), "jitter") == 0) + { + if (strlen(com) < 2) return true; + com++; + com += GetArg(com, &arg); + _maxjitter = stoi(arg.c_str()); + _maxjitter = max(_maxjitter, 0); + _maxjitter = min(_maxjitter, 3600000); + if (_maxjitter > 0) + { + doJitter = true; + this->m_AshitaCore->GetChatManager()->Writef("Random jitter betweem 0 and %ims will be added to cycle time.", _maxjitter); + } + else + { + doJitter = false; + this->m_AshitaCore->GetChatManager()->Writef("Jitter disabled.", _maxjitter); + } + return true; + } + else if (_stricmp(arg.c_str(), "start") == 0) + { + if (command != "") + { + _tickcount = 0; + this->m_AshitaCore->GetChatManager()->Write("Starting command!"); + _ispluginrunning = true; + } + else + { + _ispluginrunning = false; + this->m_AshitaCore->GetChatManager()->Write("Please specify a command to be repeated."); + } + return true; + } + else if (_stricmp(arg.c_str(), "stop") == 0) + { + _ispluginrunning = false; + this->m_AshitaCore->GetChatManager()->Write("Cycle terminated!"); + return true; + } + else if (_stricmp(arg.c_str(), "debug") == 0) + { + _debug = !(_debug); + this->m_AshitaCore->GetChatManager()->Writef("Repeat debug set to: %s", _debug ? "True" : "False" ); + return true; + } + else + { + PrintHelp(); + return true; + } + // Return false here to allow unhandled commands to continue to be processed. + return false; +} + +void Repeat::PrintHelp() +{ + this->m_AshitaCore->GetChatManager()->Write("Repeat Command Listing: /rp, /repeat or /repeater are all valid:"); + this->m_AshitaCore->GetChatManager()->Write("/rp [set|unset] [command] - Set or Unset command to be repeated."); + this->m_AshitaCore->GetChatManager()->Write("/rp [cycle] - Number of milliseconds to wait before repeating."); + this->m_AshitaCore->GetChatManager()->Write("/rp [jitter] - Specify max. random addition to cycle time. Default: 0"); + this->m_AshitaCore->GetChatManager()->Write("/rp [start|stop] - Starts or Stops repeating of previously set command"); + this->m_AshitaCore->GetChatManager()->Write("/rp debug - Toggles debug prints messages."); + this->m_AshitaCore->GetChatManager()->Write("Note: Cycle duration must be within 1s and 3600s (1000ms to 3600000ms)."); + this->m_AshitaCore->GetChatManager()->Write("Note: Jitter duration must be within 0s and 3600s (1ms to 3600000ms; 0 = disabled)."); +} + + +uint32_t Repeat::ThreadEntry(void) +{ + while (!this->IsTerminated()) + { + if (_ispluginrunning) + { + _tickcount = max(0, _tickcount - 1); + + if (_tickcount == 0) + { + if (_debug) + this->m_AshitaCore->GetChatManager()->Writef("Command being executed is: %s", command.c_str()); + this->m_AshitaCore->GetChatManager()->QueueCommand(command.c_str(), -1); + if (doJitter) + { + _jitter = (rand() % _maxjitter); + if (_debug) + { + this->m_AshitaCore->GetChatManager()->Writef("cycle time: %ims jitter: %ims", _userdelayinms, _jitter); + } + _tickcount = _userdelayinms + _jitter; + } + else + { + _tickcount = _userdelayinms; + } + } + } + + ::Sleep(1); + } + return 0; +} + +bool Repeat::IsNumber(const char* Input) +{ + bool Decimal = false; + for (unsigned int X = 0; X < strlen(Input); X++) + { + if (Input[X] == '-') + { + if (X != 0) return false; + } + else if (Input[X] == '.') + { + if (Decimal) return false; + Decimal = true; + } + else if (!isdigit(Input[X])) return false; + } + return true; +} + +uint32_t Repeat::GetArg(const char* text, std::string* buffer) +{ + std::string working(text); + + if (working[0] == '"') + { + size_t second = working.substr(1).find_first_of('"'); + if (second != string::npos) + { + *buffer = working.substr(1, second); + return second + 1; + } + } + + size_t space = working.find_first_of(' '); + if (space != string::npos) + { + *buffer = working.substr(0, space); + return space; + } + + *buffer = string(text); + return strlen(text); +} + + +/** + * Invoked when incoming text being sent to the chat log is being processed. + * + * @param {int16_t} mode - The mode of the message being added to the chatlog. + * @param {const char*} message - The raw message being added to the chat log. + * @param {int16_t*} modifiedMode - The modified mode, if any, that has been altered by other plugins/addons. + * @param {char*} modifiedMessage - The modified message, if any, that has been altered by other plugins/addons. + * @param {bool} blocked - Flag if this message has been blocked already by another plugin. (Once blocked, other plugins cannot restore it.) + * @returns {bool} True if handled and should be blocked, false otherwise. + * + * @notes + * + * Plugins can block the incoming text line by returning true in this function. + * Plugins can override the incoming text mode by setting the value of modifiedMode. + * Plugins can override the incoming text by writing a new message to the modifiedMessage buffer. + * Plugins can check if other plugins have blocked the current message by checking of the blocked param is true. + */ +bool Repeat::HandleIncomingText(int16_t mode, const char* message, int16_t* modifiedMode, char* modifiedMessage, bool blocked) +{ + UNREFERENCED_PARAMETER(mode); + UNREFERENCED_PARAMETER(message); + UNREFERENCED_PARAMETER(modifiedMode); + UNREFERENCED_PARAMETER(modifiedMessage); + UNREFERENCED_PARAMETER(blocked); + + return false; +} + +/** + * Invoked when outgoing text has not been handled by other plugins/addons. + * Invoked after HandleCommand if nothing else processed the data. + * + * @param {int16_t} mode - The type of the text that is being sent. (See Ashita::CommandInputType enumeration.) + * @param {const char*} message - The raw message being sent. + * @param {int16_t*} modifiedMode - The modified mode, if any, that has been altered by other plugins/addons. + * @param {char*} modifiedMessage - The modified message, if any, that has been altered by other plugins/addons. + * @param {bool} blocked - Flag if this message has been blocked already by another plugin. (Once blocked, other plugins cannot restore it.) + * @returns {bool} True if handled and should be blocked, false otherwise. + * + * @notes + * + * Plugins can block the outgoing text line by returning true in this function. + * Plugins can override the outgoing text mode by setting the value of modifiedMode. + * Plugins can override the outgoing text by writing a new message to the modifiedMessage buffer. + * Plugins can check if other plugins have blocked the current message by checking of the blocked param is true. + * + * Plugins can use this event as a last-ditch effort to handle outgoing text being sent from the client. + * This event can be used for overriding things like custom token parsing for things such as: + * %player_name% to be parsed out and replaced with the actual player name. + */ +bool Repeat::HandleOutgoingText(int32_t type, const char* message, int32_t* modifiedType, char* modifiedMessage, bool blocked) +{ + UNREFERENCED_PARAMETER(type); + UNREFERENCED_PARAMETER(message); + UNREFERENCED_PARAMETER(modifiedType); + UNREFERENCED_PARAMETER(modifiedMessage); + UNREFERENCED_PARAMETER(blocked); + + return false; +} + +/** + * Invoked when an incoming packet is being handled. + * + * @param {uint16_t} id - The id of the packet. + * @param {uint32_t} size - The size of the packet data. + * @param {void*} data - The raw data of the packet. + * @param {void*} modified - The modified data, if any, that has been altered by other plugins/addons. + * @param {bool} blocked - Flag if this message has been blocked already by another plugin. (Once blocked, other plugins cannot restore it.) + * @returns {bool} True if handled and should be blocked, false otherwise. + * + * @notes + * + * Plugins can block the packet by returning true in this function. + * Plugins can alter the data of the packet by editing the modified data parameter. + * Plugins can check if other plugins have blocked the current packet by checking if the blocked param is true. + * + * Please note; altering packets incorrectly or altering the flow of packets incorrectly can have adverse affects + * and possibly lead to players being banned. Edit with caution! + */ +bool Repeat::HandleIncomingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) +{ + UNREFERENCED_PARAMETER(id); + UNREFERENCED_PARAMETER(size); + UNREFERENCED_PARAMETER(data); + UNREFERENCED_PARAMETER(modified); + UNREFERENCED_PARAMETER(blocked); + + return false; +} + +/** + * Invoked when an outgoing packet is being handled. + * + * @param {uint16_t} id - The id of the packet. + * @param {uint32_t} size - The size of the packet data. + * @param {void*} data - The raw data of the packet. + * @param {void*} modified - The modified data, if any, that has been altered by other plugins/addons. + * @param {bool} blocked - Flag if this message has been blocked already by another plugin. (Once blocked, other plugins cannot restore it.) + * @returns {bool} True if handled and should be blocked, false otherwise. + * + * @notes + * + * Plugins can block the packet by returning true in this function. + * Plugins can alter the data of the packet by editing the modified data parameter. + * Plugins can check if other plugins have blocked the current packet by checking if the blocked param is true. + * + * Please note; altering packets incorrectly or altering the flow of packets incorrectly can have adverse affects + * and possibly lead to players being banned. Edit with caution! + */ +bool Repeat::HandleOutgoingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) +{ + UNREFERENCED_PARAMETER(id); + UNREFERENCED_PARAMETER(size); + UNREFERENCED_PARAMETER(data); + UNREFERENCED_PARAMETER(modified); + UNREFERENCED_PARAMETER(blocked); + + return false; +} + +/** + * Invoked when the plugin is being initialized for Direct3D rendering. + * + * Note: + * Plugins must return true with this function in order to have the other Direct3D + * functions invoked. Returning false is ideal here if you do not need to use the + * Direct3D functions within your plugin. This can help with overall performance. + * + * @param {IDirect3DDevice8*} device - The Direct3D device pointer currently being used by the game. + * @return {bool} True if the plugin should handle the other Direct3D messages, false otherwise. + */ +bool Repeat::Direct3DInitialize(IDirect3DDevice8* device) +{ + // Store the device for later usage.. + this->m_Direct3DDevice = device; + + /** + * Returning true here for the sake of the example plugin! If you do not need + * to make use of any of the Direct3D calls, it is recommended to return false + * here to save on performance! + */ + + return true; +} + +/** + * Invoked when the plugin is being unloaded and is able to cleanup its Direct3D related resources. + * + * @notes + * + * Plugins should use this function to cleanup Direct3D related objects. + * - Index Buffers, Vertex Buffers + * - Textures + */ +void Repeat::Direct3DRelease(void) +{ } + +/** + * Invoked when the Direct3D device is beginning to render. (BeginScene) + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called after BeginScene is called. + */ +void Repeat::Direct3DPreRender(void) +{ } + +/** + * Invoked when the Direct3D device is ending its rendering. (EndScene) + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before EndScene is called. + */ +void Repeat::Direct3DRender(void) +{ } + +/** + * Invoked when the Direct3D device is presenting the scene. (Present) + * + * @param {RECT*} pSourceRect - The source rect being rendered into. + * @param {RECT*} pDestRect - The destination rect being rendered from. + * @param {HWND} hDestWindowOverride - The window handle, if any, to override the rendering into. + * @param {RGNDATA*} pDirtyRegion - The dirty region data. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before Present is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DPresent(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) +{ + UNREFERENCED_PARAMETER(pSourceRect); + UNREFERENCED_PARAMETER(pDestRect); + UNREFERENCED_PARAMETER(hDestWindowOverride); + UNREFERENCED_PARAMETER(pDirtyRegion); + + return false; +} + +/** + * Invoked when the Direct3D device is drawing a primitive to the scene. (DrawPrimitive) + * + * @param {D3DPRIMITIVETYPE} PrimitiveType - The type of primitive being rendered. + * @param {UINT} StartVertex - Index of the first vertex to load. + * @param {UINT} PrimitiveCount - Number of primitives to render. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before DrawPrimitive is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DDrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) +{ + UNREFERENCED_PARAMETER(PrimitiveType); + UNREFERENCED_PARAMETER(StartVertex); + UNREFERENCED_PARAMETER(PrimitiveType); + + return false; +} + +/** + * Invoked when the Direct3D device is drawing a primitive to the scene. (DrawIndexedPrimitive) + * + * @param {D3DPRIMITIVETYPE} PrimitiveType - The type of primitive being rendered. + * @param {UINT} minIndex - Minimum vertex index for vertices used during this call. + * @param {UINT} numVertices - Number of vertices used during this call + * @param {UINT} startIndex - Index of the first index to use when accesssing the vertex buffer. + * @param {UINT} primCount - Number of primitives to render. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before DrawIndexedPrimitive is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DDrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) +{ + UNREFERENCED_PARAMETER(PrimitiveType); + UNREFERENCED_PARAMETER(minIndex); + UNREFERENCED_PARAMETER(NumVertices); + UNREFERENCED_PARAMETER(startIndex); + UNREFERENCED_PARAMETER(primCount); + + return false; +} + +/** + * Invoked when the Direct3D device is drawing a primitive to the scene. (DrawPrimitiveUP) + * + * @param {D3DPRIMITIVETYPE} PrimitiveType - The type of primitive being rendered. + * @param {UINT} PrimitiveCount - Number of primitives to render. + * @param {void*} pVertexStreamZeroData - User memory pointer to the vertex data. + * @param {UINT} VertexStreamZeroStride - The number of bytes of data for each vertex. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before DrawPrimitiveUP is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DDrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + UNREFERENCED_PARAMETER(PrimitiveType); + UNREFERENCED_PARAMETER(PrimitiveCount); + UNREFERENCED_PARAMETER(pVertexStreamZeroData); + UNREFERENCED_PARAMETER(VertexStreamZeroStride); + + return false; +} + +/** + * Invoked when the Direct3D device is drawing a primitive to the scene. (DrawIndexedPrimitiveUP) + * + * @param {D3DPRIMITIVETYPE} PrimitiveType - The type of primitive being rendered. + * @param {UINT} MinVertexIndex - Minimum vertex index. + * @param {UINT} NumVertexIndices - Number of vertices used during this call. + * @param {UINT} PrimitiveCount - Number of primitives to render. + * @param {void*} pIndexData - User memory pointer to the index data. + * @param {D3DFORMAT} IndexDataFormat - The format of the index data. + * @param {void*} pVertexStreamZeroData - User memory pointer to the vertex data. + * @param {UINT} VertexStreamZeroStride - The number of bytes of data for each vertex. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before DrawIndexedPrimitiveUP is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DDrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + UNREFERENCED_PARAMETER(PrimitiveType); + UNREFERENCED_PARAMETER(MinVertexIndex); + UNREFERENCED_PARAMETER(NumVertexIndices); + UNREFERENCED_PARAMETER(PrimitiveCount); + UNREFERENCED_PARAMETER(pIndexData); + UNREFERENCED_PARAMETER(IndexDataFormat); + UNREFERENCED_PARAMETER(pVertexStreamZeroData); + UNREFERENCED_PARAMETER(VertexStreamZeroStride); + + return false; +} + +/** + * Invoked when the Direct3D device is setting a render state. (SetRenderState) + * + * @param {D3DRENDERSTATETYPE} state - The render state to alter. + * @param {DWORD} value - The new value for the render state. + * @returns {bool} True if the call should be blocked, false otherwise. + * + * @notes + * + * This will only be called if you returned true inside of Direct3DInitialize! + * This function is called before SetRenderState is called. + * + * Plugins can block the call from happening by returning true. + */ +bool Repeat::Direct3DSetRenderState(D3DRENDERSTATETYPE State, DWORD Value) +{ + UNREFERENCED_PARAMETER(State); + UNREFERENCED_PARAMETER(Value); + + return false; +} + + +/** + * Returns the interface version this plugin was compiled with. + * + * @returns {double} The Ashita interface version. + */ +__declspec(dllexport) double __stdcall GetInterfaceVersion(void) +{ + return ASHITA_INTERFACE_VERSION; +} + +/** + * Creates and populates the plugins information structure. + * + * @returns {double} The Ashita interface version. + */ +__declspec(dllexport) void __stdcall CreatePluginInfo(plugininfo_t* info) +{ + // Store the pointer from Ashita.. + g_PluginInfo = info; + + // Populate the structure with our plugins information.. + strcpy_s(info->Author, sizeof(info->Author), "Felgar"); + strcpy_s(info->Name, sizeof(info->Name), "Repeat"); + info->InterfaceVersion = ASHITA_INTERFACE_VERSION; + info->PluginVersion = 3.0f; + info->Priority = 0; +} + +/** + * Creates an instance of the plugins main class. + * + * @returns {IPlugin*} The plugin base class instance created by this plugin. + */ +__declspec(dllexport) IPlugin* __stdcall CreatePlugin(void) +{ + return (IPlugin*)new Repeat; +} \ No newline at end of file diff --git a/Repeat.h b/Repeat.h new file mode 100644 index 0000000..ed6be8e --- /dev/null +++ b/Repeat.h @@ -0,0 +1,126 @@ +/** + * Ashita - Copyright (c) 2014 - 2016 atom0s [atom0s@live.com] + * + * This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to + * Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * + * By using Ashita, you agree to the above license and its terms. + * + * Attribution - You must give appropriate credit, provide a link to the license and indicate if changes were + * made. You must do so in any reasonable manner, but not in any way that suggests the licensor + * endorses you or your use. + * + * Non-Commercial - You may not use the material (Ashita) for commercial purposes. + * + * No-Derivatives - If you remix, transform, or build upon the material (Ashita), you may not distribute the + * modified material. You are, however, allowed to submit the modified works back to the original + * Ashita project in attempt to have it added to the original project. + * + * You may not apply legal terms or technological measures that legally restrict others + * from doing anything the license permits. + * + * No warranties are given. + */ + +#ifndef __ASHITA_Repeat_H_INCLUDED__ +#define __ASHITA_Repeat_H_INCLUDED__ + +#if defined (_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/** + * Main Ashita ADK Header + * + * This is the main header to include while creating Ashita v3 plugins. This header includes + * various things that are useful to plugins as well as includes all the other ADK files in + * a single header. Update this path to match where you have Ashita v3 installed to. + */ +#include "C:\Ashita3\plugins\ADK\Ashita.h" +#include +#include +#include + +/** + * Plugin Information + * + * This object holds information specific to this plugin. The CreatePluginInfo exported function + * uses this object to create information about the plugin which is used internally with Ashita. + * + * Please note: Ashita maintains the pointer of this object! Your plugin should never try to delete + * this object manually! + */ + +using namespace std; + +plugininfo_t* g_PluginInfo = nullptr; + +/** + * Main Plugin Class Instance + * + * The main class the plugin will expose back to Ashita when loaded. + * This class must inherit from IPlugin in order to be valid! + * + * See ExamplePlugin.cpp for more information about the functions in this class. + */ +class Repeat : IPlugin, Ashita::Threading::AS_Thread +{ + IAshitaCore* m_AshitaCore; + ILogManager* m_LogManager; + uint32_t m_PluginId; + IDirect3DDevice8* m_Direct3DDevice; + volatile bool _ispluginrunning; + volatile bool doJitter; + volatile bool _debug; + volatile uint32_t _userdelayinms; + volatile uint32_t _jitter; + volatile uint32_t _maxjitter; + int _tickcount; + string command; + +public: + // Constructor and Deconstructor + Repeat(void); + ~Repeat(void); + +public: + // Plugin Information Callback + plugininfo_t GetPluginInfo(void) override; + void PrintHelp(); + +public: + // Main Initialization and Cleanup Callbacks + bool Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) override; + void Release(void) override; + + // Thread Things + uint32_t ThreadEntry(void) override; + + // Command Parsing + bool IsNumber(const char* Input); + uint32_t GetArg(const char* text, std::string* buffer); + + // Chat Manager Callbacks + bool HandleCommand(const char* command, int32_t type) override; + bool HandleIncomingText(int16_t mode, const char* message, int16_t* modifiedMode, char* modifiedMessage, bool blocked) override; + bool HandleOutgoingText(int32_t type, const char* message, int32_t* modifiedType, char* modifiedMessage, bool blocked) override; + + // Packet Manager Callbacks + bool HandleIncomingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) override; + bool HandleOutgoingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) override; + + // Direct3D Related Callbacks + bool Direct3DInitialize(IDirect3DDevice8* device) override; + void Direct3DRelease(void) override; + void Direct3DPreRender(void) override; + void Direct3DRender(void) override; + bool Direct3DPresent(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) override; + bool Direct3DDrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) override; + bool Direct3DDrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) override; + bool Direct3DDrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override; + bool Direct3DDrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override; + bool Direct3DSetRenderState(D3DRENDERSTATETYPE State, DWORD Value) override; +}; + +#endif // __ASHITA_Repeat_H_INCLUDED__ \ No newline at end of file diff --git a/Repeat.sln b/Repeat.sln new file mode 100644 index 0000000..dcd43af --- /dev/null +++ b/Repeat.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2003 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Repeat", "Repeater.vcxproj", "{A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Debug|x64.ActiveCfg = Debug|x64 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Debug|x64.Build.0 = Debug|x64 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Debug|x86.ActiveCfg = Debug|Win32 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Debug|x86.Build.0 = Debug|Win32 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Release|x64.ActiveCfg = Release|x64 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Release|x64.Build.0 = Release|x64 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Release|x86.ActiveCfg = Release|Win32 + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D493B82F-ECB8-4A12-9FD1-CC0B90A6DEE6} + EndGlobalSection +EndGlobal diff --git a/Repeater.filters b/Repeater.filters new file mode 100644 index 0000000..ee382ef --- /dev/null +++ b/Repeater.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Resource Files + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/Repeater.vcxproj b/Repeater.vcxproj new file mode 100644 index 0000000..ab0c900 --- /dev/null +++ b/Repeater.vcxproj @@ -0,0 +1,170 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A08DCC6D-9911-4A47-8D11-9BC12DF62BC9} + Win32Proj + Repeat + 8.1 + Repeat + + + + DynamicLibrary + true + v140_xp + MultiByte + + + DynamicLibrary + false + v140_xp + true + MultiByte + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXAMPLEPLUGIN_EXPORTS;%(PreprocessorDefinitions) + true + ProgramDatabase + true + false + Async + + + Windows + true + exports.def + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;EXAMPLEPLUGIN_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + exports.def + + + + + Level3 + NotUsing + Full + false + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXAMPLEPLUGIN_EXPORTS;%(PreprocessorDefinitions) + true + true + true + Async + + + Windows + true + true + true + exports.def + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;EXAMPLEPLUGIN_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + exports.def + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Repeater.vcxproj.user b/Repeater.vcxproj.user new file mode 100644 index 0000000..be25078 --- /dev/null +++ b/Repeater.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/exports.def b/exports.def new file mode 100644 index 0000000..f3b4cf1 --- /dev/null +++ b/exports.def @@ -0,0 +1,5 @@ +LIBRARY "Repeat" +EXPORTS + GetInterfaceVersion + CreatePluginInfo + CreatePlugin \ No newline at end of file