Autor Beitrag
Cyberaxx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Fr 09.09.05 14:20 
Hallo,

ich hoffe mal das ich mit dem Thema hier richtig bin.
Ich habe mir einen IRC-Services geschrieben, der das User- und Channelmanagment übernimmt. Dies tut er im Moment auch recht gut. Das Problem ist aber das bei dem OnRead Ereignis alles anfängt, der ReviceText wird ab da auseinander genommen. Es muss auf den PING reagiert werden, auf sämtliche Befehle, die von Usern kommen und auch vom Server kommen(JOIN/QUIT/NICKCHANGE z.B.).

Gerade bei JOINS muss der Service ständig lauschen und die Empfangene Nachricht Zerlegen. Da aber die SQL Anweisungen alle ein wenig Zeit brauchen um die Datenbank zu durchsuchen, liegen alle anderen Proceduren in der Zeit auf Eis.
Der Service ist auch noch nicht komplett fertig, da ich eben jetzt auf diese Probleme stosse. Bemerkt hatte ich es wenn mehrere gleichzeitig Befehle ausführen, dann kam es zu Ausfallerscheinungen. Mit Application.ProcessMessages konnte ich ihn dabei am laufen halten, die Befehle nahm er ja dennoch nicht alle an.

Hatte mich dann umgesehen nach Lösungen und dachte da an Threads oder Dyn. erstellten Komponenten. Bin mir aber nicht sicher ob das das wahre ist. Zumal ich mich da erst einarbeiten müsste. Wenn es aber nix bringt die zu benutzen, war die Zeit vorerst verschwendet denk ich mal. Hätte diese ja dann besser nutzen können.

