Start News Client Server Entwickler Downloads Forum Bugs Impressum

EasyChat - Entwickler

Tutorial zu Plugins

In diesem Tutorial wird das EasyChat-Pluginsystem anhand eines Beispielplugins erklärt, mit dem per "Serverbefehl" ein Benutzer registriert werden kann. Eine allgemeine Pluginvorlage und der vollständige Quellcode des Beispielplugins ist ebenfalls verfügbar.

Zunächst gibt es einige Dinge zu klären. Wo wird dieses Plugin laufen? Auf dem Server, dem Client oder beiden? Welche Ereignisse müssen registriert werden?
Das Beispielplugin muss nur auf dem Server laufen und das Ereignis "ServerCommand" abfangen (registrieren). Die notwendigen Befehle sind in der RFC (Request for Comments) aufgelistet und ausführlich beschrieben.

Es ist wichtig, dass der Projektname und der Name der DLL identisch sind! Wenn zum Beispiel das Projekt "genRegisterUser" heißt, dann muss das kompilierte Plugin den Dateinamen genRegisterUser.dll besitzen.

Das Plugin ist in folgende Bereiche unterteilt:

  • Kopf: Angaben zur Version, Art, Namen und Entwickler des Plugins
  • Init-Prozedur: wird beim Start des Plugins ausgeführt.
  • Command-Prozedur: wird beim Eintreffen eines Ereignisses/Befehls aufgerufen.
  • Terminate-Prozedur: wird vor dem Beenden des Plugins ausgeführt.

Kopf

Option Explicit
'Plugin-Schnittstellen implementieren
Implements IPluginInfo
Implements IGeneralPlugin


'Name des Erstellers
Public Property Get IPluginInfo_author() As String
  IPluginInfo_author = "Stefan Rau"
End Property

'eindeutige Identifizierungs-Zeichenkette für das Plugin
Public Property Get IPluginInfo_ident() As String
  IPluginInfo_ident = "genRegisterUser"
End Property

'gibt an, zu welcher Pluginsystem-Version von EasyChat das Plugin kompatibel ist
'bei RC5 Client: 0.5 / bei RC5 Server: 1.0

Public Property Get IPluginInfo_internalversion() As String
  IPluginInfo_internalversion = "1.0"
End Property

'Name des Plugins
Public Property Get IPluginInfo_name() As String
  IPluginInfo_name = "Benutzerregistrierung"
End Property

'Art des PlugIns:
'> general - allgemeines Plugin für Client und Server
'> generalclient - allgemeines Plugin für den Client
'> generalserver - allgemeines Plugin für den Server

Public Property Get IPluginInfo_pluginType() As String
  IPluginInfo_pluginType = "generalserver"
End Property

'Pluginversion
Public Property Get IPluginInfo_version() As String
  IPluginInfo_version = "0.1"
End Property

Init-Prozedur

Nun muss das Ereignis "ServerCommand" registriert werden. Dies erfolgt in der init-Prozedur des Plugins mit folgendem Funktionsaufruf:

PluginCallback.Command Me, "AddEventHandler", "ServerCommand", vbNullString

Die Parameter zum Befehl sind in der RFC unter Server-"AddEventHandler" zu finden. In 'data' wird das zu registrierende Ereignis angegeben und für 'data2' eine leere Zeichenkette übergeben, da der Befehl in diesem Fall den Parameter nicht benötigt.
Die vollständige Prozedur sieht wie folgt aus:

'> callback_object - Verweis auf Callback im Formular (Container)
'> lcid - Sprache auf dem System
'> ecpath - Pfad zum EasyChat-Verzeichnis
'> source - gibt an, ob Plugin vom Server (server), Client (client)
'  oder den Optionen (settingsclient/settingsserver) geladen wurde
'> alwaysontop - ob Client/Server/Optionen AlwaysOnTop sind oder nicht

Public Sub IGeneralPlugin_init(ByVal callback_object As ICallback, _
    ByVal lcid As Long, _
    ByVal ecpath As String, _
    ByVal source As String, _
    ByVal alwaysontop As Boolean)
On Error Resume Next

  'Callback-Objekt merken, damit man Daten/Befehle an den Client/Server senden kann
  Set PluginCallback = callback_object
  Set plugin = Me

  If Not Left$(source, 8) = "settings" Then
    PluginCallback.Command Me, "AddEventHandler", "ServerCommand", vbNullString
  End If
End Sub

Der Befehl steht hier in einer If-Anweisung, da die init-Prozedur auch beim Öffnen der Optionen aufgerufen wird. Außerdem kann so auch ein Client & Server-Plugin mit nur einer DLL erstellt werden, da der Parameter 'source' eine Unterscheidungsmöglichkeit bietet.

Command-Prozedur

Die command-Prozedur bildet den Hauptteil des Plugins. Hier treffen alle Befehle und Ereignisse vom Client beziehungsweise Server ein. Das aufgetretene Ereignis oder der auszuführende Befehl steht im Parameter 'cmd'.

Zunächst soll die InfoBox angezeigt werden, die mit einen Klick auf den Button Info in den Optionen unter Plugins aufgerufen wird. Dazu sendet das Einstellungsfenster den Befehl "ShowAbout" an das Plugin:

