# Unicode/umlaute



## Barofioso (22. Jul 2014)

Hallo Java Community

Ich bin bereits seit 5 Tagen dabei am verzweifeln, die unicode zeichen richtig anzeigen zu lassen. Ich meine ich habe beireits alles was unicode angeht durchgelesen und vieles ausprobiert und trotzdem funktioniert nichts. Deshalb muss ich dringends hilfe von überall herholen und hoffe das hier ein profi unterwegs ist der mein problem bereits hatte oder weiss wie mans beheben kann. 

Nun zu meinem Problem:

Ich habe einen Bot für meinen Teamspeak 3 Server geschrieben der über den Query client mit dem Server kommunizieren kann. Dieser sendet jedem neuen User der sich gerade auf den Ts3 server verbindet eine welcome message. Diese enthaltet natürlich umlaute wie (öäü).

Solange ich den Bot über eclipse (launch oder debug modus) starte, werden die Umlaute richtig angezeigt bzw. gesendet.

Wenn ich den Bot nun kompiliere und den dann starte, werden die Umlaute zu einem Schwarzen hintergrund mit einem Fragezeichen. Wobei andere Zeichen wie " ๖ۣۜ " wiederum richtig angezeigt werden.

Ich weiss nicht was ich falsch mache, habe bereits viele tests durchgeführt.

Habe die Dateien alle auf UTF-8 gesetzt. Habe explizit die systemvariablen auf UTF-8 gesetzt. Habe dem compiler gesagt (was dieser sowieso standartmässig tut), dass er im UTF-8 modus kompilieren soll. Nix alles vergebens. Auch andere kodierungen funktionieren nicht.

Ich bin wie gesagt am ende mit meinem Latein. Sowieso, die logik, dass in eclipse alles funktioniert aber nach dem kompilieren nicht, ist ziemlich komisch.

Ich hoffe hier ist jemand der mir ziemlich schnell auf die sprünge helfen kann.


Ich weiss meine Rechtschreibung ist nicht gerade perfekt, also haut nicht darauf rum sondern gebt mir antworten die mir was bringen.

MFG: Barofioso


----------



## Thallius (22. Jul 2014)

Lass mich Raten: du benutzt den StringBuilder um die Texte zu erzeugen?

Gruss

Claus


----------



## Barofioso (22. Jul 2014)

Was ich benutze:


```
char a = 'ä';
char o = 'ö';
char u = 'ü';
api.sendChannelMessage("Umlaute: \u00e4 \u00f6 \u00fc \u00c4 \u00d6 \u00dc \u00df");
api.sendChannelMessage("Umlaute: ä ö ü Ä Ö Ü");
api.sendChannelMessage("Umlaute: " + a + " " + o + " " + u);
api.sendChannelMessage(new String("Umlaute: ä ö ü Ä Ö Ü".getBytes(), Charset.forName("UTF8")));
byte[] m = "Umlaute: ä ö ü Ä Ö Ü".getBytes();
api.sendChannelMessage(m.toString());
api.sendChannelMessage("Umlaute: ä ö ü ß");
```

und nein noch nie gehört vom stringbuilder

sendchannelmessage ist nur eine methode die es mir erlaubt direkt einem channel etwas zu senden. Es wird immer sendTextMessage benutzt egal ob privat channel oder server message!


```
public boolean sendTextMessage(TextMessageTargetMode targetMode,int targetId, String message) {
	final CSendTextMessage msg = new CSendTextMessage(targetMode.getIndex(), targetId, message);
	if (query.doCommand(msg)) {
		return msg.getError().isSuccessful();
	}
	return false;
}
```

die beiden Sockets:

input

```
public class SocketReader extends Thread {

	private final TS3Query ts3;
	private volatile boolean stop;

	public SocketReader(TS3Query ts3) {
		super("SocketReader");
		this.ts3 = ts3;
		try {
			int i = 0;
			while (i < 4 || ts3.getIn().ready()) {
				TS3Query.log.info("< " + ts3.getIn().readLine());
				i++;
			}
		} catch (final IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		while (ts3.getSocket() != null && ts3.getSocket().isConnected()
				&& ts3.getIn() != null && !stop) {
			try {
				if (ts3.getIn().ready()) {
					final String line = ts3.getIn().readLine();
					if (!line.isEmpty()) {
						final Command c = ts3.getCommandList().peek();
						if (line.startsWith("notify")) {
							TS3Query.log.info("< [event] " + line);
							new Thread(new Runnable() {

								public void run() {
									final String arr[] = line.split(" ", 2);
									ts3.getEventManager().fireEvent(arr[0],
											arr[1]);

								}
							}).start();

						} else if (c != null && c.isSent()) {
							TS3Query.log
									.info("[" + c.getName() + "] < " + line);
							if (line.startsWith("error")) {
								c.feedError(line.substring("error ".length()));
								if (c.getError().getId() != 0) {
									TS3Query.log.severe("[ERROR] "
											+ c.getError());
								}
								c.setAnswered();
								ts3.getCommandList().remove(c);
							} else if (!line.isEmpty()) {
								c.feed(line);
							}
						} else {
							TS3Query.log.info("< " + line);
						}
					}
				}
			} catch (final IOException e) {
				e.printStackTrace();
			}
			try {
				Thread.sleep(50);
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
		}
		TS3Query.log.warning("SocketReader has stopped!");
	}

	public void finish() {
		stop = true;
	}

}
```

output

