spktbl

Member
  • Content count

    5
  • 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.

    ApexTest.pas

    
    library ApexTest;
    
    uses Windows, PluginDefs;
    
    
    const
    
      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
    
    
    var
    
       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;
    
    begin
    
      dcpp:=pData;
    
      // set hook
    
      If hook = nil Then hook:=dcpp^.set_hook(HOOK_TIMER, @pluginProc, nil);
    
      result:=True;
    
    end;
    
    
    function onUnload(eventID: cardinal): longbool;
    
    begin
    
      // remove hook
    
      if hook <> nil then
    
      begin
    
        dcpp^.un_hook(hook);
    
        hook:=nil;
    
      end;
    
      result:=True;
    
    end;
    
    
    function TimerHandle: longbool;
    
    begin
    
      result:=True;
    
      MessageBox(0, 'To disable this message boxes - uninstall plugin!', 'ApexTest plugin', MB_ICONINFORMATION);
    
    end;
    
    
    function pluginProc(eventID: cardinal; pData: pointer): longbool; stdcall;
    
    begin
    
      result:=False;
    
      case eventId of
    
        ON_INSTALL, ON_LOAD:
    
          result:=onLoad(eventId, pData);
    
        ON_UNINSTALL, ON_UNLOAD:
    
          result:=onUnload(eventId);
    
        TIMER_MINUTE:
    
          result:=TimerHandle;
    
      end;
    
    end;
    
    
    function pluginInit(info: PMetaData): pointer; stdcall;
    
    begin
    
      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;
    
      result:=@pluginProc;
    
    end;
    
    
    exports
    
      pluginInit;
    
    
    end.
    
    
    PluginDefs.pas
    
    unit PluginDefs;
    
    
    interface
    
    
    const
    
    
      // 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
    
      DCAPI_COMPATIBLE_VER = 0.50;
    
    
      // 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;
    
    
    type
    
    
      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
    
      End;
    
      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;
    
      end;
    
      PDCCore = ^TDCCore;
    
    
    implementation
    
    
    end.
    
    


  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.