package net.minecraft.client.gui;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.multiplayer.GuiConnecting;
import net.minecraft.client.multiplayer.LanServer;
import net.minecraft.client.multiplayer.LanServerList;
import net.minecraft.client.multiplayer.ServerAddress;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.ServerList;
import net.minecraft.client.multiplayer.ThreadLanServerFind;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.ChatAllowedCharacters;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
import net.minecraft.util.StatCollector;
import net.minecraft.util.StringTranslate;
import org.lwjgl.input.Keyboard;
@SideOnly(Side.CLIENT)
public class GuiMultiplayer extends GuiScreen
{
/** Number of outstanding ThreadPollServers threads */
private static int threadsPending = 0;
/** Lock object for use with synchronized() */
private static Object lock = new Object();
/**
* A reference to the screen object that created this. Used for navigating between screens.
*/
private GuiScreen parentScreen;
/** Slot container for the server list */
private GuiSlotServer serverSlotContainer;
private ServerList internetServerList;
/** Index of the currently selected server */
private int selectedServer = -1;
private GuiButton field_96289_p;
/** The 'Join Server' button */
private GuiButton buttonSelect;
/** The 'Delete' button */
private GuiButton buttonDelete;
/** The 'Delete' button was clicked */
private boolean deleteClicked = false;
/** The 'Add server' button was clicked */
private boolean addClicked = false;
/** The 'Edit' button was clicked */
private boolean editClicked = false;
/** The 'Direct Connect' button was clicked */
private boolean directClicked = false;
/** This GUI's lag tooltip text or null if no lag icon is being hovered. */
private String lagTooltip = null;
/** Instance of ServerData. */
private ServerData theServerData = null;
private LanServerList localNetworkServerList;
private ThreadLanServerFind localServerFindThread;
/** How many ticks this Gui is already opened */
private int ticksOpened;
private boolean field_74024_A;
private List listofLanServers = Collections.emptyList();
public GuiMultiplayer(GuiScreen par1GuiScreen)
{
this.parentScreen = par1GuiScreen;
}
/**
* Adds the buttons (and other controls) to the screen in question.
*/
public void initGui()
{
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
if (!this.field_74024_A)
{
this.field_74024_A = true;
this.internetServerList = new ServerList(this.mc);
this.internetServerList.loadServerList();
this.localNetworkServerList = new LanServerList();
try
{
this.localServerFindThread = new ThreadLanServerFind(this.localNetworkServerList);
this.localServerFindThread.start();
}
catch (Exception exception)
{
this.mc.getLogAgent().logWarning("Unable to start LAN server detection: " + exception.getMessage());
}
this.serverSlotContainer = new GuiSlotServer(this);
}
else
{
this.serverSlotContainer.func_77207_a(this.width, this.height, 32, this.height - 64);
}
this.initGuiControls();
}
/**
* Populate the GuiScreen controlList
*/
public void initGuiControls()
{
StringTranslate stringtranslate = StringTranslate.getInstance();
this.buttonList.add(this.field_96289_p = new GuiButton(7, this.width / 2 - 154, this.height - 28, 70, 20, stringtranslate.translateKey("selectServer.edit")));
this.buttonList.add(this.buttonDelete = new GuiButton(2, this.width / 2 - 74, this.height - 28, 70, 20, stringtranslate.translateKey("selectServer.delete")));
this.buttonList.add(this.buttonSelect = new GuiButton(1, this.width / 2 - 154, this.height - 52, 100, 20, stringtranslate.translateKey("selectServer.select")));
this.buttonList.add(new GuiButton(4, this.width / 2 - 50, this.height - 52, 100, 20, stringtranslate.translateKey("selectServer.direct")));
this.buttonList.add(new GuiButton(3, this.width / 2 + 4 + 50, this.height - 52, 100, 20, stringtranslate.translateKey("selectServer.add")));
this.buttonList.add(new GuiButton(8, this.width / 2 + 4, this.height - 28, 70, 20, stringtranslate.translateKey("selectServer.refresh")));
this.buttonList.add(new GuiButton(0, this.width / 2 + 4 + 76, this.height - 28, 75, 20, stringtranslate.translateKey("gui.cancel")));
boolean flag = this.selectedServer >= 0 && this.selectedServer < this.serverSlotContainer.getSize();
this.buttonSelect.enabled = flag;
this.field_96289_p.enabled = flag;
this.buttonDelete.enabled = flag;
}
/**
* Called from the main game loop to update the screen.
*/
public void updateScreen()
{
super.updateScreen();
++this.ticksOpened;
if (this.localNetworkServerList.getWasUpdated())
{
this.listofLanServers = this.localNetworkServerList.getLanServers();
this.localNetworkServerList.setWasNotUpdated();
}
}
/**
* Called when the screen is unloaded. Used to disable keyboard repeat events
*/
public void onGuiClosed()
{
Keyboard.enableRepeatEvents(false);
if (this.localServerFindThread != null)
{
this.localServerFindThread.interrupt();
this.localServerFindThread = null;
}
}
/**
* Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
*/
protected void actionPerformed(GuiButton par1GuiButton)
{
if (par1GuiButton.enabled)
{
if (par1GuiButton.id == 2)
{
String s = this.internetServerList.getServerData(this.selectedServer).serverName;
if (s != null)
{
this.deleteClicked = true;
StringTranslate stringtranslate = StringTranslate.getInstance();
String s1 = stringtranslate.translateKey("selectServer.deleteQuestion");
String s2 = "\'" + s + "\' " + stringtranslate.translateKey("selectServer.deleteWarning");
String s3 = stringtranslate.translateKey("selectServer.deleteButton");
String s4 = stringtranslate.translateKey("gui.cancel");
GuiYesNo guiyesno = new GuiYesNo(this, s1, s2, s3, s4, this.selectedServer);
this.mc.displayGuiScreen(guiyesno);
}
}
else if (par1GuiButton.id == 1)
{
this.joinServer(this.selectedServer);
}
else if (par1GuiButton.id == 4)
{
this.directClicked = true;
this.mc.displayGuiScreen(new GuiScreenServerList(this, this.theServerData = new ServerData(StatCollector.translateToLocal("selectServer.defaultName"), "")));
}
else if (par1GuiButton.id == 3)
{
this.addClicked = true;
this.mc.displayGuiScreen(new GuiScreenAddServer(this, this.theServerData = new ServerData(StatCollector.translateToLocal("selectServer.defaultName"), "")));
}
else if (par1GuiButton.id == 7)
{
this.editClicked = true;
ServerData serverdata = this.internetServerList.getServerData(this.selectedServer);
this.theServerData = new ServerData(serverdata.serverName, serverdata.serverIP);
this.theServerData.setHideAddress(serverdata.isHidingAddress());
this.mc.displayGuiScreen(new GuiScreenAddServer(this, this.theServerData));
}
else if (par1GuiButton.id == 0)
{
this.mc.displayGuiScreen(this.parentScreen);
}
else if (par1GuiButton.id == 8)
{
this.mc.displayGuiScreen(new GuiMultiplayer(this.parentScreen));
}
else
{
this.serverSlotContainer.actionPerformed(par1GuiButton);
}
}
}
public void confirmClicked(boolean par1, int par2)
{
if (this.deleteClicked)
{
this.deleteClicked = false;
if (par1)
{
this.internetServerList.removeServerData(par2);
this.internetServerList.saveServerList();
this.selectedServer = -1;
}
this.mc.displayGuiScreen(this);
}
else if (this.directClicked)
{
this.directClicked = false;
if (par1)
{
this.connectToServer(this.theServerData);
}
else
{
this.mc.displayGuiScreen(this);
}
}
else if (this.addClicked)
{
this.addClicked = false;
if (par1)
{
this.internetServerList.addServerData(this.theServerData);
this.internetServerList.saveServerList();
this.selectedServer = -1;
}
this.mc.displayGuiScreen(this);
}
else if (this.editClicked)
{
this.editClicked = false;
if (par1)
{
ServerData serverdata = this.internetServerList.getServerData(this.selectedServer);
serverdata.serverName = this.theServerData.serverName;
serverdata.serverIP = this.theServerData.serverIP;
serverdata.setHideAddress(this.theServerData.isHidingAddress());
this.internetServerList.saveServerList();
}
this.mc.displayGuiScreen(this);
}
}
/**
* Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
*/
protected void keyTyped(char par1, int par2)
{
int j = this.selectedServer;
if (par2 == 59)
{
this.mc.gameSettings.hideServerAddress = !this.mc.gameSettings.hideServerAddress;
this.mc.gameSettings.saveOptions();
}
else
{
if (isShiftKeyDown() && par2 == 200)
{
if (j > 0 && j < this.internetServerList.countServers())
{
this.internetServerList.swapServers(j, j - 1);
--this.selectedServer;
if (j < this.internetServerList.countServers() - 1)
{
this.serverSlotContainer.func_77208_b(-this.serverSlotContainer.slotHeight);
}
}
}
else if (isShiftKeyDown() && par2 == 208)
{
if (j < this.internetServerList.countServers() - 1)
{
this.internetServerList.swapServers(j, j + 1);
++this.selectedServer;
if (j > 0)
{
this.serverSlotContainer.func_77208_b(this.serverSlotContainer.slotHeight);
}
}
}
else if (par1 == 13)
{
this.actionPerformed((GuiButton)this.buttonList.get(2));
}
else
{
super.keyTyped(par1, par2);
}
}
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3)
{
this.lagTooltip = null;
StringTranslate stringtranslate = StringTranslate.getInstance();
this.drawDefaultBackground();
this.serverSlotContainer.drawScreen(par1, par2, par3);
this.drawCenteredString(this.fontRenderer, stringtranslate.translateKey("multiplayer.title"), this.width / 2, 20, 16777215);
super.drawScreen(par1, par2, par3);
if (this.lagTooltip != null)
{
this.func_74007_a(this.lagTooltip, par1, par2);
}
}
/**
* Join server by slot index
*/
private void joinServer(int par1)
{
if (par1 < this.internetServerList.countServers())
{
this.connectToServer(this.internetServerList.getServerData(par1));
}
else
{
par1 -= this.internetServerList.countServers();
if (par1 < this.listofLanServers.size())
{
LanServer lanserver = (LanServer)this.listofLanServers.get(par1);
this.connectToServer(new ServerData(lanserver.getServerMotd(), lanserver.getServerIpPort()));
}
}
}
private void connectToServer(ServerData par1ServerData)
{
this.mc.displayGuiScreen(new GuiConnecting(this, this.mc, par1ServerData));
}
private static void func_74017_b(ServerData par1ServerData) throws IOException
{
ServerAddress serveraddress = ServerAddress.func_78860_a(par1ServerData.serverIP);
Socket socket = null;
DataInputStream datainputstream = null;
DataOutputStream dataoutputstream = null;
try
{
socket = new Socket();
socket.setSoTimeout(3000);
socket.setTcpNoDelay(true);
socket.setTrafficClass(18);
socket.connect(new InetSocketAddress(serveraddress.getIP(), serveraddress.getPort()), 3000);
datainputstream = new DataInputStream(socket.getInputStream());
dataoutputstream = new DataOutputStream(socket.getOutputStream());
dataoutputstream.write(254);
dataoutputstream.write(1);
if (datainputstream.read() != 255)
{
throw new IOException("Bad message");
}
String s = Packet.readString(datainputstream, 256);
char[] achar = s.toCharArray();
for (int i = 0; i < achar.length; ++i)
{
if (achar[i] != 167 && achar[i] != 0 && ChatAllowedCharacters.allowedCharacters.indexOf(achar[i]) < 0)
{
achar[i] = 63;
}
}
s = new String(achar);
int j;
int k;
String[] astring;
if (s.startsWith("\u00a7") && s.length() > 1)
{
astring = s.substring(1).split("\u0000");
if (MathHelper.parseIntWithDefault(astring[0], 0) == 1)
{
par1ServerData.serverMOTD = astring[3];
par1ServerData.field_82821_f = MathHelper.parseIntWithDefault(astring[1], par1ServerData.field_82821_f);
par1ServerData.gameVersion = astring[2];
j = MathHelper.parseIntWithDefault(astring[4], 0);
k = MathHelper.parseIntWithDefault(astring[5], 0);
if (j >= 0 && k >= 0)
{
par1ServerData.populationInfo = EnumChatFormatting.GRAY + "" + j + "" + EnumChatFormatting.DARK_GRAY + "/" + EnumChatFormatting.GRAY + k;
}
else
{
par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???";
}
}
else
{
par1ServerData.gameVersion = "???";
par1ServerData.serverMOTD = "" + EnumChatFormatting.DARK_GRAY + "???";
par1ServerData.field_82821_f = 62;
par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???";
}
}
else
{
astring = s.split("\u00a7");
s = astring[0];
j = -1;
k = -1;
try
{
j = Integer.parseInt(astring[1]);
k = Integer.parseInt(astring[2]);
}
catch (Exception exception)
{
;
}
par1ServerData.serverMOTD = EnumChatFormatting.GRAY + s;
if (j >= 0 && k > 0)
{
par1ServerData.populationInfo = EnumChatFormatting.GRAY + "" + j + "" + EnumChatFormatting.DARK_GRAY + "/" + EnumChatFormatting.GRAY + k;
}
else
{
par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???";
}
par1ServerData.gameVersion = "1.3";
par1ServerData.field_82821_f = 60;
}
}
finally
{
try
{
if (datainputstream != null)
{
datainputstream.close();
}
}
catch (Throwable throwable)
{
;
}
try
{
if (dataoutputstream != null)
{
dataoutputstream.close();
}
}
catch (Throwable throwable1)
{
;
}
try
{
if (socket != null)
{
socket.close();
}
}
catch (Throwable throwable2)
{
;
}
}
}
protected void func_74007_a(String par1Str, int par2, int par3)
{
if (par1Str != null)
{
int k = par2 + 12;
int l = par3 - 12;
int i1 = this.fontRenderer.getStringWidth(par1Str);
this.drawGradientRect(k - 3, l - 3, k + i1 + 3, l + 8 + 3, -1073741824, -1073741824);
this.fontRenderer.drawStringWithShadow(par1Str, k, l, -1);
}
}
static ServerList getInternetServerList(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.internetServerList;
}
static List getListOfLanServers(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.listofLanServers;
}
static int getSelectedServer(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.selectedServer;
}
static int getAndSetSelectedServer(GuiMultiplayer par0GuiMultiplayer, int par1)
{
return par0GuiMultiplayer.selectedServer = par1;
}
/**
* Return buttonSelect GuiButton
*/
static GuiButton getButtonSelect(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.buttonSelect;
}
/**
* Return buttonEdit GuiButton
*/
static GuiButton getButtonEdit(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.field_96289_p;
}
/**
* Return buttonDelete GuiButton
*/
static GuiButton getButtonDelete(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.buttonDelete;
}
static void func_74008_b(GuiMultiplayer par0GuiMultiplayer, int par1)
{
par0GuiMultiplayer.joinServer(par1);
}
static int getTicksOpened(GuiMultiplayer par0GuiMultiplayer)
{
return par0GuiMultiplayer.ticksOpened;
}
/**
* Returns the lock object for use with synchronized()
*/
static Object getLock()
{
return lock;
}
static int getThreadsPending()
{
return threadsPending;
}
static int increaseThreadsPending()
{
return threadsPending++;
}
static void func_82291_a(ServerData par0ServerData) throws IOException
{
func_74017_b(par0ServerData);
}
static int decreaseThreadsPending()
{
return threadsPending--;
}
static String getAndSetLagTooltip(GuiMultiplayer par0GuiMultiplayer, String par1Str)
{
return par0GuiMultiplayer.lagTooltip = par1Str;
}
}