Ich poste mal soweit es geht den ganuen Code...

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696:
697:
698:
699:
700:
701:
702:
703:
704:
705:
706:
707:
708:
709:
710:
711:
712:
713:
714:
715:
716:
717:
718:
719:
720:
721:
722:
723:
724:
725:
726:
727:
728:
729:
730:
731:
732:
733:
734:
735:
736:
737:
738:
739:
740:
741:
742:
743:
744:
745:
746:
747:
748:
749:
750:
751:
752:
753:
754:
755:
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803:
804:
805:
806:
807:
808:
809:
810:
811:
812:
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827:
828:
829:
830:
831:
832:
833:
834:
835:
836:
837:
838:
839:
840:
841:
842:
843:
844:
845:
846:
847:
848:
849:
850:
851:
852:
853:
854:
855:
856:
857:
858:
859:
860:
861:
862:
863:
864:
865:
866:
867:
868:
869:
870:
871:
872:
873:
874:
875:
876:
877:
878:
879:
880:
881:
882:
883:
884:
885:
886:
887:
888:
889:
890:
891:
892:
893:
894:
895:
896:
897:
898:
899:
900:
901:
902:
903:
904:
905:
906:
907:
908:
909:
910:
911:
912:
913:
914:
915:
916:
917:
918:
919:
920:
921:
922:
923:
924:
925:
926:
927:
928:
929:
930:
931:
932:
933:
934:
935:
936:
937:
938:
939:
940:
941:
942:
943:
944:
945:
946:
947:
948:
949:
950:
951:
952:
953:
954:
955:
956:
957:
958:
959:
960:
961:
962:
963:
964:
965:
966:
967:
968:
969:
970:
971:
972:
973:
974:
975:
976:
977:
978:
979:
980:
{ ----------------------- IRC SERVER SERVICES -------------------------------- }
{ Dieser Service dient zum verwalten der Benutzer und Channels eines           }
{ IRC-SERVERS. Als Grundvorlage diente der Original Service von Gamesurge.     }
{                                                                              }
{ Zur Zeit ist noch ein MS-SQL Server zum Betrieb des Services nötig!          }
{ Zum Grungerüst gehören zwei Tabellen:                                        }
{                                                                              }
{ USERREG        <-- Registrierte Benutzer                                     }
{ CHANREG        <-- Registrierte Channels                                     }
{ CHAN_ULEVEL_ID <-- USER Verwaltung der Channels. Wird beim Registrieren      }
{                    eines Channels angelegt. ID ist der Bezug zur CHANREG     }
{                    Tabelle. Dort wird die USERID abgelegt eines              }
{                    registrierten USERS abgelegt und seine Channel Rechte     }
{                                                                              }
{                                                                              }
{                                                                              }
{                                                                              }
{                                                                              }
{                                                                              }
{                                                                              }
{ ---------------------------------------------------------------------------- }
{  Variablen                                                                   }
{  Tokenindex   : Index des zu suchenden Wortes                                }
{  Nick         : Derzeitiger Nick eines User's                                }
{  Ch_Nick      : Bei einem Nickchange der neue Nick                           }
{  Channel      : Der Channel in dem ein Befehl ausgeführt wurde               }
{  Topic        : Topic-Zeile eines Channels                                   }
{  Modes        : Channel-Modes                                                }
{  C_Command    : Der auszuführende Befehl e.g. !users                         }
{  Authnick     : Nick der bei der Registrierung und beim Authen angegeben wird}
{  Authpass     : Selbige wie Authnick nur eben das Passwort                   }
{                 Authnick und Authpass deinen dazu das der Service den User   }
{                 Identifizieren kann                                          }
{  SQL_String   : Hier wird die Aktuelle SQL Anweisung geschrieben             }
{  Owner        : Nick auf den ein Channel Registriert wird                    }
{  OwnerID      : Zum Owner/Nick die dazugehörige ID                           }
{  ChannelPw    : Das Passwort des Channel um Administrative änderungen        }
{                 vozunehmen                                                   }
{  Chan         : Channelname eines Registrierten Channels                     }
{  ChanID       : Zum Channelname die dazugehörige ID                          }
{  Chancreate_T :                                                              }
{  Chancreate_D :                                                              }
{  AddNick      :                                                              }
{  AddNick_ID   :                                                              }
{  AddChan      :                                                              }
{  AddChan_ID   :                                                              }
{  User_ID      :                                                              }
{  CMD_ChReg    :                                                              }
{  CMD_Invite   :                                                              }
{  CMD_NoVoice  :                                                              }
{  CMD_NoOp     :                                                              }
{  Access_LVL   :                                                              }
{  CMD_CLVL     :                                                              }
{ ---------------------------------------------------------------------------- }
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp, DB, ADODB, ExtCtrls, Grids, DBGrids;

type
  Tmain = class(TForm)
    GbServerDaten: TGroupBox;
    EdIp: TEdit;
    LbIp: TLabel;
    EdPort: TEdit;
    LbPort: TLabel;
    GbTraffic: TGroupBox;
    MmTraffic: TMemo;
    GbOrders: TGroupBox;
    EdOrders: TEdit;
    GbClientActions: TGroupBox;
    BtSwitchStatus: TButton;
    ClientSocket: TClientSocket;
    connection: TADOConnection;
    regchan_sql: TADOQuery;
    Regchan_DS: TDataSource;
    Memo1: TMemo;
    REG_SQL: TADOQuery;
    AUTH_SQL: TADOQuery;
    REG_DS: TDataSource;
    AUTH_DS: TDataSource;
    CREATOR: TADOQuery;
    UREG_SQL: TADOQuery;
    UREG_DS: TDataSource;
    USER_SQL: TADOQuery;
    USER_DS: TDataSource;
    ChanA_CMD_SQL: TADOQuery;
    ChanA_CMD_DS: TDataSource;
    procedure BtSwitchStatusClick(Sender: TObject);
    procedure ClientSocketConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketConnecting(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocketLookup(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure EdOrdersKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    Procedure Chanserv_Userchan_Managment(NICKNAME:STRING);
  private
    tokenindex:integer;
    Nick, Ch_Nick, Channel, topic, modes, C_COMMAND, AUTHNICK, AUTHPASS,
    SQL_String, OWNER, CHANPW, CHAN, OWNERID, CHANID,
    CHANCREATE_T, CHANCREATE_D,
    ADDNICK, ADDNICK_ID, ADDCHAN, ADDCHAN_ID, USER_ID,
    CMD_CHREG, CMD_INVITE, CMD_NOVOICE, CMD_NOOP:string;
    ACCESS_LVL, CMD_CLVL:Integer;
    procedure Switch;
  public
    { Public declarations }
  end;

var
  main: Tmain;
  Status: Boolean;

implementation

{$R *.dfm}

function GetToken(aString, SepChar: String; TokenNum: Byte):String;
{
parameters: aString : the complete string
            SepChar : a single character used as separator 
                      between the substrings
            TokenNum: the number of the substring you want
result    : the substring or an empty string if the are less then
            'TokenNum' substrings
}

var
   Token     : String;
   StrLen    : Byte;
   TNum      : Byte;
   TEnd      : Byte;
 
begin
     StrLen := Length(aString);
     TNum   := 1;
     TEnd   := StrLen;
     while ((TNum <= TokenNum) and (TEnd <> 0)) do
     begin
          TEnd := Pos(SepChar,aString);
          if TEnd <> 0 then
          begin
               Token := Copy(aString,1,TEnd -1);
               Delete(aString,1,TEnd);
               Inc(TNum);
          end
          else
          begin
               Token := aString;
          end;
     end;
     if TNum > TokenNum then
     begin
          result := Token;
     end
     else
     begin
          result := Copy(aString,1,length(astring)-2);
     end;
end;



function NumToken(aString, SepChar: String):Byte;
{
parameters: aString : the complete string
            SepChar : a single character used as separator
                      between the substrings
result    : the number of substrings
}


var
   RChar     : Char;
   StrLen    : Byte;
   TNum      : Byte;
   TEnd      : Byte;

begin
     if SepChar = '#' then
     begin
          RChar := '*'
     end
     else
     begin
         RChar := '#'
     end;
     StrLen := Length(aString);
     TNum   := 0;
     TEnd   := StrLen;
     while TEnd <> 0 do
     begin
          Inc(TNum);
          TEnd := Pos(SepChar,aString);
          if TEnd <> 0 then
          begin
               aString[TEnd] := RChar;
          end;
     end;
     result := TNum;
end;

procedure Tmain.Switch;
begin
 Status:=ClientSocket.Active;
 if BtSwitchStatus.Caption='Connect' then
 begin
  BtSwitchStatus.Caption:='Disconnect';
 end
 else
 begin
  BtSwitchStatus.Caption:='Connect';
 end;
end;

procedure Tmain.BtSwitchStatusClick(Sender: TObject);
begin
 if BtSwitchStatus.Caption='Connect' then
 begin
  Switch;
  MmTraffic.Lines.Add('Connecting to: ' + EdIp.Text + ' [' + EdPort.Text + ']');
  ClientSocket.Address:=EdIp.Text;
  ClientSocket.Port:=StrToInt(EdPort.Text);
  ClientSocket.Open;
  Connection.Connected := true;
  regchan_sql.Active := true;

  SQL_String := 'UPDATE UserReg SET '
               + 'NICK = ' + '''' + '' + '''';

    AUTH_SQL.SQL.Clear;
    AUTH_SQL.SQL.Add(sql_string);
    AUTH_SQL.ExecSQL;
 end
 else
 begin
  ClientSocket.Close;
  Switch;
 end;

end;


procedure Tmain.ClientSocketConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
MmTraffic.Lines.Add('Connection established to: ' + Socket.RemoteHost + ' [' + Socket.RemoteAddress + ']');
clientsocket.Socket.SendText('PASS servlink'+#13);
//clientsocket.Socket.SendText('NICK Test'+#13);
clientsocket.Socket.SendText('SERVER Services.Lightbow.dyndns.org 3 LBT Services.Lightbow.dyndns.org'+#13);
//clientsocket.Socket.SendText('USER Service 192.168.10.10 192.168.10.10 :Wirklicher Name'+#13);
end;


procedure Tmain.ClientSocketLookup(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 MmTraffic.Lines.Add('Looking up...')
end;


procedure Tmain.ClientSocketConnecting(Sender: TObject;
  Socket: TCustomWinSocket);
begin
MmTraffic.Lines.Add('Connecting to: ' + EdIp.Text + ' [' + EdPort.Text + ']');
end;

procedure Tmain.ClientSocketDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
MmTraffic.Lines.Add('Disconnected');
end;


procedure Tmain.ClientSocketError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
 MmTraffic.Lines.Add('Error: ' + IntToStr(Ord(ErrorEvent)));
 case ErrorEvent of
  eeGeneral:
  begin
//   The socket received an error message that does not fit into any of the following categories.
  end;
  eeSend:
  begin
//   An error occurred when trying to write to the socket connection.
  end;
  eeReceive:
  begin
//   An error occurred when trying to read from the socket connection.
  end;
  eeConnect:
  begin
//   A connection request that was already accepted could not be completed.
  end;
  eeDisconnect:
  begin
//   An error occurred when trying to close a connection.
  end;
  eeAccept:
  begin
//   A problem occurred when trying to accept a client connection request.
  end;
 end;
end;


procedure Tmain.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var rec, uprec:string;
      i, U:Integer;
begin
application.ProcessMessages;
rec := Socket.ReceiveText;
uprec := uppercase(rec);
MmTraffic.Lines.Add('<' + timetostr(time)+ '> ' + rec);
//MmTraffic.Lines.Add(uppercase(rec));
MmTraffic.Lines.Add('<' + timetostr(time) + '> -');

// Pong an den Server senden
  if(pos('PING', rec)>0then
    begin
    Clientsocket.Socket.sendtext('PONG ' + copy(rec,pos('PING',rec) +4, length(rec))+#13);
    end;

// Nach dem erfolgreichen verbinden Nicks erstellen
  if (pos(':Lightbow.Home EOS', rec)>0then begin
    Socket.sendtext('NICK ChanServ 3 Service Services.Lightbow.dyndns.org LBT Services.Lightbow.dyndns.org :ChanServ'#13);
    Socket.sendtext('NICK NickServ 3 Service Services.Lightbow.dyndns.org LBT Services.Lightbow.dyndns.org :NickServ'#13);
    MmTraffic.Lines.Add('nickline');

// In dem IF die registrierten Channels joinen und Chanserv +oq geben
    for I := 1 to regchan_sql.RecordCount do
      begin
      channel := Regchan_ds.DataSet.fieldbyname('Channel').AsString;
      topic := Regchan_ds.DataSet.fieldbyname('Topic').AsString;
      modes := Regchan_ds.DataSet.fieldbyname('Modes').AsString;
      ClientSocket.Socket.sendtext(':ChanServ JOIN ' + channel + #13);
      ClientSocket.Socket.sendtext('MODE ' + channel + ' +oq ChanServ ChanServ'#13);
      if TOPIC <> '' then ClientSocket.Socket.sendtext(':ChanServ TOPIC ' + channel + ' :' + topic +#13);
      if MODES <> '' then ClientSocket.Socket.sendtext(':ChanServ MODE ' + channel + ' :-tnspmilkcdqj +' + modes +#13);
      regchan_ds.DataSet.Next;
      //if regchan_ds.DataSet.RecNo = regchan_ds.DataSet.RecordCount then regchan_sql.Active := false;
      end;
  end;

// ################### Nickserv Query Routinen #######################################################################
if (pos('PRIVMSG NICKSERV :AUTH', uprec) >0then
  begin
  If NumToken(rec, ' ') = 6 then
    begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    AUTHNICK := GetToken(rec, ' '5);
    AUTHPASS := GetToken(rec, ' '6);

    SQL_String := 'SELECT Authnick, Authpass, nick FROM UserReg '
               + 'WHERE authnick = ' + '''' + authnick + '''' + ' AND Authpass = '
               + '''' + Authpass + '''';

    AUTH_SQL.SQL.Clear;
    AUTH_SQL.SQL.Add(sql_string);
    AUTH_SQL.Active := true;
    AUTH_SQL.Requery();

    if AUTH_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :ERROR! Du bist nicht Registriert!' +#13);
    if (AUTH_DS.DataSet.RecordCount = 1and (AUTH_DS.DataSet.FieldByName('NICK').AsString = NICK) then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Du bist bereits geauted!' +#13);
    if (AUTH_DS.DataSet.RecordCount = 1and (AUTH_DS.DataSet.FieldByName('NICK').AsString = '')  then
      begin

      SQL_String := 'UPDATE UserReg SET '
                 + 'NICK = ' + '''' + NICK + '''' + ', ' + 'SeeLast = ' + '''' + 'here' + ''''
                 + ' WHERE authnick = ' + '''' + authnick + '''' + ' AND Authpass = ' + '''' + Authpass + '''';

      AUTH_SQL.SQL.Clear;
      AUTH_SQL.SQL.Add(sql_string);
      AUTH_SQL.ExecSQL;

      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Du bist nun bei dem Server angemeldet! Have Fun :)' +#13);

      Chanserv_Userchan_Managment(NICK); // Wenn sich ein User authet Prozedure aufrufen

      end;
    end;
  If NumToken(rec, ' ') < 6 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Unzureichende Datenmenge. Registrierung wird abgebrochen!' +#13);
  If NumToken(rec, ' ') > 6 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Datenmenge zu gross. Registrierung wird abgebrochen!' +#13);
  end;

if (pos('PRIVMSG NICKSERV :REGISTER', uprec) >0then
  begin
  If NumToken(rec, ' ') = 6 then
    begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    AUTHNICK := GetToken(rec, ' '5);
    AUTHPASS := GetToken(rec, ' '6);

    SQL_String := 'SELECT Authnick FROM UserReg '
               + 'WHERE authnick = ' + '''' + authnick + '''';

    REG_SQL.SQL.Clear;
    REG_SQL.SQL.Add(sql_string);
    REG_SQL.Active := true;
    REG_SQL.Requery();

    // beim reggen überprüfen ob der nick bereits geauthet ist!

    IF REG_DS.DataSet.RecordCount > 0 then // Falls der Authnick bereits vergeben wurde meckern
      begin
      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Registration Error' +#13);
      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :AuthNick: ' + Authnick + ' ist bereits vergeben' +#13);
      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Verwebden sie einen anderen Authnick' +#13);
      end;

    IF REG_DS.DataSet.RecordCount = 0 then // Nur wenn der Authnick noch nicht vergeben ist Registrieren
      Begin
      SQL_String := 'INSERT INTO Userreg (Authnick, Authpass, Regdatum) '
                 + 'VALUES (' + '''' + Authnick + '''' + ', ' + '''' + Authpass + '''' + ', ' +
                 '''' + DatetoStr(Date) + '''' + ')';

      REG_SQL.SQL.Clear;
      REG_SQL.SQL.Add(sql_string);
      REG_SQL.ExecSQL;

      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Registration Complete' +#13);
      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :AuthNick: ' + Authnick + ' AuthPass: ' + Authpass +#13);
      ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' :Type: /MSG NickServ Auth ' + Authnick +  ' ' + Authpass + ' to login' +#13);
      end;

    end;
  If NumToken(rec, ' ') < 6 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Unzureichende Datenmenge. Authing wird abgebrochen!' +#13);
  If NumToken(rec, ' ') > 6 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Datenmenge zu gross. Authing wird abgebrochen!' +#13);
  end;
// ################### Nickserv Query Rpoutinen #######################################################################

// ################### Chanserv Channel Routinen ######################################################################
if (pos(':!UP', uprec) >0then // Userstatus ändern sofern user rechte hat
  begin
  if GetToken(uprec, ' '4) = ':!UP' then
    begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHANNEL := GetToken(rec, ' '3);
    C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
    ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
    ClientSocket.Socket.sendtext(':Chanserv MODE ' + Channel + ' +o ' + nick +#13);
    end;
  end;

if (pos(':!DOWN', uprec) >0then // Userstatus ändern sofern user rechte hat
  begin
  if GetToken(uprec, ' '4) = ':!DOWN' then
    begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHANNEL := GetToken(rec, ' '3);
    C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
    ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
    ClientSocket.Socket.sendtext(':Chanserv MODE ' + Channel + ' -o ' + nick +#13);
    end;
  end;

if (pos(':!HELP', uprec) >0then // Hilfe
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!USERS', uprec) >0then // Zeigt alle Registrierten User an
  begin
  if GetToken(uprec, ' '4) = ':!USERS' then
    Begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHANNEL := GetToken(rec, ' '3);
    //C_Command := copy(GetToken(rec, ' ', 4), 2, length(GetToken(rec, ' ', 4)));

    SQL_String := 'SELECT Create_Date, Create_Time FROM chanreg '
               + 'WHERE channel = ' + '''' + CHANNEL + '''';

    USER_SQL.SQL.Clear;            // Channelinformationen
    USER_SQL.SQL.Add(sql_string);  // holen um den erstellungszeitpunkt
    USER_SQL.Active := true;       // und die Registrierten User anzuzeigen
    USER_SQL.Requery();

    CHANCREATE_D := USER_DS.DataSet.FieldByName('Create_Date').AsString;
    CHANCREATE_T := USER_DS.DataSet.FieldByName('Create_Time').AsString;

    SQL_String := 'SELECT userreg.authnick AS Account, CHAN_ULEVEL.CLVL AS Access, userreg.SeeLast '
               + 'FROM CHAN_ULEVEL INNER JOIN '
               + 'userreg ON CHAN_ULEVEL.USERID = userreg.ID '
               + 'WHERE (CHAN_ULEVEL.CHANNEL = ' + '''' + CHANNEL + '''' + ') '
               + 'ORDER BY CHAN_ULEVEL.CLVL DESC';

    USER_SQL.SQL.Clear;            // Aus der Channeltabelle
    USER_SQL.SQL.Add(sql_string);  // die User und deren Lvl
    USER_SQL.Active := true;       // holen
    USER_SQL.Requery();

    ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + NICK + ' :' + CHANNEL + ' wurde erstellt am '
                                + CHANCREATE_D + ' um ' + CHANCREATE_T +#13);
    ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + NICK + ' :Users von Level 1 bis 500:' +#13);
    ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + NICK + ' :Access Account Last-Seen Status' +#13);

    For U := 1 to USER_DS.DataSet.RecordCount do
      begin
      ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + NICK + ' : '
                                  + USER_DS.DataSet.FieldByName('Access').AsString
                                  + ' ' + USER_DS.DataSet.FieldByName('Account').AsString 
                                  + ' ' + USER_DS.DataSet.FieldByName('SeeLast').AsString +#13);
      USER_DS.DataSet.Next;
      end;
    end;
  end;

if (pos(':!ADDPEON', uprec) >0then // Fürgt einen User hinzu mit Access 100
  begin
  if (GetToken(uprec, ' '4) = ':!ADDPEON'and (NumToken(rec, ' ') = 5then
    Begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHANNEL := GetToken(rec, ' '3);
    ADDNICK := GetToken(rec, ' '5);

    SQL_String := 'SELECT ID, nick FROM UserReg '
               + 'WHERE nick = ' + '''' + nick + '''';

    UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
    UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
    UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
    UREG_SQL.Requery();

    USER_ID := UREG_DS.DataSet.fieldbyname('ID').asstring;

    if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist nicht Geatuhed oder Registriert!' +#13);
    if (UREG_DS.DataSet.RecordCount = 1then
      begin

      SQL_String := 'SELECT userreg.authnick AS Account, CHAN_ULEVEL.CLVL AS Access, CHAN_ULEVEL.CHANNELID '
                 + 'FROM CHAN_ULEVEL INNER JOIN '
                 + 'userreg ON CHAN_ULEVEL.USERID = userreg.ID '
                 + 'WHERE (CHAN_ULEVEL.CHANNEL = ' + '''' + CHANNEL + '''' + ') AND '
                 + '(CHAN_ULEVEL.USERID = ' + '''' + USER_ID + '''' + ')';

      UREG_SQL.SQL.Clear;            // User registrator muss im betreffenden Channel das
      UREG_SQL.SQL.Add(sql_string);  // Recht haben einen User zu adden
      UREG_SQL.Active := true;
      UREG_SQL.Requery();

      ACCESS_LVL := UREG_DS.DataSet.fieldbyname('ACCESS').AsInteger;
      ADDCHAN_ID := UREG_DS.DataSet.fieldbyname('CHANNELID').AsString;

      if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist nicht im Channel ' + CHANNEL + ' registriert!' +#13);
      if (UREG_DS.DataSet.RecordCount = 1and (ACCESS_LVL < 250then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du hast nicht das Recht einen User zu registrieren!' +#13);
      if (UREG_DS.DataSet.RecordCount = 1and (ACCESS_LVL >= 250then
        begin

        SQL_String := 'SELECT ID, nick FROM UserReg '
                   + 'WHERE nick = ' + '''' + ADDNICK + '''';

        UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
        UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
        UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
        UREG_SQL.Requery();

        ADDNICK_ID := UREG_DS.DataSet.fieldbyname('ID').asstring;

        if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' : USER ' + ADDNICK + ' ist nicht online oder geauthed!' +#13);
        if UREG_DS.DataSet.RecordCount = 1 then
          begin

          SQL_String := 'SELECT CHANNELID, USERID '
                     + 'FROM CHAN_ULEVEL '
                     + 'WHERE (USERID = ' + '''' + ADDNICK_ID + '''' + ') AND (CHANNELID = ' + '''' + ADDCHAN_ID + '''' + ')';

          UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
          UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
          UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
          UREG_SQL.Requery();

          if UREG_DS.DataSet.RecordCount = 1 then ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' : USER ' + ADDNICK + ' ist bereits registriert!' +#13);
          if UREG_DS.DataSet.RecordCount = 0 then
            begin

            SQL_String := 'INSERT INTO CHAN_ULEVEL (USERID, CHANNEL , CHANNELID, CLVL) '
                       + 'VALUES (' + '''' + ADDNICK_ID + '''' + ', '
                       + '''' + CHANNEL + '''' + ', ' + '''' + ADDCHAN_ID + '''' + ', '
                       + '''' + '100' + '''' + ')';

            UREG_SQL.SQL.Clear;             // Neue Channeltabelle erstellen
            UREG_SQL.SQL.Add(sql_string);   // und mit registrierungsdaten füllen
            UREG_SQL.ExecSQL;

            ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' :USER: ' + ADDNICK + ' wurde mit Access 100 hinzugefügt.' +#13);
            end;
          end;

        end;
      end;
    end;
  end;

if (pos(':!ADDOP', uprec) >0then // Fürgt einen User hinzu mit Access 100
  begin
  if (GetToken(uprec, ' '4) = ':!ADDOP'and (NumToken(rec, ' ') = 5then
    Begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHANNEL := GetToken(rec, ' '3);
    ADDNICK := GetToken(rec, ' '5);

    SQL_String := 'SELECT ID, nick FROM UserReg '
               + 'WHERE nick = ' + '''' + nick + '''';

    UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
    UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
    UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
    UREG_SQL.Requery();

    USER_ID := UREG_DS.DataSet.fieldbyname('ID').asstring;

    if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist nicht Geatuhed oder Registriert!' +#13);
    if (UREG_DS.DataSet.RecordCount = 1then
      begin

      SQL_String := 'SELECT userreg.authnick AS Account, CHAN_ULEVEL.CLVL AS Access, CHAN_ULEVEL.CHANNELID '
                 + 'FROM CHAN_ULEVEL INNER JOIN '
                 + 'userreg ON CHAN_ULEVEL.USERID = userreg.ID '
                 + 'WHERE (CHAN_ULEVEL.CHANNEL = ' + '''' + CHANNEL + '''' + ') AND '
                 + '(CHAN_ULEVEL.USERID = ' + '''' + USER_ID + '''' + ')';

      UREG_SQL.SQL.Clear;            // User registrator muss im betreffenden Channel das
      UREG_SQL.SQL.Add(sql_string);  // Recht haben einen User zu adden
      UREG_SQL.Active := true;
      UREG_SQL.Requery();

      ACCESS_LVL := UREG_DS.DataSet.fieldbyname('ACCESS').AsInteger;
      ADDCHAN_ID := UREG_DS.DataSet.fieldbyname('CHANNELID').AsString;

      if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist nicht im Channel ' + CHANNEL + ' registriert!' +#13);
      if (UREG_DS.DataSet.RecordCount = 1and (ACCESS_LVL < 250then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du hast nicht das Recht einen User zu registrieren!' +#13);
      if (UREG_DS.DataSet.RecordCount = 1and (ACCESS_LVL >= 250then
        begin

        SQL_String := 'SELECT ID, nick FROM UserReg '
                   + 'WHERE nick = ' + '''' + ADDNICK + '''';

        UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
        UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
        UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
        UREG_SQL.Requery();

        ADDNICK_ID := UREG_DS.DataSet.fieldbyname('ID').asstring;

        if UREG_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' : USER ' + ADDNICK + ' ist nicht online oder geauthed!' +#13);
        if UREG_DS.DataSet.RecordCount = 1 then
          begin

          SQL_String := 'SELECT CHANNELID, USERID '
                     + 'FROM CHAN_ULEVEL '
                     + 'WHERE (USERID = ' + '''' + ADDNICK_ID + '''' + ') AND (CHANNELID = ' + '''' + ADDCHAN_ID + '''' + ')';

          UREG_SQL.SQL.Clear;            // der jednige der den Befehl aufruft
          UREG_SQL.SQL.Add(sql_string);  // muss Registriert und geauthed
          UREG_SQL.Active := true;       // sein um einen user hinzuzufügen
          UREG_SQL.Requery();

          if UREG_DS.DataSet.RecordCount = 1 then ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' : USER ' + ADDNICK + ' ist bereits registriert!' +#13);
          if UREG_DS.DataSet.RecordCount = 0 then
            begin

            SQL_String := 'INSERT INTO CHAN_ULEVEL (USERID, CHANNEL , CHANNELID, CLVL) '
                       + 'VALUES (' + '''' + ADDNICK_ID + '''' + ', '
                       + '''' + CHANNEL + '''' + ', ' + '''' + ADDCHAN_ID + '''' + ', '
                       + '''' + '200' + '''' + ')';

            UREG_SQL.SQL.Clear;             // Neue Channeltabelle erstellen
            UREG_SQL.SQL.Add(sql_string);   // und mit registrierungsdaten füllen
            UREG_SQL.ExecSQL;

            ClientSocket.Socket.sendtext(':Chanserv NOTICE ' + nick + ' :USER: ' + ADDNICK + ' wurde mit Access 200 hinzugefügt.' +#13);
            end;
          end;

        end;
      end;
    end;
  end;

if (pos(':!ADDMASTER', uprec) >0then // Fürgt einen User hinzu mit Access 100
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!ADDCORNER', uprec) >0then // Fürgt einen User hinzu mit Access 100
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!ADDUSER', uprec) >0then // Fürgt einen User hinzu
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!DELUSER', uprec) >0then // Löscht einen User
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!ACCESS', uprec) >0then // Ändert / Zeigt die Zugriffsrechte eines User
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!USET', uprec) >0then // USET Befehle
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!SET', uprec) >0then // USET Befehle
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;

if (pos(':!INFO', uprec) >0then // Gibt informationen über den Channel aus
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHANNEL := GetToken(rec, ' '3);
  C_Command := copy(GetToken(rec, ' '4), 2, length(GetToken(rec, ' '4)));
  ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + Channel + ' : ' + nick + ' COMMAND --> ' + C_Command +#13);
  end;
// ################### Chanserv Channel Routinen ######################################################################

// ################### Server Channel Routinen ########################################################################
if (pos('NICK', rec) >0then // Nickchange registrieren und update der Datenbank machen
  begin
  if GetToken(rec, ' '2) = 'NICK' then
    Begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CH_NICK := GetToken(rec, ' '3);

    SQL_String := 'UPDATE UserReg SET '
               + 'NICK = ' + '''' + CH_NICK + ''''
               + ' WHERE NICK = ' + '''' + NICK + '''';

    AUTH_SQL.SQL.Clear;
    AUTH_SQL.SQL.Add(sql_string);
    AUTH_SQL.ExecSQL;

    //ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + '#Welcome' + ' : ' + nick + ' NICKCHANGE --> ' + CH_NICK +#13);
    end;
  end;

if (pos('QUIT', rec) >0then // QUIT Registrieren und in die Datenbank setzen
  begin
  if GetToken(rec, ' '2) = 'QUIT' then
    Begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));

    SQL_String := 'UPDATE UserReg SET '
               + 'NICK = ' + '''' + '' + '''' + ', '
               + 'SeeLast = ' + '''' + datetostr(date) + ' ' + Timetostr(time) + '''' 
               + ' WHERE NICK = ' + '''' + NICK + '''';

    AUTH_SQL.SQL.Clear;
    AUTH_SQL.SQL.Add(sql_string);
    AUTH_SQL.ExecSQL;

    //ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + '#Welcome' + ' : QUIT --> ' + NICK +#13);
    end;
  end;

if (pos('NICK', rec) >0then // JOIN registrieren und eintrag aus der Datenbank löschen
  begin
  if GetToken(rec, ' '1) = 'NICK' then
    Begin
    Nick := GetToken(rec, ' '2);
    //ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + '#Welcome' + ' :CONNECT --> ' + NICK +#13);
    end;
  end;

// ################### SERVER HANDLING ################################################################################
if (pos(':!SERVICE RESTART', uprec) >0then // Veranlasst den SERVICE zu einem Neustart
  begin
  if (GetToken(uprec, ' '4) = ':!SERVICE'and (GetToken(uprec, ' '5) = 'RESTART')then
    Begin
    ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + '#Welcome' + ' :<-- RESTART ' +#13);
      regchan_sql.Active := false;
      ClientSocket.Close;
      clientsocket.Open;
      regchan_sql.Active := true;
    end;
  end;

if (pos(':!SERVICE CLEARLOG', uprec) >0then // Löscht das Log des SERVICES
  begin
  if (GetToken(uprec, ' '4) = ':!SERVICE'and (GetToken(uprec, ' '5) = 'CLEARLOG')then
    Begin
    ClientSocket.Socket.sendtext(':Chanserv PRIVMSG ' + '#Welcome' + ' :<-- LOG CLEARED ' +#13);
      mmtraffic.Clear;
    end;
  end;

if (pos('PRIVMSG CHANSERV :REGISTER', uprec) >0then // Channel Registrieren
  begin
  If NumToken(rec, ' ') = 7 then // Anzahl der Tokens muss 7 sein sonst geht das registrieren schief
    begin
    Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
    CHAN := GetToken(rec, ' '5);
    OWNER := GetToken(rec, ' '6);
    CHANPW := GetToken(rec, ' '7);

    SQL_String := 'SELECT nick, Servop FROM UserReg '
               + 'WHERE nick = ' + '''' + nick + '''';

    REGCHAN_SQL.SQL.Clear;            // der jednige der den Registrierungsbefehl aufruft
    REGCHAN_SQL.SQL.Add(sql_string);  // muss Registriert, geauthed und auch das recht haben
    REGCHAN_SQL.Active := true;       // einen Channel zu Registrieren
    REGCHAN_SQL.Requery();

    if REGCHAN_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist nicht Geatuhed oder Registriert!' +#13);
    if (REGCHAN_DS.DataSet.RecordCount = 1and (REGCHAN_DS.DataSet.FieldByName('NICK').AsString = NICK) and (REGCHAN_DS.DataSet.FieldByName('servop').AsString <> '1'then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Du bist kein Server Admin!' +#13);
    if (REGCHAN_DS.DataSet.RecordCount = 1and (REGCHAN_DS.DataSet.FieldByName('NICK').AsString = NICK) and (REGCHAN_DS.DataSet.FieldByName('servop').AsString = '1'then
      begin

      SQL_String := 'SELECT ID, authnick, nick FROM UserReg '
                 + 'WHERE nick = ' + '''' + OWNER + '''';

      REGCHAN_SQL.SQL.Clear;            // es muss sichergestellt sein, das der channel
      REGCHAN_SQL.SQL.Add(sql_string);  // nur auf eine registrierte person registriert werden kann
      REGCHAN_SQL.Active := true;
      REGCHAN_SQL.Requery();

      OWNERID := REGCHAN_DS.DataSet.FieldByName('ID').AsString;

      if REGCHAN_DS.DataSet.RecordCount = 0 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! USER: ' + OWNER + ' ist nicht online oder registriert!' +#13);
      if REGCHAN_DS.DataSet.RecordCount = 1 then
        begin

        SQL_String := 'SELECT channel FROM chanreg '
                   + 'WHERE channel = ' + '''' + CHAN + '''';

        REGCHAN_SQL.SQL.Clear;            // Überprüfen od der Channel bereits Registriert ist
        REGCHAN_SQL.SQL.Add(sql_string);  // Registrierung nur fortfahren wenn der channel nicht
        REGCHAN_SQL.Active := true;       // existiert
        REGCHAN_SQL.Requery();

        if REGCHAN_DS.DataSet.RecordCount = 1 then ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :ERROR! Channel: ' + CHAN + ' wurde bereits registriert!' +#13);
        if REGCHAN_DS.DataSet.RecordCount = 0 then
          begin
          SQL_String := 'INSERT INTO Chanreg (channel, USER_ID, password, Create_Date, Create_Time) '
                     + 'VALUES (' + '''' + CHAN + '''' + ', ' + '''' + OWNERID + '''' + ', ' +
                     '''' + CHANPW + '''' + ',' + '''' + DateToStr(Date) + '''' + ', ' +
                     '''' + TimeToStr(TIME) + '''' + ')';

          REGCHAN_SQL.SQL.Clear;             // Channel in der Channel Tabelle
          REGCHAN_SQL.SQL.Add(sql_string);   // aufnehmen
          REGCHAN_SQL.ExecSQL;

          SQL_String := 'SELECT PK_Chan FROM chanreg '
                      + 'WHERE channel = ' + '''' + CHAN + ''''
                      + ' AND USER_ID = ' + '''' + OWNERID + '''';

          REGCHAN_SQL.SQL.Clear;            // Channel ID holen um damit
          REGCHAN_SQL.SQL.Add(sql_string);  // die Channel spezifische
          REGCHAN_SQL.Active := true;       // Tebelle zu erstellen
          REGCHAN_SQL.Requery();

          CHANID := REGCHAN_DS.DataSet.FieldByName('PK_CHAN').AsString;

          SQL_String := 'INSERT INTO CHAN_ULEVEL (USERID, CHANNEL , CHANNELID, CLVL) '
                     + 'VALUES (' + '''' + OWNERID + '''' + ', '
                     + '''' + CHAN + '''' + ', ' + '''' + CHANID + '''' + ', '
                     + '''' + '500' + '''' + ')';

          REGCHAN_SQL.SQL.Clear;             // Neue Channeltabelle erstellen
          REGCHAN_SQL.SQL.Add(sql_string);   // und mit registrierungsdaten füllen
          REGCHAN_SQL.ExecSQL;

          ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICK + ' :Der Channel ' + CHAN + ' wurde registriert.' +#13);

          ClientSocket.Socket.sendtext(':ChanServ JOIN ' + CHAN + #13);
          ClientSocket.Socket.sendtext('MODE ' + CHAN + ' +oq ChanServ ChanServ'#13);

          ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + OWNER + ' :Der Channel ' + CHAN + ' wurde auf Dich registriert.' +#13);
          ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + OWNER + ' :Du kannst ihn mit /JOIN ' + CHAN + ' betreten' +#13);
          end;
        end;
      end;
    end;
  If NumToken(rec, ' ') < 7 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Unzureichende Datenmenge. Channel Registrierung wird abgebrochen!' +#13);
  If NumToken(rec, ' ') > 7 then ClientSocket.Socket.sendtext(':NickServ NOTICE ' + NICK + ' Datenmenge zu gross. Channel Registrierung wird abgebrochen!' +#13);
  end;
// ################### SERVER HANDLING ################################################################################

// BADWORD Kickliste
if (pos('BVB', uprec) >0)
  or (pos('FUSSBALL', uprec) >0)
  or (pos('FUßBALL', uprec) >0)
  or (pos('f*****', uprec) >0then
  begin
  Nick := copy(GetToken(rec, ' '1), 2, length(GetToken(rec, ' '1)));
  CHAN := GetToken(rec, ' '3);
  ClientSocket.Socket.sendtext('KICK ' + CHAN + ' ' + NICK + ' :Das ist ein unerlaubtes Wort!!!' +#13);
  end;
// BADWORD Kickliste

// ################### Server Channel Routinen ########################################################################
end;


procedure Tmain.EdOrdersKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if key=13 then
 begin
  Clientsocket.Socket.SendText(EdOrders.Text+ #13);
  MmTraffic.Lines.Add(EdOrders.Text);
  EdOrders.Text:='';
 end;
end;

procedure TMain.Chanserv_Userchan_Managment(NICKNAME:STRING);
  Var J:Integer;
begin
SQL_String := 'SELECT CHAN_ULEVEL.CHANNEL, userreg.Nick, CHAN_ULEVEL.CLVL, CHAN_ULEVEL.Autoinvite, CHAN_ULEVEL.NoAutoOp, '
           + 'CHAN_ULEVEL.NoAutoVoice, CHAN_ULEVEL.Setinfo '
           + 'FROM userreg INNER JOIN '
           + 'CHAN_ULEVEL ON userreg.ID = CHAN_ULEVEL.USERID '
           + 'WHERE (userreg.Nick = ' + '''' + NICKNAME + '''' + ')';

ChanA_CMD_SQL.SQL.Clear;            // Registrierte Channels und deren Access
ChanA_CMD_SQL.SQL.Add(sql_string);  // holen, zum Access dementsprechend Modes vergeben
ChanA_CMD_SQL.Active := true;       // Zusätzlich Setinfo und Autos holen
ChanA_CMD_SQL.Requery();

for J := 1 to ChanA_CMD_DS.DataSet.RecordCount do
  begin
  CMD_CHREG := ChanA_CMD_DS.DataSet.fieldbyname('CHANNEL').AsString;
  CMD_INVITE := ChanA_CMD_DS.DataSet.fieldbyname('Autoinvite').AsString;
  CMD_NOVOICE := ChanA_CMD_DS.DataSet.fieldbyname('NoAutoVoice').AsString;
  CMD_NOOP := ChanA_CMD_DS.DataSet.fieldbyname('NoAutoOp').AsString;
  CMD_CLVL := ChanA_CMD_DS.DataSet.fieldbyname('CLVL').AsInteger;

  if CMD_INVITE = '1' then ClientSocket.Socket.sendtext(':ChanServ INVITE ' + NICKNAME + ' ' + CMD_CHREG +#13);
  if (CMD_CLVL > 199then ClientSocket.Socket.sendtext(':ChanServ MODE ' + CMD_CHREG + ' +o ' + NICKNAME +#13);
  if (CMD_CLVL > 99and (CMD_CLVL < 200then ClientSocket.Socket.sendtext(':ChanServ MODE ' + CMD_CHREG + ' +v ' + NICKNAME +#13);

  ClientSocket.Socket.sendtext(':ChanServ NOTICE ' + NICKNAME + ' :Registriert in: '
                              + CMD_CHREG + ' ' + inttostr(CMD_CLVL) + ' ' + CMD_INVITE +#13);
  ChanA_CMD_DS.DataSet.Next;
  end;
end;

end.


Wie bereits gesagt er ist noch nicht fertig. Bitte kommt mir nicht mit "Nimm doch einen Fertigen" denn die haben alle für mich nicht genug Komfort. Als zweite und sehr kleine Frage wie nennt man das #13 und woher bekomme ich die anderen. Ich weiss was es bedeutet, es macht einen Zeilenumbruch.

Vielleicht könnt ihr mir ja helfen, wie ich den Service Optimieren und verbessern kann. Danke im vorraus :)

Gruss Cyb

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 09.09.05 15:05 
Moin!

Ich muss leider sagen, dass die TClient/ServerSocket-Kompos nicht wirklich leistungsfähig sind. Man kann die Dinger zu didaktischen Zwecken ganz gut benutzen (z.B. im Rahmen des Schulunterrichts oder zum Testen), aber für produktive Systeme sind die einfach zu schlecht... :arrow: Indy-TCP-Server nehmen!

Tja, so ist das Leben... :wink:

Wenn du trotzdem bei TServerSocket bleiben willst, könntest du versuchen, die Daten im OnClientRead an einen ProcessorThread zu übergeben (über eine thread-sichere Liste z.B.) und damit den Hauptthread entlasten. Dann brauchst du aber auch eine thread-sichere Clientverwaltung... :?

Was du mit dynamischen Komponenten in diesem Zusammenhang meinst/bewirken willst, ist mir noch nicht ganz klar; dir vielleicht auch nicht... ? :gruebel:

Viel Spaß noch! :wink:

cu
Narses
Cyberaxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Fr 09.09.05 15:10 
Ganz einfach wenn eine SQL Anweisung 2 mal direkt gebraucht wird und ich sie dynamisch mit nem Array laufen lasse kann man sie ein zweites mal starten oder sehe ich das falsch?

Der nachteil dabei ist das die SQL anweisung verdammt lastig ist.

Die Probleme kommen so gesehen ja nicht von der Socket Komponente. nur ich muss ja jede Nachrricht verarbeiten.

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 09.09.05 15:16 
Moin!

user profile iconCyberaxx hat folgendes geschrieben:
Ganz einfach wenn eine SQL Anweisung 2 mal direkt gebraucht wird und ich sie dynamisch mit nem Array laufen lasse kann man sie ein zweites mal starten oder sehe ich das falsch?

Ehrlich gesagt verstehe ich nicht, was du damit meinst... :gruebel: Willst du mehrere SQL-Query-Kompos gleichzeitig einsetzen oder wie?

user profile iconCyberaxx hat folgendes geschrieben:
Der nachteil dabei ist das die SQL anweisung verdammt lastig ist.

Dann solltest du über Alternativen dazu nachdenken... :wink:

user profile iconCyberaxx hat folgendes geschrieben:
Die Probleme kommen so gesehen ja nicht von der Socket Komponente. nur ich muss ja jede Nachrricht verarbeiten.

Bist du dann hier nicht in der falschen Sparte? :arrow: Datenbanken

cu
Narses
Cyberaxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Fr 09.09.05 15:25 
Ne denke in Datenbanken ist es falsch aufegehoben denn die SQL Anweisungen funktionieren. Ich hatte ja geschrieben ich weiss nicht ob ich hier richtig bin siehe Eröffnungspost.

Wenn jemand 2 mal !Users aufruft und die Procedure noch nicht fertig ist wird das zweite mal das !users übergangen. Ich dachte es so wenn ich die Komponente dynamisch erzeuge, so könnte das zweite !users auch ausgeführt werden, ist ja sogesehen eine neu erzeugte Komponente. Ich weiss auch nicht ob es so gut wäre nun alle Befehle in einen Thread auszulagern da der Hauptthread ja so nix tut...

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 09.09.05 15:36 
Moin!

user profile iconCyberaxx hat folgendes geschrieben:
Ne denke in Datenbanken ist es falsch aufegehoben

Aber du willst doch die Performance der SQL-Anweisungen verbessern, haben wir gerade herausgefunden, oder? Also :arrow: Datenbanken.

user profile iconCyberaxx hat folgendes geschrieben:
Wenn jemand 2 mal !Users aufruft und die Procedure noch nicht fertig ist wird das zweite mal das !users übergangen. Ich dachte es so wenn ich die Komponente dynamisch erzeuge, so könnte das zweite !users auch ausgeführt werden, ist ja sogesehen eine neu erzeugte Komponente. Ich weiss auch nicht ob es so gut wäre nun alle Befehle in einen Thread auszulagern da der Hauptthread ja so nix tut...

Hmm, ich philosophiere mal frei (bin ja nicht komplett im Thema):
- wenn du eine StringListe nimmst und in die Strings die empfangenen Anweisungen packst, in die Objects[] die Socket-Kompo, die diese gesendet hat, dann haste einen "Auftragsliste"
- diese verarbeitet ein Processor-Thread, sequentiell; damit ist dein HauptThread lastfrei und reagiert besser auf die GUI und die SocketKompos (die synchronisieren sich intern nämlich über den MessageLoop des Hauptthreads)
- so gehen keine Anfragen verloren
- Problem: geht natürlich nicht mit TStringList, weil das Ding nicht threadsave ist :arrow: Forschung betreiben

cu
Narses
Cyberaxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Fr 09.09.05 15:49 
Naja ich würde gerne bei den ADOs bleiben die laufen gut sind nur lastig das habe ich ja umgangen das der Service halt weiter läuft. Auch wenn die die Anweisungen verbessern würde löst es nicht das Problem wenn ich im selben zeitraum weitere SQL(die selben) brauche.

BSP:

10:00:12 >> User(a) startet !users im Channel #welcome
11:00:12 >> User(b) startet !users im Channel #test

Dann bekommt die Socket Komponente ja zwei Befehle und versucht im selben Moment zwei mal die Procedure aufzurufen, so wie der Service im moment geschrieben ist. Damit das Programm weiter läuft lässt er ja im Moment die zweite Abfrage weg fallen.

Mir ist jetzt klar hier ist sie vllt. nicht ganz richtig aber warum ausgerechnet bei Datenbanken?
Es läuft ja alles gut so wie es ist vom SQL her.

Das andere was Du angesprochen hast klingt schon um einiges interessanter, ist ja fast nichts anderes als nen Buffer.

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 09.09.05 16:01 
Moin!

user profile iconCyberaxx hat folgendes geschrieben:
aber warum ausgerechnet bei Datenbanken?

Dir laufen die Datenbankprozesse zu langsam/lastig. Ist das kein Datenbank-"Problem"? :wink:

user profile iconCyberaxx hat folgendes geschrieben:
Das andere was Du angesprochen hast klingt schon um einiges interessanter, ist ja fast nichts anderes als nen Buffer.

Ja, klar; wenn Anweisungen verloren gehen, dann muss man sie eben zwischenspeichern. :wink:

cu
Narses
Cyberaxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Fr 09.09.05 16:27 
Ich bin es gewohnt mit den ADOs zu arbeiten lässt sich also so nichts dran ändern. und wie ich bereits gesagt habe auch wenn sie schneller laufen aber vom Server zum selben Zeitpunkt zwei oder mehr nachrichten kommen bringt mir eine beschleunigung der SQL auch nichts. Drum ist es für mich kein Datenbank Problem. Es ght hier nur darum wie ich die empfangen Daten gleichzeitig verarbeite. Dieser Bereich ist nun nicht der richtige aber den Breich Datenbanken halte ich also auch nicht für 100% angebracht.

Wie gesagt das mit dem buffern ist nicht schlecht. Muss mich halt in den Bereich einarbeiten und genau darum habe ich hier den Thread eröffnet um eben mein Projekt zu optimieren.

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
Cyberaxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Mi 14.09.05 15:32 
Habe jetzt einen Thread am laufen. Kann ich im Thread auch die ADO's bzw generell Komponenten benutzen oder muss ich das wieder auf einer anderen 'Form' machen mit Synchronize?

@dit: Frage hat sich erledigt. Hab es jetzt am laufen mit dem Buffer und es scheint auch zu laufen. :)

_________________
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!