```
public class SocketWriter extends Thread {
	private final TS3Query ts3;
	private int floodRate;
	private long lastCommand = System.currentTimeMillis();
	private volatile boolean stop;

	public SocketWriter(TS3Query ts3, int floodRate) {
		super("SocketWriter");
		this.ts3 = ts3;
		if (floodRate > 50) {
			this.floodRate = floodRate;
		} else {
			this.floodRate = 50;
		}
	}

	public void run() {
		while (ts3.getSocket() != null && ts3.getSocket().isConnected()
				&& ts3.getOut() != null && !stop) {
			final Command c = ts3.getCommandList().peek();
			if (c != null && !c.isSent()) {
				final String msg = c.toString();
				TS3Query.log.info("> " + msg);
				ts3.getOut().println(msg);
				lastCommand = System.currentTimeMillis();
				c.setSent();
			}
			try {
				Thread.sleep(floodRate);
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
		}

		TS3Query.log.warning("SocketWriter has stopped!");
	}

	public long getIdleTime() {
		return System.currentTimeMillis() - lastCommand;
	}

	public void finish() {
		stop = true;
	}
}
```

und die Query klasse

```
public class TS3Query {

	private Socket socket;
	private PrintWriter out;
	private BufferedReader in;
	private SocketReader socketReader;
	private SocketWriter socketWriter;
	private KeepAliveThread keepAlive;

	private ConcurrentLinkedQueue<Command> commandList = new ConcurrentLinkedQueue<>();
	private final EventManager eventManager = new EventManager();

	private TS3Api api;
	private final TS3Config config;

	public static final Logger log = Logger.getLogger(TS3Query.class.getName());

	public enum FloodRate {
		DEFAULT(350),
		UNLIMITED(0);

		private int ms;

		FloodRate(int ms) {
			this.ms = ms;
		}

		public int getMs() {
			return ms;
		}
	}

	public TS3Query(TS3Config config) {
		log.setUseParentHandlers(false);
		log.addHandler(new LogHandler(config.getDebugToFile()));
		log.setLevel(config.getDebugLevel());
		this.config = config;
	}

	public TS3Query connect() {
		// exit();
		try {
			socket = new Socket(config.getHost(), config.getQueryPort());
			if (socket.isConnected()) {
				out = new PrintWriter(socket.getOutputStream(), true);
				in = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				socketReader = new SocketReader(this);
				socketReader.start();
				socketWriter = new SocketWriter(this, config.getFloodRate()
						.getMs());
				socketWriter.start();
				keepAlive = new KeepAliveThread(this, socketWriter);
				keepAlive.start();
			}

		} catch (final IOException e) {
			throw new TS3ConnectionFailedException(e);
		}

		// Executing config object
		final TS3Api api = getApi();
		if (config.getUsername() != null && config.getPassword() != null) {
			api.login(config.getUsername(), config.getPassword());
		}
		return this;
	}

	public Socket getSocket() {
		return socket;
	}

	public PrintWriter getOut() {
		return out;
	}

	public BufferedReader getIn() {
		return in;
	}

	public boolean doCommand(Command c) {
		commandList.offer(c);
		final long start = System.currentTimeMillis();
		while (!c.isAnswered() && System.currentTimeMillis() - start < 4_000) {
			try {
				Thread.sleep(50);
			} catch (final InterruptedException e) {
				throw new TS3CommandFailedException(e);
			}
		}
		if (!c.isAnswered()) {
			log.severe(("Command " + c.getName() + " is not answered in time."));
			commandList.remove(c);
			return false;
		}
		return true;
	}

	public void doCommandAsync(final Command c) {
		doCommandAsync(c, null);
	}

	public void doCommandAsync(final Command c, final Callback callback) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				doCommand(c);
				if (callback != null) {
					callback.handle();
				}
			}
		}).start();
	}

	/**
	 * Removes and closes all used resources to the teamspeak server.
	 */
	public void exit() {
		if (out != null) {
			out.close();
		}
		if (in != null) {
			try {
				in.close();
			} catch (final IOException ignored) {
			}
		}
		if (socket != null) {
			try {
				socket.close();
			} catch (final IOException ignored) {
			}
		}
		try {
			if (socketReader != null) {
				socketReader.finish();
				socketReader.join();
			}
			if (socketWriter != null) {
				socketWriter.finish();
				socketWriter.join();
			}
			if (keepAlive != null) {
				keepAlive.finish();
				keepAlive.join();
			}
		} catch (final InterruptedException e) {
			e.printStackTrace();
		}

		commandList.clear();
		commandList = null;
		for (final Handler lh : log.getHandlers()) {
			log.removeHandler(lh);
		}
	}

	public ConcurrentLinkedQueue<Command> getCommandList() {
		return commandList;
	}

	public EventManager getEventManager() {
		return eventManager;
	}

	public TS3Api getApi() {
		if (api == null) {
			api = new TS3Api(this);
		}
		return api;
	}

}
```


----------



## Barofioso (22. Jul 2014)

Ich habe soeben erfahren dass alle String in UTF16 gespeichert werden. Dies ist tödlich für jede Telnetanwendung. Und somit ist mir nun auch klar wieso dies nicht geklappt hatte!

Ich muss nun extra 2 methoden erstellen die mir alle zeichen die mit utf16 erhalten werden zu utf8 konvertieren. und dies is eine gewaltige arbeit ...

Gibbets hier nicht einfach eine einfach möglichkeit dem kompiler bzw der runnable jar zu sagen er solle dies in UTF8 starten bzw benutzen?


----------

