package net.md_5.bungee.forge;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.forge.ForgeLogger.LogDirection;
import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.protocol.packet.PluginMessage;
/**
* Handshake sequence manager for the Bungee - Forge Server (Downstream/Server
* Connector) link. Modelled after the Forge implementation.
*/
public enum ForgeServerHandshakeState implements IForgeServerPacketHandler<ForgeServerHandshakeState>
{
/**
* Start the handshake.
*
*/
START
{
@Override
public ForgeServerHandshakeState handle(PluginMessage message, ChannelWrapper ch)
{
ForgeLogger.logServer( LogDirection.RECEIVED, this.name(), message );
ch.write( message );
return this;
}
@Override
public ForgeServerHandshakeState send(PluginMessage message, UserConnection con)
{
// Send custom channel registration. Send Hello.
return HELLO;
}
},
HELLO
{
@Override
public ForgeServerHandshakeState handle(PluginMessage message, ChannelWrapper ch)
{
ForgeLogger.logServer( LogDirection.RECEIVED, this.name(), message );
if ( message.getData()[0] == 1 ) // Client Hello
{
ch.write( message );
}
if ( message.getData()[0] == 2 ) // Client ModList
{
ch.write( message );
}
return this;
}
@Override
public ForgeServerHandshakeState send(PluginMessage message, UserConnection con)
{
// Send Server Mod List.
return WAITINGCACK;
}
},
WAITINGCACK
{
@Override
public ForgeServerHandshakeState handle(PluginMessage message, ChannelWrapper ch)
{
ForgeLogger.logServer( LogDirection.RECEIVED, this.name(), message );
ch.write( message );
return this;
}
@Override
public ForgeServerHandshakeState send(PluginMessage message, UserConnection con)
{
if ( message.getData()[0] == 3 && message.getTag().equals( ForgeConstants.FML_HANDSHAKE_TAG ) )
{
con.getForgeClientHandler().setServerIdList( message );
return this;
}
if ( message.getData()[0] == -1 && message.getTag().equals( ForgeConstants.FML_HANDSHAKE_TAG ) ) // transition to COMPLETE after sending ACK
{
return this;
}
if ( message.getTag().equals( ForgeConstants.FORGE_REGISTER ) ) // wait for Forge channel registration
{
return COMPLETE;
}
return this;
}
},
COMPLETE
{
@Override
public ForgeServerHandshakeState handle(PluginMessage message, ChannelWrapper ch)
{
// Wait for ACK
ForgeLogger.logServer( LogDirection.RECEIVED, this.name(), message );
ch.write( message );
return this;
}
@Override
public ForgeServerHandshakeState send(PluginMessage message, UserConnection con)
{
// Send ACK
return DONE;
}
},
/**
* Handshake has been completed. Do not respond to any more handshake
* packets.
*/
DONE
{
@Override
public ForgeServerHandshakeState handle(PluginMessage message, ChannelWrapper ch)
{
// RECEIVE 2 ACKS
ForgeLogger.logServer( LogDirection.RECEIVED, this.name(), message );
ch.write( message );
return this;
}
@Override
public ForgeServerHandshakeState send(PluginMessage message, UserConnection con)
{
return this;
}
}
}