TheHolyWaffle / TeamSpeak-3-Java-API

A Java wrapper of TeamSpeak's 3 server query API.
MIT License
306 stars 107 forks source link

Tutorial? :) #100

Closed SquadScope closed 7 years ago

SquadScope commented 8 years ago

Hey all,

I'm pretty new in Java-coding, could someone give a short tutorial about how to use, how to build in the api? I really like the idea of the api, but I still have no idea how to use it :(

Thanks! SquadScope

TheMolkaPL commented 8 years ago

Here you go!

SquadScope commented 8 years ago

Thanks man! :+1: :)

2 small questions left:

  1. Is the API able to listen to every channel at the same time or is there a way to listen to the global chat?
  2. What's the command to get invokers uid? - I couldn't find it in the documentation and it's not used in the examples :( - I tried some commands, but never found the right one :(
TheMolkaPL commented 8 years ago

No you can't listen to every channel - #92. You can listen to the global chat using the following:

TS3Config config = new TS3Config();
config.setHost("localhost");
config.setDebugLevel(Level.ALL);

TS3Query query = new TS3Query(config);
query.connect();

TS3Api ts = query.getApi();
ts.registerEvent(TS3EventType.TEXT_SERVER);
ts.addTS3Listener(new TS3EventAdapter() {
        @Override
        public void onTextMessage(TextMessageEvent e) {
            // your code...
        }
});
SquadScope commented 8 years ago

Thanks man! :+1: :)

And how to get the invokers uid? :) I'm trying to add an adminlist (!kill for example) and just some guys should be able to use this commands. :)

TheMolkaPL commented 8 years ago

You should be able to use this method.

SquadScope commented 8 years ago

Thanks man! :+1: :)

Here is my code:

Why the program does not execute "fortune|cowsay" ?

`/*

import com.github.theholywaffle.teamspeak3.TS3Api; import com.github.theholywaffle.teamspeak3.TS3Config; import com.github.theholywaffle.teamspeak3.TS3Query; import com.github.theholywaffle.teamspeak3.api.TextMessageTargetMode; import com.github.theholywaffle.teamspeak3.api.event.TS3EventAdapter; import com.github.theholywaffle.teamspeak3.api.event.TS3EventType; import com.github.theholywaffle.teamspeak3.api.event.TextMessageEvent;

import java.util.logging.Level; import java.io.*;

/**

SquadScope commented 8 years ago

OK, Cowsay works now! :D 1 more question, how can I get the invokers Channel-Id?

rogermb commented 8 years ago

You can't get that directly. You can, however, do api.getClientInfo(invokerClientId) and then take the channel ID from there.

SquadScope commented 8 years ago

cannot find symbol - variable invokerClientId :(

I'm trying to code the game "secret hitler" for teamspeak, some clients often plays this game at my teamspeak and they asked me to code something for them because it's hard to play a card game on teamspeak :( and you need some chat commands to join the party, to start the game and so on...

Is there a way to get client Nickname by Id? :-)

rogermb commented 8 years ago

Yeah, I just wrote invokerClientId and expected you to "fill in the blanks", so to say.

You have an event with an invoker, so you can get the client ID of the invoker from the event. The name should be so straight-forward that I'll let you figure it out.

SquadScope commented 8 years ago

Okay, thanks man! :+1: :-)

What's wrong?

CClientGetDBIdFromUId getDBId = new CClientGetDBIdFromUId(e.getInvokerUniqueId()); String cldbidString = getDBId.getResponse().toString(); System.out.println(cldbidString); I tried Thread.sleep() between sending the command and getting the response, but that doesn't work too, than I tried while(getDBId.isSent()==false) with Thread.sleep() in it.

The the program doesn't leave while... Why? :o

rogermb commented 8 years ago

You should never use commands (e.g. classes that start with C, everything in the commands package) directly in your code. The reason you're not getting a response is because these commands don't send themselves. You should let the API handle all the command sending for you.

Use the methods in the TS3Api class instead.

TS3Api api = ....;

String uid = e.getInvokerUniqueId();
DatabaseClientInfo client = api.getDatabaseClientByUId(uid);
int databaseId = client.getDatabaseId();
SquadScope commented 8 years ago

Okay! Thanks man! :+1:

MoralCode commented 8 years ago

another question, is it possible to connect to an external channel (i.e. an actual live teamspeak server (I'm trying with ts.meepcraft.com)). I can connect to through my actual TS client, but not through my mod...

my code (in main method):

    System.out.println("1");
    final TS3Config config = new TS3Config();
    config.setHost("ts.meepcraft.com");//the minecraft server im using for testing
    config.setDebugLevel(Level.ALL);
    System.out.println("2");
    final TS3Query query = new TS3Query(config);
    System.out.println("2.5");
    try {
        query.connect();
        System.out.println("3");
        final TS3Api api = query.getApi();
        api.login("test_bot", "");
        api.selectVirtualServerById(1);
        api.setNickname("Test_Bot");
        api.sendChannelMessage("Test Bot is online!");
        System.out.println("4");
        query.exit();
    } catch (TS3ConnectionFailedException e) {
        System.out.println("Error Connecting");
        e.printStackTrace();

    }

do you have any idea whats going on?

SquadScope commented 8 years ago

I think it's not possible to connect to servers using the domain, you need to connect using the ip! ;D Ping the domain to get IP, when the IP changes often, add this to your code: try{ InetAddress inetAddress = java.net.InetAddress.getByName(ts.meepcraft.com); String ip = inetAddress.getHostAddress(); }catch(Exception e1){ System.out.println("ERROR!! DNS-Resolve not possible!"); try{ Thread.sleep(1500); } catch(Exception e2){ System.out.println("ERROR!! Something went wrong!!"); } }

Sorry becauseof my catches, but I'm new to Java and I don't really know how to deal with them. :)

I hope I could help you, SquadScope

P.S.: Sorry, I don't know how to use the editor or it's bugging at the moment, I copied out of my code, it's indented in mine. :o

rogermb commented 8 years ago

@SquadScope That's not true, you can use domain names without any problems.

I tested it by using ts.meepcraft.com as the host name and was able to connect without any issues. It might take just a little bit longer to connect because there first needs to be a DNS lookup, but it's still generally preferable to use the domain instead of the raw IP address.

MoralCode commented 8 years ago

I think its an issue with the query login info. Its not my ts server and I'm trying to find a way to connect without using a query login...

SquadScope commented 8 years ago

@Firedroide Oh, Okay is it a new feature? Because I wanted to connect to my ts server using the domain two month ago and it still doesn't work..

But another question: It is possible to check if a client is a query client? Because I wrote a bot which greets everybody connecting to the server and always when I connect using putty for example, I get error messages [SEVERE] TS3 command error: {msg=invalid clientID, id=512}

rogermb commented 8 years ago

@DeveloperACE You can also generate your own login, you don't have to use serveradmin.

Generate TS3 ServerQuery Login

@SquadScope We haven't changed anything, this should've been working from day 1. We just use simple Java Sockets to establish the connection, and these always do domain name resolution.

Maybe you had the wrong port or something else was preventing the connection?

Other question: Client#isRegularClient and Client#isServerQueryClient.

SquadScope commented 8 years ago

@Firedroide Okay, thank you! :)

Another question: ClientLeaveEvent e e.getInvokerUniqueId();

Return an empty String, how do I get the UId on client leave?

rogermb commented 8 years ago

This has been asked and answered so many times already, I should really create an FAQ.

Alternatively, you could always just use the search function, though 😛

SquadScope commented 8 years ago

I'm sorry man, but I think the linked threads are about the nickname and not about uids :D

I searched for it before, but just found threads about nick! :o

I tried to use the results of your linked threads to create the following, but it doesn't work too: DatabaseClientInfo client = api.getDatabaseClientByUId(methods.getUIdByName(clientInfo.getLoginName(), api));

methods.getUIdByName(clientInfo.getLoginName(), api) returns the UniqueId by inserting the nickname :D

Thanks!

rogermb commented 8 years ago

Invoker = a different client that caused this event to happen.

Quoting from the first link:

ClientLeaveEvent seems to be the only event for which the TS server does not send us any information about the client who actually left. A typical notifyclientleftview notify message looks like this:

notifyclientleftview cfid=1 ctid=0 reasonid=8 reasonmsg=Disconnect clid=5

As you can see, there's no invokername or anything like that in there, [because no other client caused this event to happen]. So basically it's this: We cannot give you information we don't have ^^

Replace invokername with invokeruid, because they both describe the invoker and are both absent in notifyclientleftview. Further:

If you need more detailed information about your clients when they leave, you currently have to set up some kind of client registry. Basically you'd create a HashMap mapping the clients' IDs to their data. Then, when a client leaves, you could use their client ID to look up their last known nickname.

And as to why getClientInfo won't work after a client has left:

no, because the client has already left the server and so getClientInfo won't find any info. - TheHolyWaffle

If you need information about a client when they leave, you have to store it before the client actually leaves. The only information TS3 provides you about the client who left is their client ID, meaning you'll have to store your information with the client ID as the key.

xdev-pl commented 7 years ago

@rogermb "If you need information about a client when they leave, you have to store it before the client actually leaves" i have already stored it. Now i have problem, how to check if the client is online, because i have to remove him from List, any idea?

rogermb commented 7 years ago

If you know the client's UId, you could call TS3Api#getClientByUId(String). This method will return null if the client is not online.

Now i have problem, how to check if the client is online, because i have to remove him from List

Why don't you just remove the client from your data store when they leave?

Apart from that, why are you using a List and not something like a Map<Integer, Client> that maps the client's (session) ID to their Client or ClientInfo object?

xdev-pl commented 7 years ago

Lol, its still not working.

for(TeamSpeakUser cl : clients){ if(bot.getApi().getClientByUId(cl.getUniqueIdentifier()) == null){ bot.getApi().sendChannelMessage("Trying to Unregister: " + cl.getUniqueIdentifier() + "/" + cl.getNick());

rogermb commented 7 years ago

So what exactly is it that isn't working?

Can you provide a stack trace of any errors you're getting? And that class TeamSpeakUser, that's also not from our API. Could it be that that class is causing your issue?

xdev-pl commented 7 years ago

I need TeamSpeakUser class because i store there many things for example if someone is goes afk im storing his old channelId moving him, and when he's back i can move him to the old channel.

Im not getting any errors ;f

rogermb commented 7 years ago

Im not getting any errors ;f

Then do you see the clientgetids command in the console / your log file? If not, the code snippet you've sent isn't even being executed.

xdev-pl commented 7 years ago

Nvm, now it works :)