/*
* 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 3 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.network.communityserver;
import java.io.IOException;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netcon.BaseReadPacket;
import org.netcon.BaseWritePacket;
import org.netcon.NetConnection;
import org.netcon.NetConnectionConfig;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.network.communityserver.readpackets.AuthResponse;
import com.l2jserver.gameserver.network.communityserver.readpackets.ClanNoticeInfo;
import com.l2jserver.gameserver.network.communityserver.readpackets.ConnectionError;
import com.l2jserver.gameserver.network.communityserver.readpackets.InitCS;
import com.l2jserver.gameserver.network.communityserver.readpackets.RequestPlayerShowBoard;
import com.l2jserver.gameserver.network.communityserver.readpackets.RequestPlayerShowMessage;
import com.l2jserver.gameserver.network.communityserver.readpackets.RequestWorldInfo;
/**
* @authors Forsaiken, Gigiikun
*/
public final class CommunityServerThread extends NetConnection
{
private static final Logger _log = Logger.getLogger(CommunityServerThread.class.getName());
private static CommunityServerThread _instance;
public static final void initialize()
{
if (_instance == null)
{
if (Config.ENABLE_COMMUNITY_BOARD)
{
try
{
_instance = new CommunityServerThread(new NetConnectionConfig(Config.COMMUNITY_CONFIGURATION_FILE));
_instance.start();
}
catch (Exception e)
{
_log.log(Level.WARNING, "CommunityServerThread: Failed loading config file! " + e.getMessage(), e);
}
}
else
{
_log.log(Level.INFO, "CommunityServerThread: Deactivated by config.");
_instance = new CommunityServerThread(null);
}
}
}
public static final CommunityServerThread getInstance()
{
return _instance;
}
private boolean _authed;
private CommunityServerThread(final NetConnectionConfig config)
{
super(config);
}
public final boolean isAuthed()
{
return _authed;
}
public final void setAuthed(final boolean authed)
{
_authed = authed;
}
public final void forceClose(final BaseWritePacket packet)
{
_authed = false;
try
{
super.close(packet);
}
catch (IOException e)
{
_log.log(Level.INFO, "CommunityServerThread: Failed disconnecting server, server already disconnected: " + e.getMessage(), e);
}
}
public boolean sendPacket(final BaseWritePacket packet)
{
return sendPacket(packet, true);
}
public boolean sendPacket(final BaseWritePacket packet, final boolean needAuth)
{
if (needAuth && !_authed)
return false;
try
{
super.write(packet);
}
catch (IOException e)
{
_log.log(Level.INFO, "CommunityServerThread: Failed sending TCP packet: " + e.getMessage(), e);
return false;
}
return true;
}
@Override
public void run()
{
_log.log(Level.INFO, "CommunityServerThread: Activated by config.");
int packetType1 = 0xFF;
int packetType2 = 0xFF;
BaseReadPacket packet = null;
byte[] data = null;
while (!isInterrupted())
{
try
{
super.sleep(10000L);
}
catch (InterruptedException e)
{
return;
}
_log.log(Level.INFO, "CommunityServerThread: Trying to connect to " + Config.COMMUNITY_SERVER_ADDRESS + " on port " + Config.COMMUNITY_SERVER_PORT + ".");
try
{
_instance.connect(Config.COMMUNITY_SERVER_ADDRESS, Config.COMMUNITY_SERVER_PORT);
}
catch (SocketException se)
{
_log.log(Level.INFO, "CommunityServerThread: Connecting to " + Config.COMMUNITY_SERVER_ADDRESS + " on port " + Config.COMMUNITY_SERVER_PORT + " failed.");
continue;
}
catch (IOException e)
{
_log.log(Level.INFO, "CommunityServerThread: Connection failed: " + e.getMessage(), e);
continue;
}
try
{
long gameServerConnectStart = System.currentTimeMillis();
while (!isInterrupted())
{
data = super.read();
packetType1 = data[0] & 0xFF;
packetType2 = data[1] & 0xFF;
if (Config.PACKET_HANDLER_DEBUG)
_log.log(Level.INFO, "Received packet: 0x" + Integer.toHexString(packetType1) + "-0x" + Integer.toHexString(packetType2));
switch (packetType1)
{
case 0x00:
{
switch (packetType2)
{
case 0x00:
packet = new InitCS(data, this);
break;
case 0x01:
_log.info("Server connected in " + ((System.currentTimeMillis() - gameServerConnectStart) / 1000) + " seconds");
packet = new AuthResponse(data, this);
break;
case 0x02:
packet = new ConnectionError(data);
break;
}
break;
}
case 0x01:
{
switch (packetType2)
{
case 0x00:
packet = new RequestWorldInfo(data, this, RequestWorldInfo.SERVER_LOAD);
break;
case 0x01:
packet = new RequestWorldInfo(data, this, RequestWorldInfo.PLAYER_DATA_UPDATE);
break;
case 0x02:
packet = new RequestWorldInfo(data, this, RequestWorldInfo.CLAN_DATA_UPDATE);
break;
case 0x03:
packet = new ClanNoticeInfo(data, 0);
break;
case 0x04:
packet = new ClanNoticeInfo(data, 1);
break;
case 0x05:
packet = new ClanNoticeInfo(data, this, 2);
break;
}
break;
}
case 0x02:
{
switch (packetType2)
{
case 0x00:
packet = new RequestPlayerShowBoard(data);
break;
case 0x01:
packet = new RequestPlayerShowMessage(data);
break;
}
break;
}
}
if (packet != null)
//new Thread(packet).start();
ThreadPoolManager.getInstance().executeCommunityPacket(packet);
else
throw new IOException("Invalid packet!");
}
if (isInterrupted())
forceClose(null);
}
catch (IOException e)
{
_log.log(Level.WARNING, "CommunityServerThread: TCP Connection lost: " + e.getMessage(), e);
forceClose(null);
}
}
}
}