📄 client.java
字号:
/* * MegaMek - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */package megamek.client;import java.io.File;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.ObjectOutputStream;import java.util.Enumeration;import java.util.Vector;import java.util.Hashtable;import megamek.client.bot.BotClient;import megamek.common.*;import megamek.common.actions.AttackAction;import megamek.common.actions.ClubAttackAction;import megamek.common.actions.DodgeAction;import megamek.common.actions.EntityAction;import megamek.common.actions.FlipArmsAction;import megamek.common.actions.LayMinefieldAction;import megamek.common.actions.TorsoTwistAction;import megamek.common.event.GameEntityChangeEvent;import megamek.common.event.GameMapQueryEvent;import megamek.common.event.GamePlayerChatEvent;import megamek.common.event.GamePlayerDisconnectedEvent;import megamek.common.event.GameReportEvent;import megamek.common.event.GameSettingsChangeEvent;import megamek.common.net.Connection;import megamek.common.net.ConnectionFactory;import megamek.common.net.ConnectionListenerAdapter;import megamek.common.net.DisconnectedEvent;import megamek.common.net.Packet;import megamek.common.net.PacketReceivedEvent;import megamek.common.options.GameOptions;import megamek.common.preference.PreferenceManager;import megamek.common.util.StringUtil;public class Client { // we need these to communicate with the server private String name; private Connection connection; // some info about us and the server private boolean connected = false; public int local_pn = -1; private String host; private int port; // the game state object public IGame game = new Game(); // here's some game phase stuff private MapSettings mapSettings; public String phaseReport; public String roundReport; //And close client events! private Vector closeClientListeners = new Vector(); // we might want to keep a game log... private GameLog log; private boolean disconnectFlag = false; private Hashtable duplicateNameHash = new Hashtable(); private ConnectionListenerAdapter connectionListener = new ConnectionListenerAdapter() { /** * Called when it is sensed that a connection has terminated. */ public void disconnected(DisconnectedEvent e) { Client.this.disconnected(); } public void packetReceived(PacketReceivedEvent e) { handlePacket(e.getPacket()); } }; /** * Construct a client which will try to connect. If the connection * fails, it will alert the player, free resources and hide the frame. * * @param name the player name for this client * @param host the hostname * @param port the host port */ public Client(String name, String host, int port) { // construct new client this.name = name; this.host = host; this.port = port; } /** * Attempt to connect to the specified host */ public boolean connect() { connection = ConnectionFactory.getInstance().createClientConnection(host, port, 1); boolean result = connection.open(); if (result) { connection.addConnectionListener(connectionListener); } return result; } /** * Shuts down threads and sockets */ public void die() { // If we're still connected, tell the server that we're going down. if (connected) { send(new Packet(Packet.COMMAND_CLOSE_CONNECTION)); } connected = false; if (connection != null) { connection.close(); connection = null; } for (int i = 0; i < closeClientListeners.size(); i++){ ((CloseClientListener)closeClientListeners.elementAt(i)).clientClosed(); } if (log != null) { try { log.close(); } catch (IOException e) { System.err.print("Exception closing logfile: "); //$NON-NLS-1$ e.printStackTrace(); } } System.out.println("client: died"); //$NON-NLS-1$ System.out.flush(); } /** * The client has become disconnected from the server */ protected void disconnected() { if (!disconnectFlag) { disconnectFlag = true; if (connected) { connected = false; die(); } if (!host.equals("localhost")) { //$NON-NLS-1$ game.processGameEvent(new GamePlayerDisconnectedEvent(this, getLocalPlayer())); } } } private void initGameLog() { //log = new GameLog( // PreferenceManager.getClientPreferences().getGameLogFilename(), // false, // (new Integer(PreferenceManager.getClientPreferences().getGameLogMaxSize()).longValue() * 1024 * 1024) ); log = new GameLog(PreferenceManager.getClientPreferences().getGameLogFilename()); } private boolean keepGameLog() { return PreferenceManager.getClientPreferences().keepGameLog() && !(this instanceof BotClient); } /** * Return an enumeration of the players in the game */ public Enumeration getPlayers() { return game.getPlayers(); } public Entity getEntity(int id) { return game.getEntity(id); } /** * Returns the individual player assigned the index * parameter. */ public Player getPlayer(int idx) { return game.getPlayer(idx); } /** * Return the local player */ public Player getLocalPlayer() { return getPlayer(local_pn); } /** * Returns an <code>Enumeration</code> of the entities that match * the selection criteria. */ public Enumeration getSelectedEntities(EntitySelector selector) { return game.getSelectedEntities(selector); } /** * Returns the number of first selectable entity */ public int getFirstEntityNum() { return game.getFirstEntityNum(); } /** * Returns the number of the next selectable entity after the one given */ public int getNextEntityNum(int entityId) { return game.getNextEntityNum(entityId); } /** * Returns the number of the first deployable entity */ public int getFirstDeployableEntityNum() { return game.getFirstDeployableEntityNum(); } /** * Returns the number of the next deployable entity */ public int getNextDeployableEntityNum(int entityId) { return game.getNextDeployableEntityNum(entityId); } /** * Shortcut to game.board */ public IBoard getBoard() { return game.getBoard(); } /** * Returns an emumeration of the entities in game.entities */ public Enumeration getEntities() { return game.getEntities(); } public MapSettings getMapSettings() { return mapSettings; } /** * Changes the game phase, and the displays that go * along with it. */ public void changePhase(int phase) { game.setPhase(phase); // Handle phase-specific items. switch (phase) { case IGame.PHASE_STARTING_SCENARIO : sendDone(true); break; case IGame.PHASE_EXCHANGE : sendDone(true); break; case IGame.PHASE_DEPLOYMENT : //free some memory thats only needed in lounge MechSummaryCache.dispose(); MechFileParser.dispose(); memDump("entering deployment phase"); //$NON-NLS-1$ break; case IGame.PHASE_TARGETING : memDump("entering targeting phase"); //$NON-NLS-1$ break; case IGame.PHASE_MOVEMENT : memDump("entering movement phase"); //$NON-NLS-1$ break; case IGame.PHASE_OFFBOARD : memDump("entering offboard phase"); //$NON-NLS-1$ break; case IGame.PHASE_FIRING : memDump("entering firing phase"); //$NON-NLS-1$ break; case IGame.PHASE_PHYSICAL : memDump("entering physical phase"); //$NON-NLS-1$ break; case IGame.PHASE_LOUNGE : MechSummaryCache.getInstance(); duplicateNameHash = new Hashtable(); //reset this break; } } /** * Adds the specified close client listener to receive * close client events. * This is used by external programs running megamek * * @param l the game listener. */ public void addCloseClientListener(CloseClientListener l) { closeClientListeners.addElement(l); } /** * */ public void retrieveServerInfo() { int retry = 50; while (retry-- > 0 && !connected) { synchronized (this) { try { wait(100); } catch (InterruptedException ex) { } } } } /** * is it my turn? */ public boolean isMyTurn() { return game.getTurn() != null && game.getTurn().isValid(local_pn, game); } /** * Can I unload entities stranded on immobile transports? */ public boolean canUnloadStranded() { return game.getTurn() instanceof GameTurn.UnloadStrandedTurn && game.getTurn().isValid(local_pn, game); } /** * Send command to unload stranded entities to the server */ public void sendUnloadStranded(int[] entityIds) { Object[] data = new Object[1]; data[0] = entityIds; send(new Packet(Packet.COMMAND_UNLOAD_STRANDED, data));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -