package Ġme . anno . network Ċ Ċ import Ġme . anno . utils . Sleep . wait Until Ċ import Ġjava . io . Closeable Ċ import Ġjava . io . Data InputStream Ċ import Ġjava . io . Data OutputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Inet Address Ċ import Ġjava . net . Socket Ċ import Ġjava . net . Socket Exception Ċ import Ġjava . util . concurrent . Linked BlockingQueue Ċ import Ġjavax . net . ssl . SS LS ocket Factory Ċ import Ġkotlin . concurrent . thread Ċ Ċ open Ġclass ĠTCP Client ( val Ġsocket : ĠSocket , Ġval Ġprotocol : ĠProtocol , Ġvar Ġrandom Id : ĠInt ) Ġ: ĠClose able Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġcreate Socket ( address : ĠInet Address , Ġport : ĠInt , Ġprotocol : ĠProtocol ): ĠSocket Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( protocol . network Protocol Ġ== ĠNetwork Protocol . TCP _ SSL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSSL Socket Factory . getDefault (). create Socket ( address , Ġport ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSocket ( address , Ġport ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( socket : ĠSocket , Ġprotocol : ĠProtocol , Ġname : ĠString ) Ġ: Ġthis ( socket , Ġprotocol , Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . name Ġ= Ġname ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġname Ġ= Ġ"" ĊĠĠĠ Ġvar Ġuuid Ġ= Ġ"" ĊĠĠĠ Ġvar Ġversion : ĠInt Ġ= Ġ 0 ĊĊĠĠĠ Ġvar Ġserver Name Ġ= Ġ"" ĊĠĠĠ Ġvar Ġserver Mot d Ġ= Ġ"" ĊĊĠĠĠ Ġvar Ġclosing Reason Ġ= Ġ"" ĊĊĠĠĠ Ġval Ġdis Ġ= ĠData InputStream ( socket . getInputStream ()) ĊĠĠĠ Ġval Ġdos Ġ= ĠData OutputStream ( socket . get OutputStream ()) ĊĊĠĠĠ Ġval Ġbuffer Ġ= ĠReset ByteArray InputStream ( 3 2 ) ĊĠĠĠ Ġval Ġbuffer Dis Ġ= ĠData InputStream ( buffer ) ĊĊĠĠĠ Ġvar Ġmax Packet Size Ġ= Ġ 1 Ġshl Ġ 2 0 ĊĊĠĠĠ Ġvar Ġudp Port Ġ= Ġ- 1 ĊĠĠĠ Ġvar Ġis Closed 2 Ġ= Ġfalse ĊĊĠĠĠ Ġval Ġwriting Queue Ġ= ĠLinked BlockingQueue < Packet >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġclient Ġtime Ġminus Ġown Ġsystem Ġtime , ĊĠĠĠĠ Ġ* Ġso Ġhow Ġmany Ġnano Ġseconds , Ġthe Ġclock Ġof Ġthe Ġclient Ġis Ġahead ĊĠĠĠĠ Ġ* Ġ*/ ĊĠĠĠ Ġvar Ġlocal Time Offset Ġ= Ġ 0 L ĊĊĠĠĠ Ġval Ġis Closed Ġget () Ġ= Ġsocket . is Closed Ġ|| Ġ! socket . isConnected Ġ|| Ġ! socket . is Bound Ġ|| Ġis Closed 2 ĊĠĠĠ Ġval Ġrandom Id String Ġget () Ġ= Ġrandom Id . to UInt (). toString ( 1 6 ) ĊĠĠĠ Ġvar Ġis Running Ġ= Ġfalse ĊĊĠĠĠ Ġfun Ġensure Connection () Ġ{ ĊĠĠĠĠĠĠĠ Ġwait Until ( true ) Ġ{ Ġis Running Ġ|| Ġis Closed Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is Closed ) Ġthrow ĠSocket Exception (" Connection Ġhas Ġbeen Ġclosed ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġpacket Limit Ġ= Ġ 1 2 8 ĊĊĠĠĠ Ġfun Ġsend TCP ( packet : ĠPacket ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( protocol . find ( packet . big Endian Magic ) Ġ== Ġnull ) Ġthrow ĠUn registered Packet Exception ( packet ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Closed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwriting Queue . size Ġ< Ġpacket Limit Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwriting Queue . add ( packet ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! packet . can Drop Packet Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfind Ġslot Ġin Ġpackets Ġthat Ġwe Ġcan Ġtake ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( writing Queue . remove If Ġ{ Ġit . can Drop Packet Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwriting Queue . add ( packet ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġall Ġpackets Ġare Ġimportant ... Ġthis Ġis Ġawk ward ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġshould Ġnot Ġhappen Ġwith Ġa Ġwell Ġdesigned Ġprotocol , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġor Ġonly Ġif Ġthe Ġclient Ġis Ġm alic ious Ġand Ġnot Ġreading Ġpackets ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠSocket Exception (" There Ġwere Ġtoo Ġmany Ġwaiting , Ġimportant Ġpackets ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġwork Packet Tasks ( server : ĠServer ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġensure Connection () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġhas Data Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! is Closed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpacket Ġ= Ġwriting Queue . poll () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( packet Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġflush Ġautomatically Ġ:) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Data ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( dos ) Ġ{ Ġdos . flush () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Data Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( dos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdos . writeInt ( packet . big Endian Magic ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpacket . send ( server , Ġthis , Ġdos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Data Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSocket Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġflush () Ġ{ ĊĠĠĠĠĠĠĠ Ġensure Connection () ĊĠĠĠĠĠĠĠ Ġsynchronized ( dos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdos . flush () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend UDP ( packet : ĠPacket , Ġprotocol : ĠProtocol , Ġreceive : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsend UDP ( null , Ġprotocol , Ġpacket , Ġreceive ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend UDP ( server : ĠServer ?, Ġprotocol : ĠProtocol , Ġpacket : ĠPacket , Ġreceive : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( receive ) Ġsend UDP ( server , Ġprotocol , Ġpacket ) Ġ{} ĊĠĠĠĠĠĠĠ Ġelse Ġsend UDP ( server , Ġprotocol , Ġpacket , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend UDP ( packet : ĠPacket , Ġprotocol : ĠProtocol , Ġon Receive : Ġ(( Packet ) Ġ-> ĠUnit )? ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsend UDP ( null , Ġprotocol , Ġpacket , Ġon Receive ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend UDP ( server : ĠServer ?, Ġprotocol : ĠProtocol , Ġpacket : ĠPacket , Ġon Receive : Ġ(( Packet ) Ġ-> ĠUnit )? ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( server Ġ!= Ġnull ) Ġthrow ĠSocket Exception (" You Ġneed Ġto Ġsend Ġa Ġresponse Ġto Ġa Ġclient Ġdirectly Ġafter Ġtheir Ġrequest ") ĊĠĠĠĠĠĠĠ Ġensure Connection () ĊĠĠĠĠĠĠĠ Ġval Ġsender Ġ= ĠU D PS ender ( protocol , Ġthis ) ĊĠĠĠĠĠĠĠ Ġsender . send ( packet , Ġon Receive ) ĊĠĠĠĠĠĠĠ Ġsender . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart Client Side ( shutdown : Ġ() Ġ-> ĠBoolean Ġ= Ġ{ Ġfalse Ġ}) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( synchronized ( dos ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsocket Ġ= Ġsocket ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdos . writeInt ( protocol . big Endian Magic ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprotocol . client Handshake ( socket , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Running Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprotocol . client Run ( socket , Ġthis , Ġshutdown ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠSocket Exception (" Handshake Ġfailed ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart Client Side Async ( shutdown : Ġ() Ġ-> ĠBoolean Ġ= Ġ{ Ġfalse Ġ}) Ġ{ ĊĠĠĠĠĠĠĠ Ġthread ( name Ġ= Ġ"$ name . tcp ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Client Side ( shutdown ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSocket Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġconnection Ġclosed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġis Closed 2 Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġis Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġsocket . close () ĊĠĠĠĠĠĠĠ Ġdis . close () ĊĠĠĠĠĠĠĠ Ġdos . close () ĊĠĠĠ Ġ} Ċ Ċ }