001package net.minecraft.network; 002 003import cpw.mods.fml.common.network.FMLNetworkHandler; 004import cpw.mods.fml.relauncher.Side; 005import cpw.mods.fml.relauncher.SideOnly; 006import java.net.InetSocketAddress; 007import java.net.SocketAddress; 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.List; 011import java.util.Queue; 012import java.util.concurrent.ConcurrentLinkedQueue; 013 014import com.google.common.collect.Queues; 015 016import net.minecraft.logging.ILogAgent; 017import net.minecraft.network.packet.NetHandler; 018import net.minecraft.network.packet.Packet; 019 020public class MemoryConnection implements INetworkManager 021{ 022 private static final SocketAddress mySocketAddress = new InetSocketAddress("127.0.0.1", 0); 023 private final Queue<Packet> readPacketCache = Queues.newConcurrentLinkedQueue(); 024 private final ILogAgent field_98214_c; 025 private MemoryConnection pairedConnection; 026 private NetHandler myNetHandler; 027 028 /** set to true by {server,network}Shutdown */ 029 private boolean shuttingDown = false; 030 private String shutdownReason = ""; 031 private Object[] field_74439_g; 032 @SideOnly(Side.CLIENT) 033 private boolean gamePaused = false; 034 035 @SideOnly(Side.CLIENT) 036 public MemoryConnection(ILogAgent par1ILogAgent, NetHandler par2NetHandler) 037 { 038 this.myNetHandler = par2NetHandler; 039 this.field_98214_c = par1ILogAgent; 040 } 041 042 /** 043 * Sets the NetHandler for this NetworkManager. Server-only. 044 */ 045 public void setNetHandler(NetHandler par1NetHandler) 046 { 047 this.myNetHandler = par1NetHandler; 048 } 049 050 /** 051 * Adds the packet to the correct send queue (chunk data packets go to a separate queue). 052 */ 053 public void addToSendQueue(Packet par1Packet) 054 { 055 if (!this.shuttingDown) 056 { 057 this.pairedConnection.processOrCachePacket(par1Packet); 058 } 059 } 060 061 /** 062 * Wakes reader and writer threads 063 */ 064 public void wakeThreads() {} 065 066 @SideOnly(Side.CLIENT) 067 public void closeConnections() 068 { 069 this.pairedConnection = null; 070 this.myNetHandler = null; 071 } 072 073 @SideOnly(Side.CLIENT) 074 public boolean isConnectionActive() 075 { 076 return !this.shuttingDown && this.pairedConnection != null; 077 } 078 079 /** 080 * Checks timeouts and processes all pending read packets. 081 */ 082 public void processReadPackets() 083 { 084 int i = 2500; 085 086 while (i-- >= 0 && !this.readPacketCache.isEmpty()) 087 { 088 Packet packet = readPacketCache.poll(); 089 packet.processPacket(this.myNetHandler); 090 } 091 092 if (this.readPacketCache.size() > i) 093 { 094 this.field_98214_c.func_98236_b("Memory connection overburdened; after processing 2500 packets, we still have " + this.readPacketCache.size() + " to go!"); 095 } 096 097 if (this.shuttingDown && this.readPacketCache.isEmpty()) 098 { 099 this.myNetHandler.handleErrorMessage(this.shutdownReason, this.field_74439_g); 100 FMLNetworkHandler.onConnectionClosed(this, this.myNetHandler.getPlayer()); 101 } 102 } 103 104 /** 105 * Return the InetSocketAddress of the remote endpoint 106 */ 107 public SocketAddress getSocketAddress() 108 { 109 return mySocketAddress; 110 } 111 112 /** 113 * Shuts down the server. (Only actually used on the server) 114 */ 115 public void serverShutdown() 116 { 117 this.shuttingDown = true; 118 } 119 120 /** 121 * Shuts down the network with the specified reason. Closes all streams and sockets, spawns NetworkMasterThread to 122 * stop reading and writing threads. 123 */ 124 public void networkShutdown(String par1Str, Object ... par2ArrayOfObj) 125 { 126 this.shuttingDown = true; 127 this.shutdownReason = par1Str; 128 this.field_74439_g = par2ArrayOfObj; 129 } 130 131 /** 132 * returns 0 for memoryConnections 133 */ 134 public int packetSize() 135 { 136 return 0; 137 } 138 139 @SideOnly(Side.CLIENT) 140 public void pairWith(MemoryConnection par1MemoryConnection) 141 { 142 this.pairedConnection = par1MemoryConnection; 143 par1MemoryConnection.pairedConnection = this; 144 } 145 146 @SideOnly(Side.CLIENT) 147 public boolean isGamePaused() 148 { 149 return this.gamePaused; 150 } 151 152 @SideOnly(Side.CLIENT) 153 public void setGamePaused(boolean par1) 154 { 155 this.gamePaused = par1; 156 } 157 158 @SideOnly(Side.CLIENT) 159 public MemoryConnection getPairedConnection() 160 { 161 return this.pairedConnection; 162 } 163 164 /** 165 * acts immiditally if isWritePacket, otherwise adds it to the readCache to be processed next tick 166 */ 167 public void processOrCachePacket(Packet par1Packet) 168 { 169 if (par1Packet.canProcessAsync() && this.myNetHandler.canProcessPacketsAsync()) 170 { 171 par1Packet.processPacket(this.myNetHandler); 172 } 173 else 174 { 175 this.readPacketCache.add(par1Packet); 176 } 177 } 178}