import java.awt.*; import java.lang.*; import java.net.*; import java.io.*; import java.util.*; import sfi; public class Network implements Runnable { public static final short OFFLINE = 0; public static final short UNAUTH = 1; public static final short AUTH = 2; private short state = AUTH; private short TTL = 0; private sfi comp; private String message; private DataInputStream in; private DataOutputStream out; private Socket soc; private Thread runner; private int averageBytesPerSec = 0; private int BytesRec = 0; private int packets = 0; public Font font = new Font("Helvetica", Font.PLAIN, 12); FontMetrics fontSize; Network(int port, sfi c) { comp = c; fontSize = comp.getFontMetrics(font); try { soc = new Socket (comp.getParameter("server"), port); in = new DataInputStream(new BufferedInputStream(soc.getInputStream())); out = new DataOutputStream(new BufferedOutputStream(soc.getOutputStream())); message = "Login"; } catch (IOException ex) { error(ex.getMessage()); } try { out.writeUTF("@login|" + comp.getParameter("id") + "`" + comp.getParameter("password") + "`" + comp.getParameter("gameid")); out.flush(); state = AUTH; } catch (IOException ex) { error(ex.getMessage()); } start(); } public boolean online() { return (state == AUTH); } public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } } public void run() { while(true) { try { if (state == AUTH) handle(in.readUTF()); } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } } public void paint(Graphics g) { if (averageBytesPerSec < 1500) g.setColor(Color.green); else if (averageBytesPerSec < 2200) g.setColor(Color.yellow); else if (averageBytesPerSec < 2800) g.setColor(Color.orange); else if (averageBytesPerSec >= 2800) g.setColor(Color.red); g.setFont(font); g.drawString("n:" + (averageBytesPerSec), 435 - fontSize.stringWidth("n:" + (averageBytesPerSec*2)/2), 388); } private void handle(String msg) { // System.out.println("Got: " + msg); BytesRec += msg.length() + 5; StringTokenizer Token = new StringTokenizer(msg, "|", false); if (Token.nextToken().compareTo("@") == 0) handleCommand(Token.nextToken(), Token.nextToken()); else handleGameData(Token.nextToken(), Token.nextToken()); } private void handleCommand(String cmd, String data) { if (cmd.compareTo("join") == 0 && comp.checkState(comp.PLAY)) addNewUser(data); else if (cmd.compareTo("part") == 0 && comp.checkState(comp.PLAY)) comp.game.removeUser(data); else if (cmd.compareTo("who") == 0) procWho(data); else if (cmd.compareTo("chanjoin") == 0 && comp.checkState(comp.WAIT)) comp.init_startGame(); else if (cmd.compareTo("list") == 0) { StringTokenizer Token = new StringTokenizer(data, "`", false); comp.addList(toInt(Token.nextToken()), Token.nextToken(), Token.nextToken(), toInt(Token.nextToken())); } else if (cmd.compareTo("login") == 0) comp.enterChat(); else if (cmd.compareTo("ERROR") == 0) error(data); else if (cmd.compareTo("logout") == 0) error(data); else System.err.println("[Network] Command <" + cmd + "> unknown"); } private void handleGameData(String who, String data) { try { StringTokenizer Token = new StringTokenizer(data, "`", false); String type = Token.nextToken(); if (type.compareTo("k") == 0) comp.game.update_Keys(toInt(who), Token.nextToken()); else if (type.compareTo("f") == 0) comp.game.update_Full(toInt(who), toInt(Token.nextToken()), toInt(Token.nextToken()), toDouble(Token.nextToken()), toInt(Token.nextToken()), toDouble(Token.nextToken()), toInt(Token.nextToken()) ); else if (type.compareTo("d") == 0) comp.game.hurtPlayer(toInt(Token.nextToken()), toInt(Token.nextToken())); else if (type.compareTo("c") == 0) comp.addMessage(Token.nextToken() + " - " + Token.nextToken()); else if (type.compareTo("p") == 0) comp.game.map.putPowerUp(toInt(Token.nextToken()), toInt(Token.nextToken()), toInt(Token.nextToken()), toInt(Token.nextToken()), toDouble(Token.nextToken()), toInt(Token.nextToken()) ); else if (type.compareTo("b") == 0 && comp.bar != null) comp.bar.addMessage(who + " - " + Token.nextToken()); else System.err.println("[Network] Data <" + data + "> unknown"); } catch (NoSuchElementException ex) { System.out.println("[Network] ERROR: \"" + data + "\" was bad."); ex.printStackTrace(); } } public void error(String msg) { message = msg; comp.showStatus("Network Error: " + msg); try { soc.close(); } catch (IOException ex) { ex.printStackTrace(); } state = OFFLINE; } public void sendPackateData() { if (state == AUTH && comp.game.me.isAlive() && TTL-- == 0) { try { out.writeUTF(comp.game.me.getPacket()); out.flush(); BytesRec += comp.game.me.getPacket().length() + 5; TTL = 8; int total = averageBytesPerSec * packets; averageBytesPerSec = (total + BytesRec)/++packets; BytesRec = 0; if (packets > 150) packets = 50; } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } } public void sendKeyUpdate() { try { out.writeUTF(comp.game.me.getKeyPacket()); out.flush(); BytesRec += comp.game.me.getKeyPacket().length() + 5; } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } public void sendDamageUpdate(int id, int damage) { try { out.writeUTF("#d`" + id + "`" + damage); out.flush(); BytesRec += 17; } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } public void sendChatMessage(String name, String msg) { try { out.writeUTF("#c`" + name + "`" + msg); out.flush(); BytesRec += (7 + name.length() + msg.length()); } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } public void sendPowerUp(int i, int type, int x, int y, double angle, int vel) { try { out.writeUTF("#p`" + i + "`" + type + "`" + x + "`" + y + "`" + angle + "`" + vel); out.flush(); BytesRec += 18; } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } public void sendMessage(String data) { try { out.writeUTF(data); out.flush(); BytesRec += data.length(); } catch (IOException ex) { error(ex.getMessage()); ex.printStackTrace(); } } private void addNewUser(String data) { StringTokenizer Token = new StringTokenizer(data, "`", false); comp.game.addUser(Token.nextToken(), toInt(Token.nextToken()), Token.nextToken()); } private void procWho(String data) { if (data.compareTo("null") != 0 && comp.checkState(comp.PLAY)) { StringTokenizer Token = new StringTokenizer(data, ",", false); while (Token.hasMoreTokens()) addNewUser(Token.nextToken()); } } private int toInt(String s) { Integer i = new Integer(s); return i.intValue(); } private double toDouble(String s) { Double d = new Double(s); return d.doubleValue(); } }