Public Function IGeneralPlugin_command(ByVal cmd As String, _
    ByVal data As String, ByVal data2 As String) As String

  If cmd = "ShowAbout" Then
    MsgBox "Benutzerregistrierungsplugin v" & App.Major & "." & App.Minor & "." & _
      App.Revision & " für EasyChat v3.00 RC5" & vbCrLf & _
      "Copyright (C) 2003/2006 Stefan Rau" & vbCrLf & _
      "Kontakt: stefan.rau@ec3hp.de", vbInformation, "Über..."

Nun soll das eben registrierte Ereignis "ServerCommand" verarbeitet werden. Dazu kann aus der RFC entnommen werden, dass in dem Parameter 'data' der Befehl und Absender steht, wobei die beiden Informationen durch ein Zeichen mit dem ASCII-Wert 0 getrennt sind. Der Parameter 'data2' enthält den hinter dem Serverbefehl angegebenen Text. Wenn jetzt also im Client "\reg Stefan" eingegeben wird, dann ist der Befehl = "reg" und 'data2' = "Stefan".

Zunächst muss erst einmal überprüft werden, ob der eingetroffene Befehl "reg" ist:

  ElseIf cmd = "ServerCommand" Then
    'erstellt ein Array, in dem der Befehl und Absender stehen werden
    Dim Daten() As String
    'splittet das Array am Trennzeichen;
    'nun ist Daten(0) = Befehl und Daten(1) = Absender

    Daten = Split(data, Chr$(0))

    If Not LCase(Daten(0)) = "reg" Then Exit Function

Wenn der Befehl nicht "reg" ist, wird die Verarbeitung abgebrochen.
Gibt der Absender "info" als Parameter beim Serverbefehl an, soll eine Bedienungsanleitung zurückgegeben, ansonsten der Benutzer registriert werden. Die command-Prozedur muss immer "done" zurückgeben, wenn der Serverbefehl bearbeitet wurde. Wird dies nicht gemacht, erscheint beim Client die Meldung, dass ein unbekannter Serverbefehl angegeben wurde.

    If LCase(data2) = "info" Then
      PluginCallback.Command Me, "SendMessage", Daten(1), _
        "Informationen zum Registrieren:" & vbCrLf & _
        "Zum Registrieren eines Nicks gebt \reg NICKNAME,PASSWORT ein."
      IGeneralPlugin_command = "done"
      Exit Function
    End If

    'Unterfunktion aufrufen, die den Account erstellt
    RegisterUser daten(1), data2
    IGeneralPlugin_command = "done"
  End If
End Function

Die Unterfunktion "RegisterUser" wurde in einem extra Modul definiert, um zu zeigen, wie ein Plugin modular aufgeteilt werden kann. Damit das Plugin eine Referenz auf die Hauptklasse besitzt, wurde diese in der init-Prozedur mit der Zeile Set plugin = Me gesetzt. Der komplette Quellcode (Source) des Moduls ist:

Option Explicit
'diese Zeilen werden benötigt, um Befehle senden zu können
Public PluginCallback As ICallback
Public plugin As IPluginInfo


Public Sub RegisterUser(ByVal receiver As String, ByVal data2 As String)
On Error Resume Next

  Dim daten() As String
  daten = Split(data2, ",")

  'überprüfen, ob Nick und Passwort angegeben wurden;
  'ansonsten abbrechen und eine Nachricht schicken

  If Not UBound(daten) = 1 Then
    PluginCallback.Command plugin, "SendMessage", receiver, _
      "Du hast einen Fehler beim Angeben der Daten gemacht."
    Exit Sub
  End If

  'überprüfen, ob der Nick schon registriert ist;   'wenn nicht Account erstellen
  If PluginCallback.Command(plugin, "CreateUserAccount", daten(0), vbNullString) = "exists" Then
    PluginCallback.Command plugin, "SendMessage", receiver, _
      "Der gewählte Nick ist leider vergeben."
    Exit Sub
  End If

  'Passwort setzten und aktivieren
  PluginCallback.Command plugin, "ModifyUserAccount", daten(0) & Chr$(0) _
    & "Password", daten(1)
  PluginCallback.Command plugin, "ModifyUserAccount", daten(0) & Chr$(0) _
    & "Active", "True"
  'Bestätigung senden
  PluginCallback.Command plugin, "SendMessage", receiver, "Hallo " & daten(0) & _
    ", dein Account wurde erfolgreich mit dem Passwort " & daten(1) & " erstellt."
End Sub

Terminate

Hier sollten alle Formulare beendet und Daten freigegeben werden, damit das Plugin ordnungsgemäß beendet werden kann.

Public Sub IGeneralPlugin_terminate(ByVal callback_object As IEasyChat3.ICallback, ByVal source As String)
On Error Resume Next

  'FOLGENDE ZEILEN SIND SEHR WICHTIG !!!
  '--------------------------------------
  'Formular entladen

  Unload frmConfig
  Set frmConfig = Nothing
  'und Referenz freigeben
  Set PluginCallback = Nothing
End Sub

Wenn noch Fragen offen sind oder Hilfe benötigt wird, kann unser Support-Forum genutzt werden. Selbsterstellte Plugins können ebenfalls in diesem Forum veröffentlicht werden.