Teamspeak3 Viewer

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Bisonte
Beiträge: 2470
Registriert: 01.04.2007 20:18

Teamspeak3 Viewer

Beitrag von Bisonte »

Hallo...

Hier hab ich mit meinem bescheidenen Wissen, eine kleine Include gebastelt,
um Daten von einem Teamspeak 3 Server zu holen. (Channelliste und Clientliste)

Wenn man weitere Befehle braucht, kann man diese einfach dazuschustern...

Sicherlich nicht perfekt, daher sind Verbesserungsvorschläge gern gesehen ;)

Hier kommt der Source

Code: Alles auswählen

EnableExplicit
Structure teamspeak3_online_clients
  clid.i
  cid.i
  client_database_id.i
  client_nickname.s
  client_type.i  
EndStructure
Structure teamspeak3_channels
  cid.i
  pid.i
  channel_order.i
  channel_name.s
  channel_topic.s
  total_clients.i
  channel_needed_subscribe_power.i  
EndStructure
Global TS3_Error.i
Procedure.i TS3_CloseConnection(Connection.i)
  If Connection
    SendNetworkString(Connection,"quit"+#CRLF$)
    CloseNetworkConnection(Connection)
  EndIf
EndProcedure
Procedure.s TS3_ReceiveAnswerString(ConnectionID.i, AnswerTimeOut.i = 1000)
  If ConnectionID
    Protected *Buffer = AllocateMemory(65000)
    Protected String.s = "", In.i, CEvent.i, Quit.i
    Protected TimerStop.i  = ElapsedMilliseconds() + AnswerTimeOut
    TS3_Error = 0
    If *Buffer
      Repeat 
        CEvent = NetworkClientEvent(ConnectionID)
        If ElapsedMilliseconds() >= TimerStop
          TS3_Error = 1
          Break  
        EndIf
        If CEvent = #PB_NetworkEvent_Data
          TS3_Error = 0
          Break
        EndIf
      ForEver
      If TS3_Error = 0
        Repeat
          In = ReceiveNetworkData(ConnectionID,*Buffer,65000)
          String = String + PeekS(*Buffer)
        Until In>-1 And In<65000
      Else
        TS3_CloseConnection(ConnectionID)
      EndIf
      FreeMemory(*Buffer)
    EndIf    
  EndIf
  ProcedureReturn String  
EndProcedure
Procedure.s TS3_GetDNS(NameIP.s = "")
  Protected TheIPAddress.s, pHostinfo, AdressNumber, ipAddress, Url.s
  Protected hostinfo.HOSTENT
  URL.s = GetURLPart(NameIP,#PB_URL_Site)
  If Url = "" : Url = NameIP : EndIf
  pHostinfo = gethostbyname_(Url) 
  If pHostinfo = 0
    TheIPAddress = "Unable to resolve domain name" 
  Else 
    CopyMemory (pHostinfo, hostinfo.HOSTENT, SizeOf(HOSTENT)) 
    If hostinfo\h_addrtype <> #AF_INET   
      TheIPAddress = "A non-IP address was returned."   
    Else 
      While PeekL(hostinfo\h_addr_list+AdressNumber*4) 
        ipAddress = PeekL(hostinfo\h_addr_list+AdressNumber*4)  
        TheIPAddress = StrU(PeekB(ipAddress),0)+"."+StrU(PeekB(ipAddress+1),0)+"."+StrU(PeekB(ipAddress+2),0)+"."+StrU(PeekB(ipAddress+3),0)
        AdressNumber+1 
      Wend 
    EndIf 
  EndIf 
  ProcedureReturn TheIPAddress
EndProcedure
Procedure.i TS3_Establish_Connection(ServerAdress.s, ServerQueryPort.i = 10011, ServerPort.i = 9987, AnswerTimeOut.i = 1000)
  Protected DNS.s = TS3_GetDNS(ServerAdress.s)
  Protected Connection.i, String.s, PortString.s = "use port="+Str(ServerPort)
  Connection = OpenNetworkConnection(DNS, ServerQueryPort, #PB_Network_TCP)
  If Connection
    String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
    If Left(LCase(String),3) <> "ts3"
      CloseNetworkConnection(Connection)
      Connection = 0
    Else
      String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
      SendNetworkString(Connection, PortString+#CRLF$)
      String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
      If FindString(LCase(String),"error id=0",1) = 0
        TS3_CloseConnection(Connection)
        Connection = 0
      EndIf
    EndIf
  EndIf
  ProcedureReturn Connection    
EndProcedure
Procedure.i TS3_GetChannelList(Connection, List Channels.teamspeak3_channels(), AnswerTimeOut.i = 1000)
  Protected String.s, Start.i, ChannelCount.i, i.i, x.s
  ClearList(Channels())
  If Connection
    SendNetworkString(Connection, "channellist -topic"+#CRLF$)
    String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
    If TS3_Error = 0
      If FindString(String,"error id=0 msg=ok",1)
        String = RemoveString(String,"error id=0 msg=ok",0,1,1)
      EndIf      
      ChannelCount = CountString(String,"|")
      If ChannelCount
        For i=1 To ChannelCount + 1
          x = StringField(String,i,"|")
          AddElement(Channels())
          With Channels()
            \cid                            = Val(StringField(StringField(x,1," "),2,"="))  
            \pid                            = Val(StringField(StringField(x,2," "),2,"="))  
            \channel_order                  = Val(StringField(StringField(x,3," "),2,"="))  
            \channel_name                   = ReplaceString(StringField(StringField(x,4," "),2,"="),"\s"," ")
            \channel_topic                  = ReplaceString(StringField(StringField(x,5," "),2,"="),"\s"," ")
            \total_clients                  = Val(StringField(StringField(x,6," "),2,"="))  
            \channel_needed_subscribe_power = Val(StringField(StringField(x,7," "),2,"="))  
          EndWith
        Next i
      EndIf
      ;##### Errorcode abholen
      String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
    EndIf
  EndIf
EndProcedure
Procedure.i TS3_GetClientList(Connection, List Clients.teamspeak3_online_clients(), AnswerTimeOut.i = 1000)
  Protected String.s, ClientCount.i = 0, i.i, x.s, clienttype.i
  ClearList(Clients())
  If Connection
    SendNetworkString(Connection, "clientlist"+#CRLF$)
    String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)  
    If TS3_Error = 0
      If FindString(String,"error id=0 msg=ok",1)
        String = RemoveString(String,"error id=0 msg=ok",0,1,1)
      EndIf
      ClientCount = CountString(String,"|")
      For i=1 To ClientCount + 1
        x = StringField(String,i,"|")
        clienttype = Val(StringField(StringField(x,5," "),2,"="))  
        If clienttype = 0
          AddElement(Clients())
          With Clients()
            \clid               = Val(StringField(StringField(x,1," "),2,"="))  
            \cid                = Val(StringField(StringField(x,2," "),2,"="))  
            \client_database_id = Val(StringField(StringField(x,3," "),2,"="))  
            \client_nickname    = ReplaceString(StringField(StringField(x,4," "),2,"="),"\s"," ")
            \client_type        = Val(StringField(StringField(x,5," "),2,"="))  
          EndWith
        EndIf
      Next i
      ;##### Errorcode abholen
      String = TS3_ReceiveAnswerString(Connection, AnswerTimeOut)
    EndIf
    ProcedureReturn ClientCount
  EndIf  
EndProcedure

;##### Beispiel 

Procedure.i TS3_Viewer(List Channels.teamspeak3_channels(), List Clients.teamspeak3_online_clients(), ServerAdress.s, ServerPort.i = 9987, ServerQueryPort.i = 10011, AnswerTimeOut.i = 1000)
  Protected Connection.i, ClientCount.i 
  Connection = TS3_Establish_Connection(ServerAdress,ServerQueryPort,ServerPort,AnswerTimeOut)
  If Connection
    TS3_GetChannelList(Connection, Channels())
    ClientCount = TS3_GetClientList(Connection, Clients())
    TS3_CloseConnection(Connection)
  Else
    ProcedureReturn 0
  EndIf
  ProcedureReturn ClientCount  
EndProcedure

InitNetwork()

NewList Channels.teamspeak3_channels()
NewList User.teamspeak3_online_clients()
Define AA 
aa = TS3_Viewer(Channels(),User(),"IP Adresse des TS3 Servers")

ForEach Channels()
  Debug Channels()\channel_name
  If Channels()\total_clients>0
    ForEach User()
      If User()\cid = Channels()\cid
        Debug "  " + User()\client_nickname
      EndIf
    Next 
  EndIf
Next
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​