From 87925b052e0e75bcf8d42d838344caf1f5cb4f38 Mon Sep 17 00:00:00 2001 From: zombie343 Date: Fri, 29 Dec 2017 23:47:01 -0500 Subject: [PATCH] first commit of repeat plugin --- README.md | 28 ++ Release/Repeat.dll | Bin 0 -> 22016 bytes Repeat.cpp | 694 ++++++++++++++++++++++++++++++++++++++++++ Repeat.h | 126 ++++++++ Repeat.sln | 31 ++ Repeater.filters | 32 ++ Repeater.vcxproj | 170 +++++++++++ Repeater.vcxproj.user | 4 + exports.def | 5 + 9 files changed, 1090 insertions(+) create mode 100644 README.md create mode 100644 Release/Repeat.dll create mode 100644 Repeat.cpp create mode 100644 Repeat.h create mode 100644 Repeat.sln create mode 100644 Repeater.filters create mode 100644 Repeater.vcxproj create mode 100644 Repeater.vcxproj.user create mode 100644 exports.def 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 0000000000000000000000000000000000000000..52a3b7884dd8f7443827afc9ba40cd9457095c75 GIT binary patch literal 22016 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 M)c@uB|6T+C32y+{&Hw-a literal 0 HcmV?d00001 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