001package com.github.theholywaffle.teamspeak3; 002 003/* 004 * #%L 005 * TeamSpeak 3 Java API 006 * %% 007 * Copyright (C) 2014 Bert De Geyter 008 * %% 009 * Permission is hereby granted, free of charge, to any person obtaining a copy 010 * of this software and associated documentation files (the "Software"), to deal 011 * in the Software without restriction, including without limitation the rights 012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 013 * copies of the Software, and to permit persons to whom the Software is 014 * furnished to do so, subject to the following conditions: 015 * 016 * The above copyright notice and this permission notice shall be included in 017 * all copies or substantial portions of the Software. 018 * 019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 025 * THE SOFTWARE. 026 * #L% 027 */ 028 029import com.github.theholywaffle.teamspeak3.commands.Command; 030import com.github.theholywaffle.teamspeak3.commands.response.ResponseBuilder; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034import java.io.IOException; 035import java.io.PrintStream; 036import java.util.concurrent.BlockingQueue; 037 038public class SocketWriter extends Thread { 039 040 private static final Logger log = LoggerFactory.getLogger(SocketWriter.class); 041 042 private final BlockingQueue<Command> sendQueue; 043 private final BlockingQueue<ResponseBuilder> receiveQueue; 044 private final int floodRate; 045 private final boolean logComms; 046 private final PrintStream out; 047 private volatile long lastCommand = System.currentTimeMillis(); 048 049 public SocketWriter(QueryIO io, TS3Config config) throws IOException { 050 super("[TeamSpeak-3-Java-API] SocketWriter"); 051 this.sendQueue = io.getSendQueue(); 052 this.receiveQueue = io.getReceiveQueue(); 053 this.floodRate = config.getFloodRate().getMs(); 054 this.logComms = config.getEnableCommunicationsLogging(); 055 this.out = new PrintStream(io.getSocket().getOutputStream(), true, "UTF-8"); 056 } 057 058 @Override 059 public void run() { 060 try { 061 // Initial sleep to prevent flood ban shortly after connecting 062 if (floodRate > 0) Thread.sleep(floodRate); 063 064 while (!isInterrupted()) { 065 final Command c = sendQueue.take(); 066 final String msg = c.toString(); 067 068 receiveQueue.put(new ResponseBuilder(c)); 069 if (logComms) log.debug("[{}] > {}", c.getName(), msg); 070 out.println(msg); 071 072 lastCommand = System.currentTimeMillis(); 073 if (floodRate > 0) Thread.sleep(floodRate); 074 } 075 } catch (final InterruptedException e) { 076 // Regular shutdown 077 interrupt(); 078 } 079 080 out.close(); 081 082 if (!isInterrupted()) { 083 log.warn("SocketWriter has stopped!"); 084 } 085 } 086 087 long getIdleTime() { 088 return System.currentTimeMillis() - lastCommand; 089 } 090}