• Content count

  • Joined

  • Last visited

Posts posted by spktbl

  1. I hope I can help a bit - actually I'm using Delphi 7, not C++, so I just rewrite header file a bit for my needs.

    1) Here is a code for very simple plugin.

    2) I want to warn you that I don't test all functions and you may crash ApexDC++ when using it.

    3) It is not a complete port for header file - only things what I need.

    4) This code may a bit rough for someone, but, as I say, I did that for myself and put it here only to help anyone who don't know how to start.

    5) The code below is legal only for version 1.3.6 and may be not compatible with later version of ApexDC++ - don't forget to check PluginDefs.h from latest source code package.


    library ApexTest;
    uses Windows, PluginDefs;
      PLUGIN_GUID = '{c0dec0de-c0de-c0de-c0de-c0dec0dec0de}'; // UUID/GUID for this plugin project
      PLUGIN_NAME = 'ApexTest'; // Name of the plugin
      PLUGIN_AUTHOR = 'Anonymous'; // Author of the plugin
      PLUGIN_DESC = 'A simple Delphi test plugin with every minute message.'; // Short description about the plugin
      PLUGIN_VERSION = 1.00; // Version of the plugin (note: not api version)
      PLUGIN_WEB = 'N/A'; // Plugin website, set to "N/A" if none
       dcpp: PDCCore = nil;
       hook: pointer = nil;
    // forward declaration for onLoad function
    function pluginProc(eventID: cardinal; pData: pointer): longbool; stdcall; forward;
    function onLoad(eventID: cardinal; pData: pointer): longbool;
      // set hook
      If hook = nil Then hook:=dcpp^.set_hook(HOOK_TIMER, @pluginProc, nil);
    function onUnload(eventID: cardinal): longbool;
      // remove hook
      if hook <> nil then
    function TimerHandle: longbool;
      MessageBox(0, 'To disable this message boxes - uninstall plugin!', 'ApexTest plugin', MB_ICONINFORMATION);
    function pluginProc(eventID: cardinal; pData: pointer): longbool; stdcall;
      case eventId of
          result:=onLoad(eventId, pData);
    function pluginInit(info: PMetaData): pointer; stdcall;
      info^.name := PLUGIN_NAME;
      info^.author := PLUGIN_AUTHOR;
      info^.description := PLUGIN_DESC;
      info^.version := PLUGIN_VERSION;
      info^.web := PLUGIN_WEB;
      info^.apiVersion := DCAPI_VER;
      info^.compatibleVersion := DCAPI_COMPATIBLE_VER;
      info^.guid := PLUGIN_GUID;
    unit PluginDefs;
      // Version of the plugin api (must change every time the API has changed)
      DCAPI_VER = 0.50;
      // The earliest version of the API that this version is backwards compatible with
      // Hook IDs
      // Mandatory callback hook
      CALLBACK_BASE = 0;
      // Common hooks (none manadatory, however, one required)
      HOOK_PROTOCOL = 500;
      HOOK_CHAT     = 501;
      HOOK_HUBS     = 502;
      HOOK_TIMER    = 503;
      HOOK_QUEUE    = 504;
      HOOK_UI       = 505;
      // Plugin created hooks and callbacks (HOOK_USER + n)
      HOOK_USER = 1000;
      // Main hook events (returned by pluginInit)
      ON_INSTALL      = 0; // Replaces ON_LOAD for the very first loading of the plugin
      ON_UNINSTALL    = 1; // Replaces ON_UNLOAD when plugin is being uninstalled
      ON_LOAD         = 2; // Sent after successful call to pluginInit
      ON_UNLOAD       = 3; // Sent right before plugin is unloaded (no params)
      ON_CONFIGURE    = 4; // Sent when user wants to configure the plugin (obj: obj: impl. dependant or NULL)
      // Chat hook events (HOOK_CHAT)
      CHAT_IN         = 500; // Incoming chat from hub (obj: ClientData)
      CHAT_OUT        = 501; // Outgoing chat (obj: ClientData)
      CHAT_PM_IN      = 502; // Incoming private message (obj: UserData)
      CHAT_PM_OUT     = 503; // Outgoing private message (obj: UserData)
      // Timer hook events (HOOK_TIMER)
      TIMER_SECOND    = 1000; // Timer event fired once per second (tick value)
      TIMER_MINUTE    = 1001; // Timer event fired once per minute (tick value)
      // Hubs hook events (HOOK_HUBS)
      HUB_OFFLINE     = 1500; // Hub has just gone offline (obj: ClientData)
      HUB_ONLINE      = 1501; // (New) hub has just gone online (obj: ClientData)
      // Connections hook events (HOOK_PROTOCOL)
      HUB_IN          = 2000; // Incoming protocol messages from hub (obj: ClientData)
      HUB_OUT         = 2001; // Outgoing protocol message to hub (obj: ClientData)
      CONN_IN         = 2002; // Incoming client<->client protocol message (obj: ConnectionData)
      CONN_OUT        = 2003; // Outgoing client<->client protocol message (obj: ConnectionData)
      // Queue hook events (HOOK_QUEUE)
      QUEUE_ADD       = 2500; // (New) item has been added to download queue (obj: QueueData)
      QUEUE_MOVE      = 2501; // Download queue item has been moved to new location (obj: QueueData)
      QUEUE_REMOVE    = 2502; // Item has just been removed from download queue (obj: QueueData)
      QUEUE_FINISHED  = 2503; // Item has just finished downloading (obj: QueueData)
      // UI hook events (HOOK_UI)
      UI_CREATED      = 3000; // Host node UI has been created (if any, obj: impl. dependant)
      UI_CHAT_DISPLAY = 3001; // Chat messages before displayed to user (obj: StringData)
      // Plugin created hook events (EVENT_USER + n)
      EVENT_USER      = 3500;
      TMetaData = record
                     name: pchar;    // Name of the plugin
                   author: pchar;    // Name/Nick of the plugin author
              description: pchar;    // *Short* description of plugin functionality (may be multiple lines)
                      web: pchar;    // Authors website if any
                     guid: pchar;    // Plugins unique GUID
             dependencies: ^pchar;   // Array of plugin dependencies
          numDependencies: cardinal; // Number of plugin GUIDs in dependencies array
                  version: double;   // Plugin version
               apiVersion: double;   // API version the plugin was compiled against
        compatibleVersion: double;   // Earliest API version the plugin can be used with
      PMetaData = ^TMetaData;
      TDCCore = record
        // Core API version
        apiVersion: double;
        // Hook creation
        create_hook: function(hookID, hookType: cardinal; defProc: pointer): pointer; stdcall;
        destroy_hook: procedure(hHook: cardinal); stdcall;
        // Hook interaction
        set_hook: function(hookID: cardinal; hookProc, pCommon: pointer): pointer; stdcall;
        call_hook: function(hookID, eventID: cardinal; pData: pointer): LongBool; stdcall;
        un_hook: function(hHook: pointer): cardinal; stdcall;
        // Message regitster
        register_message: function(hookType: cardinal; const name: pchar): cardinal; stdcall;
        register_range: function(hookType: cardinal; const name: pchar; count: cardinal): cardinal; stdcall;
        seek_message: function(const name: pchar): cardinal; stdcall;
        // Settings management
        set_cfg: procedure(const guid, settings: pchar; cval: pointer); stdcall;
        get_cfg: function(const guid, settings: pchar; cval: pointer): LongBool; stdcall;
        // General
        memalloc: function(P: pointer; bytes: cardinal): pointer; stdcall;
        strconv: function(ctype: cardinal; dst, src: pointer; len: cardinal): cardinal; stdcall;
      PDCCore = ^TDCCore;

  2. So right now what you want to do is, while not impossible, extremely hard...

    Thank you for answering!

    So, I think, there is only one way to do it now: full emulation through WinAPI user's action, like selecting user, "Send private command" and etc.

  3. No there isn't... but if there was it would be very unlikely that what you'd work with was UserData.
    Okey, I got it and download latest source code for plugins.

    From old source:

    BASE_HUB_SEND_PM(dcpp, user->object, result.c_str(), thirdPerson);
    From latest (1.3.6):
    BASE_HUB_SEND_PM(dcpp, ((UserDataPtr)cmd->object)->object, result.c_str(), thirdPerson)
    1) What is structure of UserData->object? From "PluginDefs.h" - it's just a pointer:
    dcptr_t object;
    dcptr_t declared as:
    typedef void *hookHandle, *dcptr_t, *subsHandle;

    2) Can I fill this structure manually and what I need if can?

    If there is no API for algorithm from my post above - I can try to get current userlist with WinAPI, but only username and it's hard as hell to use EnumWindows() / SendMessage() to do that...

    Any suggestions?

    Thanks in advance.

  4. Thank you for your answer!

    No there isn't... but if there was it would be very unlikely that what you'd work with was UserData.
    Oh, I see. Is there any chance that something like this would be added in future releases?

    What would you want it for exactly anyways? And if it is for blocking uploads, that is a) not really something we want to encourage and B) already possible for a plugin to do, although it's a rather roundabout way.
    No-no-no. It's not for blocking uploads.

    The basic idea behind all of this: if someone trying to download something from me he / she recieve message about HTTP site where you can find description, screenshots and other infromation related to this files.

    Algorithm (what I'm try to achieve):

    1) Send message to user when he / she start uploading something.

    2) Add user and current datetime to list.

    3) If user not in list or time difference between now and datetime from list for current user more than 24 hours - user recieve this message again and list updated with current datetime.

    4) Optionally user can send private command and this message won't be shown anymore.

  5. Hello all!

    I like to use ApexDC++, because it's very light, simply and easy to use!

    And want to thank all of the developers!

    I have a question about plugin API.

    I'm trying to write a plugin which send private message to user when he/she start to Upload something from me.

    So, I have question: is there something like QUEUE_ADD for HOOK_QUEUE, but for Upload, not Download?

    For example:

    Bool DCAPI pluginProc(uint32_t eventId, dcptr_t pData) {
      switch(eventId) {
        /* default actions */
        case ON_INSTALL:
        case ON_LOAD:
          return onLoad(eventId, (DCCorePtr)pData);
        case ON_UNINSTALL:
        case ON_UNLOAD:
          return onUnload(eventId);
        case QUEUE_ADD_UPLOAD: /* <-- I need this action to hook! */
          BASE_HUB_SEND_PM(dcpp, ((UserDataPtr)pData)->object, "Hello world!", TRUE);
          return True;
        default: return False;

    Thanks in advance.