/* * 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 . */ 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 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; import org.netcon.BaseReadPacket; import org.netcon.BaseWritePacket; import org.netcon.NetConnection; import org.netcon.NetConnectionConfig; /** * @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); } } } }