Dropped MMOCore.

This commit is contained in:
MobiusDevelopment
2021-04-13 09:22:54 +00:00
parent 46ae40bd54
commit 5d89a8ad18
1202 changed files with 23827 additions and 22497 deletions

View File

@@ -6,6 +6,7 @@
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="dist/libs/mariadb-java-client-2.6.1.jar" sourcepath="dist/libs/mariadb-java-client-2.6.1-sources.jar"/> <classpathentry kind="lib" path="dist/libs/mariadb-java-client-2.6.1.jar" sourcepath="dist/libs/mariadb-java-client-2.6.1-sources.jar"/>
<classpathentry kind="lib" path="dist/libs/netty-all-4.1.50.Final.jar" sourcepath="dist/libs/netty-all-4.1.50.Final-sources.jar"/>
<classpathentry including="**/*.java" kind="src" path="dist/game/data/scripts"/> <classpathentry including="**/*.java" kind="src" path="dist/game/data/scripts"/>
<classpathentry kind="src" path="java"/> <classpathentry kind="src" path="java"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>

View File

@@ -130,6 +130,9 @@ ScheduledThreadPoolCount = 160
# Default: 120 # Default: 120
InstantThreadPoolCount = 120 InstantThreadPoolCount = 120
# Default: 40
UrgentPacketThreadCoreSize = 40
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Misc Player Settings # Misc Player Settings

View File

@@ -46,7 +46,7 @@ import org.l2jmobius.gameserver.model.quest.Quest;
import org.l2jmobius.gameserver.model.spawn.Spawn; import org.l2jmobius.gameserver.model.spawn.Spawn;
import org.l2jmobius.gameserver.model.zone.type.BossZone; import org.l2jmobius.gameserver.model.zone.type.BossZone;
import org.l2jmobius.gameserver.network.serverpackets.Earthquake; import org.l2jmobius.gameserver.network.serverpackets.Earthquake;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound; import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SpecialCamera; import org.l2jmobius.gameserver.network.serverpackets.SpecialCamera;
@@ -560,7 +560,7 @@ public class Antharas extends Quest
} }
} }
protected void broadcastPacket(GameServerPacket mov) protected void broadcastPacket(IClientOutgoingPacket mov)
{ {
if (_zone != null) if (_zone != null)
{ {

Binary file not shown.

View File

@@ -106,11 +106,9 @@ public class Config
// others // others
private static final String BANNED_IP_FILE = "./config/others/banned_ip.cfg"; private static final String BANNED_IP_FILE = "./config/others/banned_ip.cfg";
public static final String SERVER_NAME_FILE = "./config/others/servername.xml"; public static final String SERVER_NAME_FILE = "./config/others/servername.xml";
// legacy
private static final String LEGACY_BANNED_IP = "./config/banned_ip.cfg";
// -------------------------------------------------- // --------------------------------------------------
// Constants // Variable Definitions
// -------------------------------------------------- // --------------------------------------------------
public static final String EOL = System.lineSeparator(); public static final String EOL = System.lineSeparator();
@@ -1129,6 +1127,7 @@ public class Config
public static int MAX_PROTOCOL_REVISION; public static int MAX_PROTOCOL_REVISION;
public static int SCHEDULED_THREAD_POOL_COUNT; public static int SCHEDULED_THREAD_POOL_COUNT;
public static int INSTANT_THREAD_POOL_COUNT; public static int INSTANT_THREAD_POOL_COUNT;
public static int IO_PACKET_THREAD_CORE_SIZE;
public static String CNAME_TEMPLATE; public static String CNAME_TEMPLATE;
public static String PET_NAME_TEMPLATE; public static String PET_NAME_TEMPLATE;
public static String CLAN_NAME_TEMPLATE; public static String CLAN_NAME_TEMPLATE;
@@ -1159,18 +1158,6 @@ public class Config
public static long SESSION_TTL; public static long SESSION_TTL;
public static int MAX_LOGINSESSIONS; public static int MAX_LOGINSESSIONS;
/** MMO settings */
public static final int MMO_SELECTOR_SLEEP_TIME = 20; // default 20
public static final int MMO_MAX_SEND_PER_PASS = 80; // default 80
public static final int MMO_MAX_READ_PER_PASS = 80; // default 80
public static final int MMO_HELPER_BUFFER_COUNT = 20; // default 20
/** Client Packets Queue settings */
public static final int CLIENT_PACKET_QUEUE_SIZE = 14; // default MMO_MAX_READ_PER_PASS + 2
/** Packet handler settings */
public static final boolean PACKET_HANDLER_DEBUG = false;
public static void loadAccessConfig() public static void loadAccessConfig()
{ {
final PropertiesParser accessConfig = new PropertiesParser(ACCESS_CONFIG_FILE); final PropertiesParser accessConfig = new PropertiesParser(ACCESS_CONFIG_FILE);
@@ -1229,6 +1216,7 @@ public class Config
} }
SCHEDULED_THREAD_POOL_COUNT = serverConfig.getInt("ScheduledThreadPoolCount", 40); SCHEDULED_THREAD_POOL_COUNT = serverConfig.getInt("ScheduledThreadPoolCount", 40);
INSTANT_THREAD_POOL_COUNT = serverConfig.getInt("InstantThreadPoolCount", 20); INSTANT_THREAD_POOL_COUNT = serverConfig.getInt("InstantThreadPoolCount", 20);
IO_PACKET_THREAD_CORE_SIZE = serverConfig.getInt("UrgentPacketThreadCoreSize", 20);
CNAME_TEMPLATE = serverConfig.getString("CnameTemplate", ".*"); CNAME_TEMPLATE = serverConfig.getString("CnameTemplate", ".*");
PET_NAME_TEMPLATE = serverConfig.getString("PetNameTemplate", ".*"); PET_NAME_TEMPLATE = serverConfig.getString("PetNameTemplate", ".*");
CLAN_NAME_TEMPLATE = serverConfig.getString("ClanNameTemplate", ".*"); CLAN_NAME_TEMPLATE = serverConfig.getString("ClanNameTemplate", ".*");
@@ -2962,12 +2950,6 @@ public class Config
public static void loadBanFile() public static void loadBanFile()
{ {
File file = new File(BANNED_IP_FILE); File file = new File(BANNED_IP_FILE);
if (!file.exists())
{
// old file position
file = new File(LEGACY_BANNED_IP);
}
if (file.exists() && file.isFile()) if (file.exists() && file.isFile())
{ {
FileInputStream fis = null; FileInputStream fis = null;

View File

@@ -1,46 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
import java.nio.ByteBuffer;
/**
* @author KenM
* @param <T>
*/
public abstract class MMOClient<T extends MMOConnection<?>>
{
private final T _con;
public MMOClient(T con)
{
_con = con;
}
public T getConnection()
{
return _con;
}
public abstract boolean decrypt(ByteBuffer buf, int size);
public abstract boolean encrypt(ByteBuffer buf, int size);
protected abstract void onDisconnection();
protected abstract void onForcedDisconnection();
}

View File

@@ -1,270 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.WritableByteChannel;
/**
* @author KenM
* @param <T>
*/
public class MMOConnection<T extends MMOClient<?>>
{
private final SelectorThread<T> _selectorThread;
private final Socket _socket;
private final InetAddress _address;
private final ReadableByteChannel _readableByteChannel;
private final WritableByteChannel _writableByteChannel;
private final int _port;
private final NioNetStackList<SendablePacket<T>> _sendQueue;
private final SelectionKey _selectionKey;
private ByteBuffer _readBuffer;
private ByteBuffer _primaryWriteBuffer;
private ByteBuffer _secondaryWriteBuffer;
private volatile boolean _pendingClose;
private T _client;
public MMOConnection(SelectorThread<T> selectorThread, Socket socket, SelectionKey key)
{
_selectorThread = selectorThread;
_socket = socket;
_address = socket.getInetAddress();
_readableByteChannel = socket.getChannel();
_writableByteChannel = socket.getChannel();
_port = socket.getPort();
_selectionKey = key;
_sendQueue = new NioNetStackList<>();
}
final void setClient(T client)
{
_client = client;
}
public T getClient()
{
return _client;
}
public void sendPacket(SendablePacket<T> sp)
{
sp._client = _client;
if (_pendingClose)
{
return;
}
synchronized (getSendQueue())
{
_sendQueue.addLast(sp);
}
if (!_sendQueue.isEmpty())
{
try
{
_selectionKey.interestOps(_selectionKey.interestOps() | SelectionKey.OP_WRITE);
}
catch (CancelledKeyException e)
{
// ignore
}
}
}
final SelectionKey getSelectionKey()
{
return _selectionKey;
}
public InetAddress getInetAddress()
{
return _address;
}
public int getPort()
{
return _port;
}
final void close() throws IOException
{
_socket.close();
}
final int read(ByteBuffer buf) throws IOException
{
return _readableByteChannel.read(buf);
}
final int write(ByteBuffer buf) throws IOException
{
return _writableByteChannel.write(buf);
}
final void createWriteBuffer(ByteBuffer buf)
{
if (_primaryWriteBuffer == null)
{
_primaryWriteBuffer = _selectorThread.getPooledBuffer();
_primaryWriteBuffer.put(buf);
}
else
{
final ByteBuffer temp = _selectorThread.getPooledBuffer();
temp.put(buf);
final int remaining = temp.remaining();
_primaryWriteBuffer.flip();
final int limit = _primaryWriteBuffer.limit();
if (remaining >= _primaryWriteBuffer.remaining())
{
temp.put(_primaryWriteBuffer);
_selectorThread.recycleBuffer(_primaryWriteBuffer);
_primaryWriteBuffer = temp;
}
else
{
_primaryWriteBuffer.limit(remaining);
temp.put(_primaryWriteBuffer);
_primaryWriteBuffer.limit(limit);
_primaryWriteBuffer.compact();
_secondaryWriteBuffer = _primaryWriteBuffer;
}
_primaryWriteBuffer = temp;
}
}
final boolean hasPendingWriteBuffer()
{
return _primaryWriteBuffer != null;
}
final void movePendingWriteBufferTo(ByteBuffer dest)
{
_primaryWriteBuffer.flip();
dest.put(_primaryWriteBuffer);
_selectorThread.recycleBuffer(_primaryWriteBuffer);
_primaryWriteBuffer = _secondaryWriteBuffer;
_secondaryWriteBuffer = null;
}
final void setReadBuffer(ByteBuffer buf)
{
_readBuffer = buf;
}
final ByteBuffer getReadBuffer()
{
return _readBuffer;
}
public boolean isClosed()
{
return _pendingClose;
}
final NioNetStackList<SendablePacket<T>> getSendQueue()
{
return _sendQueue;
}
/*
* final SendablePacket<T> getClosePacket() { return _closePacket; }
*/
@SuppressWarnings("unchecked")
public void close(SendablePacket<T> sp)
{
close(new SendablePacket[]
{
sp
});
}
public void close(SendablePacket<T>[] closeList)
{
if (_pendingClose)
{
return;
}
synchronized (getSendQueue())
{
if (!_pendingClose)
{
_pendingClose = true;
_sendQueue.clear();
for (SendablePacket<T> sp : closeList)
{
_sendQueue.addLast(sp);
}
}
}
try
{
_selectionKey.interestOps(_selectionKey.interestOps() & ~SelectionKey.OP_WRITE);
}
catch (CancelledKeyException e)
{
// ignore
}
// _closePacket = sp;
_selectorThread.closeConnection(this);
}
final void releaseBuffers()
{
if (_primaryWriteBuffer != null)
{
_selectorThread.recycleBuffer(_primaryWriteBuffer);
_primaryWriteBuffer = null;
if (_secondaryWriteBuffer != null)
{
_selectorThread.recycleBuffer(_secondaryWriteBuffer);
_secondaryWriteBuffer = null;
}
}
if (_readBuffer != null)
{
_selectorThread.recycleBuffer(_readBuffer);
_readBuffer = null;
}
}
}

View File

@@ -1,101 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
/**
* @author Forsaiken
* @param <E>
*/
public class NioNetStackList<E>
{
private final NioNetStackNode _start = new NioNetStackNode();
private final NioNetStackNodeBuf _buf = new NioNetStackNodeBuf();
private NioNetStackNode _end = new NioNetStackNode();
public NioNetStackList()
{
clear();
}
public void addLast(E elem)
{
final NioNetStackNode newEndNode = _buf.removeFirst();
_end._value = elem;
_end._next = newEndNode;
_end = newEndNode;
}
public E removeFirst()
{
final NioNetStackNode old = _start._next;
final E value = old._value;
_start._next = old._next;
_buf.addLast(old);
return value;
}
public boolean isEmpty()
{
return _start._next == _end;
}
public void clear()
{
_start._next = _end;
}
protected final class NioNetStackNode
{
protected NioNetStackNode _next;
protected E _value;
}
private final class NioNetStackNodeBuf
{
private final NioNetStackNode _start = new NioNetStackNode();
private NioNetStackNode _end = new NioNetStackNode();
NioNetStackNodeBuf()
{
_start._next = _end;
}
final void addLast(NioNetStackNode node)
{
node._next = null;
node._value = null;
_end._next = node;
_end = node;
}
final NioNetStackNode removeFirst()
{
if (_start._next == _end)
{
return new NioNetStackNode();
}
final NioNetStackNode old = _start._next;
_start._next = old._next;
return old;
}
}
}

View File

@@ -1,61 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
import java.nio.BufferOverflowException;
/**
* @author Forsaiken
*/
public class NioNetStringBuffer
{
private final char[] _buf;
private final int _size;
private int _len;
public NioNetStringBuffer(int size)
{
_buf = new char[size];
_size = size;
_len = 0;
}
public void clear()
{
_len = 0;
}
public void append(char c)
{
if (_len < _size)
{
_buf[_len++] = c;
}
else
{
throw new BufferOverflowException();
}
}
@Override
public String toString()
{
return new String(_buf, 0, _len);
}
}

View File

@@ -1,139 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
import java.nio.ByteBuffer;
/**
* @author KenM
* @param <T>
*/
public abstract class ReceivablePacket<T extends MMOClient<?>>extends AbstractPacket<T> implements Runnable
{
NioNetStringBuffer _sbuf;
protected ReceivablePacket()
{
}
protected abstract boolean read();
@Override
public abstract void run();
/**
* Reads <b>byte[]</b> from the buffer.<br>
* Reads as many bytes as the length of the array.
* @param dst : the byte array which will be filled with the data.
*/
protected final void readB(byte[] dst)
{
_buf.get(dst);
}
/**
* Reads <b>byte[]</b> from the buffer.<br>
* Reads as many bytes as the given length (len). Starts to fill the byte array from the given offset to <b>offset</b> + <b>len</b>.
* @param dst : the byte array which will be filled with the data.
* @param offset : starts to fill the byte array from the given offset.
* @param len : the given length of bytes to be read.
*/
protected final void readB(byte[] dst, int offset, int len)
{
_buf.get(dst, offset, len);
}
/**
* Reads <b>byte</b> from the buffer.<br>
* 8bit integer (00)
* @return
*/
protected final int readC()
{
return _buf.get() & 0xFF;
}
/**
* Reads <b>short</b> from the buffer.<br>
* 16bit integer (00 00)
* @return
*/
protected final int readH()
{
return _buf.getShort() & 0xFFFF;
}
/**
* Reads <b>int</b> from the buffer.<br>
* 32bit integer (00 00 00 00)
* @return
*/
protected final int readD()
{
return _buf.getInt();
}
/**
* Reads <b>long</b> from the buffer.<br>
* 64bit integer (00 00 00 00 00 00 00 00)
* @return
*/
protected final long readQ()
{
return _buf.getLong();
}
/**
* Reads <b>double</b> from the buffer.<br>
* 64bit double precision float (00 00 00 00 00 00 00 00)
* @return
*/
protected final double readF()
{
return _buf.getDouble();
}
/**
* Reads <b>String</b> from the buffer.
* @return
*/
protected final String readS()
{
_sbuf.clear();
char ch;
while ((ch = _buf.getChar()) != 0)
{
_sbuf.append(ch);
}
return _sbuf.toString();
}
/**
* packet forge purpose
* @param data
* @param client
* @param sBuffer
*/
public void setBuffers(ByteBuffer data, T client, NioNetStringBuffer sBuffer)
{
_buf = data;
_client = client;
_sbuf = sBuffer;
}
}

View File

@@ -1,52 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
/**
* @author KenM
*/
public class SelectorConfig
{
public int READ_BUFFER_SIZE = 64 * 1024;
public int WRITE_BUFFER_SIZE = 64 * 1024;
public int HELPER_BUFFER_COUNT = 20;
public int HELPER_BUFFER_SIZE = 64 * 1024;
/**
* Server will try to send MAX_SEND_PER_PASS packets per socket write call<br>
* however it may send less if the write buffer was filled before achieving this value.
*/
public int MAX_SEND_PER_PASS = 10;
/**
* Server will try to read MAX_READ_PER_PASS packets per socket read call<br>
* however it may read less if the read buffer was empty before achieving this value.
*/
public int MAX_READ_PER_PASS = 10;
/**
* Defines how much time (in milis) should the selector sleep, an higher value increases throughput but also increases latency(to a max of the sleep value itself).<br>
* Also an extremely high value(usually > 100) will decrease throughput due to the server not doing enough sends per second (depends on max sends per pass).<br>
* Recommended values:<br>
* 1 for minimal latency.<br>
* 10-30 for an latency/troughput trade-off based on your needs.
*/
public int SLEEP_TIME = 10;
}

View File

@@ -1,692 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.LinkedList;
/**
* Parts of design based on network core from WoodenGil
* @param <T>
* @author KenM
*/
public class SelectorThread<T extends MMOClient<?>>extends Thread
{
// default BYTE_ORDER
private static final ByteOrder BYTE_ORDER = ByteOrder.LITTLE_ENDIAN;
// default HEADER_SIZE
private static final int HEADER_SIZE = 2;
// Selector
private final Selector _selector;
// Implementations
private final IPacketHandler<T> _packetHandler;
private final IMMOExecutor<T> _executor;
private final IClientFactory<T> _clientFactory;
// Configurations
private final int HELPER_BUFFER_SIZE;
private final int HELPER_BUFFER_COUNT;
private final int MAX_SEND_PER_PASS;
private final int MAX_READ_PER_PASS;
private final long SLEEP_TIME;
// Main Buffers
private final ByteBuffer DIRECT_WRITE_BUFFER;
private final ByteBuffer WRITE_BUFFER;
private final ByteBuffer READ_BUFFER;
// String Buffer
private final NioNetStringBuffer STRING_BUFFER;
// ByteBuffers General Purpose Pool
private final LinkedList<ByteBuffer> _bufferPool;
// Pending Close
private final NioNetStackList<MMOConnection<T>> _pendingClose;
private boolean _shutdown;
public SelectorThread(SelectorConfig sc, IMMOExecutor<T> executor, IPacketHandler<T> packetHandler, IClientFactory<T> clientFactory) throws IOException
{
super.setName("SelectorThread-" + super.getId());
HELPER_BUFFER_SIZE = sc.HELPER_BUFFER_SIZE;
HELPER_BUFFER_COUNT = sc.HELPER_BUFFER_COUNT;
MAX_SEND_PER_PASS = sc.MAX_SEND_PER_PASS;
MAX_READ_PER_PASS = sc.MAX_READ_PER_PASS;
SLEEP_TIME = sc.SLEEP_TIME;
DIRECT_WRITE_BUFFER = ByteBuffer.allocateDirect(sc.WRITE_BUFFER_SIZE).order(BYTE_ORDER);
WRITE_BUFFER = ByteBuffer.wrap(new byte[sc.WRITE_BUFFER_SIZE]).order(BYTE_ORDER);
READ_BUFFER = ByteBuffer.wrap(new byte[sc.READ_BUFFER_SIZE]).order(BYTE_ORDER);
STRING_BUFFER = new NioNetStringBuffer(64 * 1024);
_pendingClose = new NioNetStackList<>();
_bufferPool = new LinkedList<>();
for (int i = 0; i < HELPER_BUFFER_COUNT; i++)
{
_bufferPool.addLast(ByteBuffer.wrap(new byte[HELPER_BUFFER_SIZE]).order(BYTE_ORDER));
}
_packetHandler = packetHandler;
_clientFactory = clientFactory;
_executor = executor;
_selector = Selector.open();
}
public void openServerSocket(InetAddress address, int tcpPort) throws IOException
{
final ServerSocketChannel selectable = ServerSocketChannel.open();
selectable.configureBlocking(false);
final ServerSocket ss = selectable.socket();
if (address != null)
{
ss.bind(new InetSocketAddress(address, tcpPort));
}
else
{
ss.bind(new InetSocketAddress(tcpPort));
}
selectable.register(_selector, SelectionKey.OP_ACCEPT);
}
protected ByteBuffer getPooledBuffer()
{
if (_bufferPool.isEmpty())
{
return ByteBuffer.wrap(new byte[HELPER_BUFFER_SIZE]).order(BYTE_ORDER);
}
return _bufferPool.removeFirst();
}
protected void recycleBuffer(ByteBuffer buf)
{
if (_bufferPool.size() < HELPER_BUFFER_COUNT)
{
buf.clear();
_bufferPool.addLast(buf);
}
}
@SuppressWarnings("unchecked")
@Override
public void run()
{
int selectedKeysCount = 0;
SelectionKey key;
MMOConnection<T> con;
Iterator<SelectionKey> selectedKeys;
while (!_shutdown)
{
try
{
selectedKeysCount = _selector.selectNow();
}
catch (IOException e)
{
e.printStackTrace();
}
if (selectedKeysCount > 0)
{
selectedKeys = _selector.selectedKeys().iterator();
while (selectedKeys.hasNext())
{
key = selectedKeys.next();
selectedKeys.remove();
con = (MMOConnection<T>) key.attachment();
switch (key.readyOps())
{
case SelectionKey.OP_CONNECT:
{
finishConnection(key, con);
break;
}
case SelectionKey.OP_ACCEPT:
{
acceptConnection(key, con);
break;
}
case SelectionKey.OP_READ:
{
readPacket(key, con);
break;
}
case SelectionKey.OP_WRITE:
{
writePacket(key, con);
break;
}
case SelectionKey.OP_READ | SelectionKey.OP_WRITE:
{
writePacket(key, con);
if (key.isValid())
{
readPacket(key, con);
}
break;
}
}
}
}
synchronized (_pendingClose)
{
while (!_pendingClose.isEmpty())
{
con = _pendingClose.removeFirst();
writeClosePacket(con);
closeConnectionImpl(con.getSelectionKey(), con);
}
}
try
{
Thread.sleep(SLEEP_TIME);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
closeSelectorThread();
}
private final void finishConnection(SelectionKey key, MMOConnection<T> con)
{
try
{
((SocketChannel) key.channel()).finishConnect();
}
catch (IOException e)
{
con.getClient().onForcedDisconnection();
closeConnectionImpl(key, con);
}
// key might have been invalidated on finishConnect()
if (key.isValid())
{
key.interestOps(key.interestOps() | SelectionKey.OP_READ);
key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT);
}
}
@SuppressWarnings("all")
private void acceptConnection(SelectionKey key, MMOConnection<T> con)
{
final ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = null;
try
{
while ((sc = ssc.accept()) != null)
{
sc.configureBlocking(false);
final SelectionKey clientKey = sc.register(_selector, SelectionKey.OP_READ);
con = new MMOConnection<>(this, sc.socket(), clientKey);
con.setClient(_clientFactory.create(con));
clientKey.attach(con);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void readPacket(SelectionKey key, MMOConnection<T> con)
{
if (con.isClosed())
{
return;
}
ByteBuffer buf = con.getReadBuffer();
if (buf == null)
{
buf = READ_BUFFER;
}
// if we try to to do a read with no space in the buffer it will read 0 bytes going into infinite loop
if (buf.position() == buf.limit())
{
System.exit(0);
}
int result = -2;
try
{
result = con.read(buf);
}
catch (IOException e)
{
// error handling goes bellow
}
if (result > 0)
{
buf.flip();
final T client = con.getClient();
for (int i = 0; i < MAX_READ_PER_PASS; i++)
{
if (!tryReadPacket(key, client, buf, con))
{
return;
}
}
// only reachable if MAX_READ_PER_PASS has been reached
// check if there are some more bytes in buffer
// and allocate/compact to prevent content lose.
if (buf.remaining() > 0)
{
// did we use the READ_BUFFER ?
if (buf == READ_BUFFER)
{
// move the pending byte to the connections READ_BUFFER
allocateReadBuffer(con);
}
else
{
// move the first byte to the beginning :)
buf.compact();
}
}
}
else
{
switch (result)
{
case 0:
case -1:
{
closeConnectionImpl(key, con);
break;
}
case -2:
{
con.getClient().onForcedDisconnection();
closeConnectionImpl(key, con);
break;
}
}
}
}
private boolean tryReadPacket(SelectionKey key, T client, ByteBuffer buf, MMOConnection<T> con)
{
switch (buf.remaining())
{
case 0:
{
// buffer is full nothing to read
return false;
}
case 1:
{
// we don't have enough data for header so we need to read
key.interestOps(key.interestOps() | SelectionKey.OP_READ);
// did we use the READ_BUFFER ?
if (buf == READ_BUFFER)
{
// move the pending byte to the connections READ_BUFFER
allocateReadBuffer(con);
}
else
{
// move the first byte to the beginning :)
buf.compact();
}
return false;
}
default:
{
// data size excluding header size :>
final int dataPending = (buf.getShort() & 0xFFFF) - HEADER_SIZE;
// do we got enough bytes for the packet?
if (dataPending <= buf.remaining())
{
// avoid parsing dummy packets (packets without body)
if (dataPending > 0)
{
final int pos = buf.position();
parseClientPacket(pos, buf, dataPending, client);
buf.position(pos + dataPending);
}
// if we are done with this buffer
if (!buf.hasRemaining())
{
if (buf != READ_BUFFER)
{
con.setReadBuffer(null);
recycleBuffer(buf);
}
else
{
READ_BUFFER.clear();
}
return false;
}
return true;
}
// we don't have enough bytes for the dataPacket so we need to read
key.interestOps(key.interestOps() | SelectionKey.OP_READ);
// did we use the READ_BUFFER ?
if (buf == READ_BUFFER)
{
// move it's position
buf.position(buf.position() - HEADER_SIZE);
// move the pending byte to the connections READ_BUFFER
allocateReadBuffer(con);
}
else
{
buf.position(buf.position() - HEADER_SIZE);
buf.compact();
}
return false;
}
}
}
private void allocateReadBuffer(MMOConnection<T> con)
{
con.setReadBuffer(getPooledBuffer().put(READ_BUFFER));
READ_BUFFER.clear();
}
private final void parseClientPacket(int pos, ByteBuffer buf, int dataSize, T client)
{
final boolean ret = client.decrypt(buf, dataSize);
if (ret && buf.hasRemaining())
{
// apply limit
final int limit = buf.limit();
buf.limit(pos + dataSize);
final ReceivablePacket<T> cp = _packetHandler.handlePacket(buf, client);
if (cp != null)
{
cp._buf = buf;
cp._sbuf = STRING_BUFFER;
cp._client = client;
if (cp.read())
{
_executor.execute(cp);
}
cp._buf = null;
cp._sbuf = null;
}
buf.limit(limit);
}
}
private void writeClosePacket(MMOConnection<T> con)
{
SendablePacket<T> sp;
synchronized (con.getSendQueue())
{
if (con.getSendQueue().isEmpty())
{
return;
}
while ((sp = con.getSendQueue().removeFirst()) != null)
{
WRITE_BUFFER.clear();
putPacketIntoWriteBuffer(con.getClient(), sp);
WRITE_BUFFER.flip();
try
{
con.write(WRITE_BUFFER);
}
catch (IOException e)
{
// error handling goes on the if bellow
}
}
}
}
protected void writePacket(SelectionKey key, MMOConnection<T> con)
{
if (!prepareWriteBuffer(con))
{
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
return;
}
DIRECT_WRITE_BUFFER.flip();
final int size = DIRECT_WRITE_BUFFER.remaining();
int result = -1;
try
{
result = con.write(DIRECT_WRITE_BUFFER);
}
catch (IOException e)
{
// error handling goes on the if bellow
}
// check if no error happened
if (result >= 0)
{
// check if we written everything
if (result == size)
{
// complete write
synchronized (con.getSendQueue())
{
if (con.getSendQueue().isEmpty() && !con.hasPendingWriteBuffer())
{
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
}
}
}
else
{
// incomplete write
con.createWriteBuffer(DIRECT_WRITE_BUFFER);
}
}
else
{
con.getClient().onForcedDisconnection();
closeConnectionImpl(key, con);
}
}
private boolean prepareWriteBuffer(MMOConnection<T> con)
{
boolean hasPending = false;
DIRECT_WRITE_BUFFER.clear();
// if there is pending content add it
if (con.hasPendingWriteBuffer())
{
con.movePendingWriteBufferTo(DIRECT_WRITE_BUFFER);
hasPending = true;
}
if ((DIRECT_WRITE_BUFFER.remaining() > 1) && !con.hasPendingWriteBuffer())
{
final NioNetStackList<SendablePacket<T>> sendQueue = con.getSendQueue();
final T client = con.getClient();
SendablePacket<T> sp;
for (int i = 0; i < MAX_SEND_PER_PASS; i++)
{
synchronized (con.getSendQueue())
{
if (sendQueue.isEmpty())
{
sp = null;
}
else
{
sp = sendQueue.removeFirst();
}
}
if (sp == null)
{
break;
}
hasPending = true;
// put into WriteBuffer
putPacketIntoWriteBuffer(client, sp);
WRITE_BUFFER.flip();
if (DIRECT_WRITE_BUFFER.remaining() < WRITE_BUFFER.limit())
{
con.createWriteBuffer(WRITE_BUFFER);
break;
}
DIRECT_WRITE_BUFFER.put(WRITE_BUFFER);
}
}
return hasPending;
}
private void putPacketIntoWriteBuffer(T client, SendablePacket<T> sp)
{
WRITE_BUFFER.clear();
// reserve space for the size
final int headerPos = WRITE_BUFFER.position();
final int dataPos = headerPos + HEADER_SIZE;
WRITE_BUFFER.position(dataPos);
// set the write buffer
sp._buf = WRITE_BUFFER;
// write content to buffer
sp.write();
// delete the write buffer
sp._buf = null;
// size (inclusive header)
int dataSize = WRITE_BUFFER.position() - dataPos;
WRITE_BUFFER.position(dataPos);
client.encrypt(WRITE_BUFFER, dataSize);
// recalculate size after encryption
dataSize = WRITE_BUFFER.position() - dataPos;
WRITE_BUFFER.position(headerPos);
// write header
WRITE_BUFFER.putShort((short) (dataSize + HEADER_SIZE));
WRITE_BUFFER.position(dataPos + dataSize);
}
protected void closeConnection(MMOConnection<T> con)
{
synchronized (_pendingClose)
{
_pendingClose.addLast(con);
}
}
private void closeConnectionImpl(SelectionKey key, MMOConnection<T> con)
{
try
{
// notify connection
con.getClient().onDisconnection();
}
finally
{
try
{
// close socket and the SocketChannel
con.close();
}
catch (IOException e)
{
// ignore, we are closing anyway
}
finally
{
con.releaseBuffers();
// clear attachment
key.attach(null);
// cancel key
key.cancel();
}
}
}
public void shutdown()
{
_shutdown = true;
}
protected void closeSelectorThread()
{
for (SelectionKey key : _selector.keys())
{
try
{
key.channel().close();
}
catch (IOException e)
{
// ignore
}
}
try
{
_selector.close();
}
catch (IOException e)
{
// Ignore
}
}
}

View File

@@ -1,121 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.mmocore;
/**
* @author KenM
* @param <T>
*/
public abstract class SendablePacket<T extends MMOClient<?>>extends AbstractPacket<T>
{
protected final void putInt(int value)
{
_buf.putInt(value);
}
protected final void putDouble(double value)
{
_buf.putDouble(value);
}
protected final void putFloat(float value)
{
_buf.putFloat(value);
}
/**
* Write <b>byte</b> to the buffer.<br>
* 8bit integer (00)
* @param data
*/
protected final void writeC(int data)
{
_buf.put((byte) data);
}
/**
* Write <b>double</b> to the buffer.<br>
* 64bit double precision float (00 00 00 00 00 00 00 00)
* @param value
*/
protected final void writeF(double value)
{
_buf.putDouble(value);
}
/**
* Write <b>short</b> to the buffer.<br>
* 16bit integer (00 00)
* @param value
*/
protected final void writeH(int value)
{
_buf.putShort((short) value);
}
/**
* Write <b>int</b> to the buffer.<br>
* 32bit integer (00 00 00 00)
* @param value
*/
protected final void writeD(int value)
{
_buf.putInt(value);
}
/**
* Write <b>long</b> to the buffer.<br>
* 64bit integer (00 00 00 00 00 00 00 00)
* @param value
*/
protected final void writeQ(long value)
{
// C4 adjustment.
// _buf.putLong(value);
_buf.putInt((int) value);
}
/**
* Write <b>byte[]</b> to the buffer.<br>
* 8bit integer array (00 ...)
* @param data
*/
protected final void writeB(byte[] data)
{
_buf.put(data);
}
/**
* Write <b>String</b> to the buffer.
* @param text
*/
protected final void writeS(String text)
{
if (text != null)
{
final int len = text.length();
for (int i = 0; i < len; i++)
{
_buf.putChar(text.charAt(i));
}
}
_buf.putChar('\000');
}
protected abstract void write();
}

View File

@@ -14,21 +14,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.loginserver.network.clientpackets; package org.l2jmobius.commons.network;
import org.l2jmobius.loginserver.LoginClient; import org.l2jmobius.loginserver.LoginClient;
/** /**
* This class ...
* @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:30:12 $ * @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:30:12 $
*/ */
public abstract class ClientBasePacket implements Runnable public abstract class BaseRecievePacket implements Runnable
{ {
private final LoginClient _client; private final LoginClient _client;
private final byte[] _decrypt; private final byte[] _decrypt;
private int _off; private int _off;
public ClientBasePacket(byte[] decrypt, LoginClient client) public BaseRecievePacket(byte[] decrypt, LoginClient client)
{ {
_decrypt = decrypt; _decrypt = decrypt;
_off = 1; // skip packet type id _off = 1; // skip packet type id

View File

@@ -14,18 +14,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.loginserver.network.gameserverpackets; package org.l2jmobius.commons.network;
/** /**
* This class ...
* @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:30:12 $ * @version $Revision: 1.2.4.1 $ $Date: 2005/03/27 15:30:12 $
*/ */
public abstract class GameServerBasePacket public abstract class BaseSendablePacket
{ {
private final byte[] _decrypt; private final byte[] _decrypt;
private int _off; private int _off;
public GameServerBasePacket(byte[] decrypt) public BaseSendablePacket(byte[] decrypt)
{ {
_decrypt = decrypt; _decrypt = decrypt;
_off = 1; // skip packet type id _off = 1; // skip packet type id

View File

@@ -0,0 +1,46 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* @author Nos
* @param <T>
*/
public abstract class ChannelInboundHandler<T extends ChannelInboundHandler<?>>extends SimpleChannelInboundHandler<IIncomingPacket<T>>
{
private Channel _channel;
@Override
public void channelActive(ChannelHandlerContext ctx)
{
_channel = ctx.channel();
}
public void setConnectionState(IConnectionState connectionState)
{
_channel.attr(IConnectionState.ATTRIBUTE_KEY).set(connectionState);
}
public IConnectionState getConnectionState()
{
return _channel != null ? _channel.attr(IConnectionState.ATTRIBUTE_KEY).get() : null;
}
}

View File

@@ -14,18 +14,14 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.gameserver.network.serverpackets; package org.l2jmobius.commons.network;
import io.netty.util.AttributeKey;
/** /**
* Format: (ch). * @author Nos
* @author -Wooden-
*/ */
public class ExOrcMove extends GameServerPacket public interface IConnectionState
{ {
@Override AttributeKey<IConnectionState> ATTRIBUTE_KEY = AttributeKey.valueOf(IConnectionState.class, "");
protected void writeImpl()
{
writeC(0xfe);
writeH(0x44);
}
} }

View File

@@ -14,14 +14,16 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.commons.mmocore; package org.l2jmobius.commons.network;
import java.nio.channels.SocketChannel; import io.netty.buffer.ByteBuf;
/** /**
* @author KenM * @author Nos
*/ */
public interface IAcceptFilter public interface ICrypt
{ {
boolean accept(SocketChannel sc); void encrypt(ByteBuf buf);
void decrypt(ByteBuf buf);
} }

View File

@@ -14,13 +14,21 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.commons.mmocore; package org.l2jmobius.commons.network;
/** /**
* @author KenM * @author Nos
* @param <T> * @param <T>
*/ */
public interface IClientFactory<T extends MMOClient<?>> public interface IIncomingPacket<T>
{ {
T create(MMOConnection<T> con); /**
* Reads a packet.
* @param client the client
* @param packet the packet reader
* @return {@code true} if packet was read successfully, {@code false} otherwise.
*/
boolean read(T client, PacketReader packet);
void run(T client) throws Exception;
} }

View File

@@ -14,22 +14,19 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.commons.mmocore; package org.l2jmobius.commons.network;
import java.nio.ByteBuffer; import java.util.Set;
/** /**
* @author KenM * @author Nos
* @param <T> * @param <T>
*/ */
public abstract class AbstractPacket<T extends MMOClient<?>> public interface IIncomingPackets<T>extends IConnectionState
{ {
protected ByteBuffer _buf; int getPacketId();
T _client; IIncomingPacket<T> newIncomingPacket();
public T getClient() Set<IConnectionState> getConnectionStates();
{
return _client;
}
} }

View File

@@ -14,14 +14,16 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.loginserver.network.serverpackets; package org.l2jmobius.commons.network;
import org.l2jmobius.commons.mmocore.SendablePacket;
import org.l2jmobius.loginserver.LoginClient;
/** /**
* @author KenM * @author Nos
*/ */
public abstract class LoginServerPacket extends SendablePacket<LoginClient> public interface IOutgoingPacket
{ {
/**
* @param packet the packet writer
* @return {@code true} if packet was writen successfully, {@code false} otherwise.
*/
boolean write(PacketWriter packet);
} }

View File

@@ -0,0 +1,76 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network;
import java.util.logging.Logger;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @author Nos
*/
public class NetworkManager
{
private static final Logger LOGGER = Logger.getLogger(NetworkManager.class.getName());
private final ServerBootstrap _serverBootstrap;
private final String _host;
private final int _port;
private ChannelFuture _channelFuture;
public NetworkManager(EventLoopGroup bossGroup, EventLoopGroup workerGroup, ChannelInitializer<SocketChannel> clientInitializer, String host, int port)
{
// @formatter:off
_serverBootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(clientInitializer)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
// @formatter:on
_host = host;
_port = port;
}
public ChannelFuture getChannelFuture()
{
return _channelFuture;
}
public void start() throws InterruptedException
{
if ((_channelFuture != null) && !_channelFuture.isDone())
{
return;
}
_channelFuture = _serverBootstrap.bind(_host.equals("*") ? "0.0.0.0" : _host, _port).sync();
LOGGER.info(getClass().getSimpleName() + ": Listening on " + _host + ":" + _port);
}
public void stop() throws InterruptedException
{
_channelFuture.channel().close().sync();
}
}

View File

@@ -0,0 +1,163 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network;
import io.netty.buffer.ByteBuf;
/**
* @author Nos
*/
public class PacketReader
{
private final ByteBuf _buf;
public PacketReader(ByteBuf buf)
{
_buf = buf;
}
/**
* Gets the readable bytes.
* @return the readable bytes
*/
public int getReadableBytes()
{
return _buf.readableBytes();
}
/**
* Reads an unsigned byte.
* @return the unsigned byte
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 1}
*/
public short readC()
{
return _buf.readUnsignedByte();
}
/**
* Reads an unsigned short.
* @return the unsigned short
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 2}
*/
public int readH()
{
return _buf.readUnsignedShortLE();
}
/**
* Reads an integer.
* @return the integer
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 4}
*/
public int readD()
{
return _buf.readIntLE();
}
/**
* Reads a long.
* @return the long
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 8}
*/
public long readQ()
{
return _buf.readLongLE();
}
/**
* Reads a float.
* @return the float
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 4}
*/
public float readE()
{
return Float.intBitsToFloat(_buf.readIntLE());
}
/**
* Reads a double.
* @return the double
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 8}
*/
public double readF()
{
return Double.longBitsToDouble(_buf.readLongLE());
}
/**
* Reads a string.
* @return the string
* @throws IndexOutOfBoundsException if string {@code null} terminator is not found within {@code readableBytes}
*/
public String readS()
{
final StringBuilder sb = new StringBuilder();
char chr;
while ((chr = Character.reverseBytes(_buf.readChar())) != 0)
{
sb.append(chr);
}
return sb.toString();
}
/**
* Reads a fixed length string.
* @return the string
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code 2 + String.length * 2}
*/
public String readString()
{
final StringBuilder sb = new StringBuilder();
final int stringLength = _buf.readShortLE();
if ((stringLength * 2) > _buf.readableBytes())
{
throw new IndexOutOfBoundsException("readerIndex(" + _buf.readerIndex() + ") + length(" + (stringLength * 2) + ") exceeds writerIndex(" + _buf.writerIndex() + "): " + _buf);
}
for (int i = 0; i < stringLength; i++)
{
sb.append(Character.reverseBytes(_buf.readChar()));
}
return sb.toString();
}
/**
* Reads a byte array.
* @param length the length
* @return the byte array
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code length}
*/
public byte[] readB(int length)
{
final byte[] result = new byte[length];
_buf.readBytes(result);
return result;
}
/**
* Reads a byte array.
* @param dst the destination
* @param dstIndex the destination index to start writing the bytes from
* @param length the length
* @throws IndexOutOfBoundsException if {@code readableBytes} is less than {@code length}, if the specified dstIndex is less than 0 or if {@code dstIndex + length} is greater than {@code dst.length}
*/
public void readB(byte[] dst, int dstIndex, int length)
{
_buf.readBytes(dst, dstIndex, length);
}
}

View File

@@ -0,0 +1,141 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network;
import io.netty.buffer.ByteBuf;
/**
* @author Nos
*/
public class PacketWriter
{
private final ByteBuf _buf;
public PacketWriter(ByteBuf buf)
{
_buf = buf;
}
/**
* Gets the writable bytes.
* @return the writable bytes
*/
public int getWritableBytes()
{
return _buf.writableBytes();
}
/**
* Writes a byte.
* @param value the byte (The 24 high-order bits are ignored)
*/
public void writeC(int value)
{
_buf.writeByte(value);
}
/**
* Writes a short.
* @param value the short (The 16 high-order bits are ignored)
*/
public void writeH(int value)
{
_buf.writeShortLE(value);
}
/**
* Writes an integer.
* @param value the integer
*/
public void writeD(int value)
{
_buf.writeIntLE(value);
}
/**
* Writes a long.
* @param value the long
*/
public void writeQ(long value)
{
_buf.writeLongLE(value);
}
/**
* Writes a float.
* @param value the float
*/
public void writeE(float value)
{
_buf.writeIntLE(Float.floatToIntBits(value));
}
/**
* Writes a double.
* @param value the double
*/
public void writeF(double value)
{
_buf.writeLongLE(Double.doubleToLongBits(value));
}
/**
* Writes a string.
* @param value the string
*/
public void writeS(String value)
{
if (value != null)
{
for (int i = 0; i < value.length(); i++)
{
_buf.writeChar(Character.reverseBytes(value.charAt(i)));
}
}
_buf.writeChar(0);
}
/**
* Writes a string with fixed length specified as [short length, char[length] data].
* @param value the string
*/
public void writeString(String value)
{
if (value != null)
{
_buf.writeShortLE(value.length());
for (int i = 0; i < value.length(); i++)
{
_buf.writeChar(Character.reverseBytes(value.charAt(i)));
}
}
else
{
_buf.writeShort(0);
}
}
/**
* Writes a byte array.
* @param bytes the byte array
*/
public void writeB(byte[] bytes)
{
_buf.writeBytes(bytes);
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network.codecs;
import java.util.List;
import org.l2jmobius.commons.network.ICrypt;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
/**
* @author Nos
*/
public class CryptCodec extends ByteToMessageCodec<ByteBuf>
{
private final ICrypt _crypt;
public CryptCodec(ICrypt crypt)
{
super();
_crypt = crypt;
}
/*
* (non-Javadoc)
* @see io.netty.handler.codec.ByteToMessageCodec#encode(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.buffer.ByteBuf)
*/
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out)
{
// Check if there are any data to encrypt.
if (!msg.isReadable())
{
return;
}
msg.resetReaderIndex();
_crypt.encrypt(msg);
msg.resetReaderIndex();
out.writeBytes(msg);
}
/*
* (non-Javadoc)
* @see io.netty.handler.codec.ByteToMessageCodec#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)
*/
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
{
in.resetReaderIndex();
_crypt.decrypt(in);
in.readerIndex(in.writerIndex());
out.add(in.copy(0, in.writerIndex()));
}
}

View File

@@ -14,33 +14,28 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.loginserver.network.clientpackets; package org.l2jmobius.commons.network.codecs;
import java.util.logging.Logger; import java.util.List;
import org.l2jmobius.commons.mmocore.ReceivablePacket; import io.netty.buffer.ByteBuf;
import org.l2jmobius.loginserver.LoginClient; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
/** /**
* @author KenM * @author Nos
*/ */
public abstract class LoginClientPacket extends ReceivablePacket<LoginClient> @Sharable
public class LengthFieldBasedFrameEncoder extends MessageToMessageEncoder<ByteBuf>
{ {
private static final Logger LOGGER = Logger.getLogger(LoginClientPacket.class.getName());
@Override @Override
protected final boolean read() protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
{ {
try final ByteBuf buf = ctx.alloc().buffer(2);
{ final short length = (short) (msg.readableBytes() + 2);
return readImpl(); buf.writeShortLE(length);
} out.add(buf);
catch (Exception e) out.add(msg.retain());
{
LOGGER.warning("ERROR READING: " + e);
return false;
}
} }
protected abstract boolean readImpl();
} }

View File

@@ -0,0 +1,91 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network.codecs;
import java.util.List;
import java.util.logging.Logger;
import org.l2jmobius.commons.network.IConnectionState;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.network.IIncomingPackets;
import org.l2jmobius.commons.network.PacketReader;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
/**
* @author Nos
* @param <T>
*/
public class PacketDecoder<T>extends ByteToMessageDecoder
{
private static final Logger LOGGER = Logger.getLogger(PacketDecoder.class.getName());
private final IIncomingPackets<T>[] _incomingPackets;
private final T _client;
public PacketDecoder(IIncomingPackets<T>[] incomingPackets, T client)
{
_incomingPackets = incomingPackets;
_client = client;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
{
if ((in == null) || !in.isReadable())
{
return;
}
try
{
final short packetId = in.readUnsignedByte();
if (packetId >= _incomingPackets.length)
{
LOGGER.finer("Unknown packet: " + Integer.toHexString(packetId));
return;
}
final IIncomingPackets<T> incomingPacket = _incomingPackets[packetId];
if (incomingPacket == null)
{
LOGGER.finer("Unknown packet: " + Integer.toHexString(packetId));
return;
}
final IConnectionState connectionState = ctx.channel().attr(IConnectionState.ATTRIBUTE_KEY).get();
if ((connectionState == null) || !incomingPacket.getConnectionStates().contains(connectionState))
{
// LOGGER.warning(incomingPacket + ": Connection at invalid state: " + connectionState + " Required States: " + incomingPacket.getConnectionStates());
return;
}
final IIncomingPacket<T> packet = incomingPacket.newIncomingPacket();
if ((packet != null) && packet.read(_client, new PacketReader(in)))
{
out.add(packet);
}
}
finally
{
// We always consider that we read whole packet.
in.readerIndex(in.writerIndex());
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.network.codecs;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.commons.network.IOutgoingPacket;
import org.l2jmobius.commons.network.PacketWriter;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
/**
* @author Nos
*/
@Sharable
public class PacketEncoder extends MessageToByteEncoder<IOutgoingPacket>
{
private static final Logger LOGGER = Logger.getLogger(PacketEncoder.class.getName());
private final int _maxPacketSize;
public PacketEncoder(int maxPacketSize)
{
super();
_maxPacketSize = maxPacketSize;
}
@Override
protected void encode(ChannelHandlerContext ctx, IOutgoingPacket packet, ByteBuf out)
{
try
{
if (packet.write(new PacketWriter(out)))
{
if (out.writerIndex() > _maxPacketSize)
{
throw new IllegalStateException("Packet (" + packet + ") size (" + out.writerIndex() + ") is bigger than the expected client limit (" + _maxPacketSize + ")");
}
}
else
{
// Avoid sending the packet
out.clear();
}
}
catch (Throwable e)
{
LOGGER.log(Level.WARNING, "Failed sending Packet(" + packet + ")", e);
// Avoid sending the packet if some exception happened
out.clear();
}
}
}

View File

@@ -1,30 +1,24 @@
/* /*
* This file is part of the L2J Mobius project. * This file is based on the Blowfish Engine that is part of the BouncyCastle JCE.
* Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* *
* This program is free software: you can redistribute it and/or modify * The above copyright notice and this permission notice shall be included in all copies
* it under the terms of the GNU General Public License as published by * or substantial portions of the Software.
* the Free Software Foundation, either version 3 of the License, or * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* (at your option) any later version. * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* This program is distributed in the hope that it will be useful, * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* 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 org.l2jmobius.commons.crypt; package org.l2jmobius.commons.util.crypt;
import java.io.IOException; import java.io.IOException;
/**
* This file is based on the Blowfish Engine that is part of the BouncyCastle JCE Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
public class BlowfishEngine public class BlowfishEngine
{ {
private static final int[] KP = private static final int[] KP =
@@ -1084,19 +1078,16 @@ public class BlowfishEngine
0x578FDFE3, 0x578FDFE3,
0x3AC372E6 0x3AC372E6
}; };
// ====================================
// Useful constants
// ====================================
private static final int ROUNDS = 16; private static final int ROUNDS = 16;
private static final int BLOCK_SIZE = 8; // bytes = 64 bits private static final int BLOCK_SIZE = 8; // bytes = 64 bits
private static final int SBOX_SK = 256; private static final int SBOX_SK = 256;
private static final int P_SZ = ROUNDS + 2; private static final int P_SZ = ROUNDS + 2;
private final int[] S0; // the s-boxes private final int[] S0; // the s-boxes
private final int[] S1; private final int[] S1; // the s-boxes
private final int[] S2; private final int[] S2; // the s-boxes
private final int[] S3; private final int[] S3; // the s-boxes
private final int[] P; // the p-array private final int[] P; // the p-array
private boolean encrypting = false;
private byte[] workingKey = null; private byte[] workingKey = null;
public BlowfishEngine() public BlowfishEngine()
@@ -1110,13 +1101,10 @@ public class BlowfishEngine
/** /**
* Initialize a Blowfish cipher. * Initialize a Blowfish cipher.
* @param pEncrypting whether or not we are for encryption. * @param key the key used to set up the cipher
* @param key the key used to set up the cipher.
* @exception IllegalArgumentException if the params argument is inappropriate.
*/ */
public void init(boolean pEncrypting, byte[] key) public void init(byte[] key)
{ {
encrypting = pEncrypting;
workingKey = key; workingKey = key;
setKey(workingKey); setKey(workingKey);
} }
@@ -1126,50 +1114,14 @@ public class BlowfishEngine
return "Blowfish"; return "Blowfish";
} }
public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws IOException
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialised");
}
if ((inOff + BLOCK_SIZE) > in.length)
{
throw new IOException("input buffer too short");
}
if ((outOff + BLOCK_SIZE) > out.length)
{
throw new IOException("output buffer too short");
}
if (encrypting)
{
encryptBlock(in, inOff, out, outOff);
}
else
{
decryptBlock(in, inOff, out, outOff);
}
return BLOCK_SIZE;
}
public void reset()
{
}
public int getBlockSize() public int getBlockSize()
{ {
return BLOCK_SIZE; return BLOCK_SIZE;
} }
// ==================================
// Private Implementation
// ==================================
private int func(int x) private int func(int x)
{ {
return ((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]; return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
} }
/** /**
@@ -1185,13 +1137,23 @@ public class BlowfishEngine
for (int s = 0; s < size; s += 2) for (int s = 0; s < size; s += 2)
{ {
xl ^= P[0]; xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2) xr ^= func(xl) ^ P[1];
{ xl ^= func(xr) ^ P[2];
xr ^= func(xl) ^ P[i]; xr ^= func(xl) ^ P[3];
xl ^= func(xr) ^ P[i + 1]; xl ^= func(xr) ^ P[4];
} xr ^= func(xl) ^ P[5];
xl ^= func(xr) ^ P[6];
xr ^= P[ROUNDS + 1]; xr ^= func(xl) ^ P[7];
xl ^= func(xr) ^ P[8];
xr ^= func(xl) ^ P[9];
xl ^= func(xr) ^ P[10];
xr ^= func(xl) ^ P[11];
xl ^= func(xr) ^ P[12];
xr ^= func(xl) ^ P[13];
xl ^= func(xr) ^ P[14];
xr ^= func(xl) ^ P[15];
xl ^= func(xr) ^ P[16];
xr ^= P[17];
table[s] = xr; table[s] = xr;
table[s + 1] = xl; table[s + 1] = xl;
xr = xl; // end of cycle swap xr = xl; // end of cycle swap
@@ -1201,16 +1163,19 @@ public class BlowfishEngine
private void setKey(byte[] key) private void setKey(byte[] key)
{ {
/* /**
* - comments are from _Applied Crypto_, Schneier, p338 please be careful comparing the two, AC numbers the arrays from 1, the enclosed code from 0. (1) Initialise the S-boxes and the P-array, with a fixed string This string contains the hexadecimal digits of pi (3.141...) * - comments are from _Applied Crypto_, Schneier, p338.<br>
* Please be careful comparing the two, AC numbers the arrays from 1, the enclosed code from 0.<br>
* (1) Initialize the S-boxes and the P-array, with a fixed string This string contains the hexadecimal digits of pi (3.141...)
*/ */
System.arraycopy(KS0, 0, S0, 0, SBOX_SK); System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
System.arraycopy(KS1, 0, S1, 0, SBOX_SK); System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
System.arraycopy(KS2, 0, S2, 0, SBOX_SK); System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
System.arraycopy(KS3, 0, S3, 0, SBOX_SK); System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
System.arraycopy(KP, 0, P, 0, P_SZ); System.arraycopy(KP, 0, P, 0, P_SZ);
/* /**
* (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the second 32-bits of the key, and so on for all bits of the key (up to P[17]). Repeatedly cycle through the key bits until the entire P-array has been XOR-ed with the key bits * (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the second 32-bits of the key, and so on for all bits of the key (up to P[17]).<br>
* Repeatedly cycle through the key bits until the entire P-array has been XOR-ed with the key bits
*/ */
final int keyLength = key.length; final int keyLength = key.length;
int keyIndex = 0; int keyIndex = 0;
@@ -1231,9 +1196,12 @@ public class BlowfishEngine
// XOR the newly created 32 bit chunk onto the P-array // XOR the newly created 32 bit chunk onto the P-array
P[i] ^= data; P[i] ^= data;
} }
/* /**
* (3) Encrypt the all-zero string with the Blowfish algorithm, using the subkeys described in (1) and (2) (4) Replace P1 and P2 with the output of step (3) (5) Encrypt the output of step(3) using the Blowfish algorithm, with the modified subkeys. (6) Replace P3 and P4 with the output of * (3) Encrypt the all-zero string with the Blowfish algorithm, using the subkeys described in (1) and (2)<br>
* step (5) (7) Continue the process, replacing all elements of the P-array and then all four S-boxes in order, with the output of the continuously changing Blowfish algorithm * (4) Replace P1 and P2 with the output of step (3)<br>
* (5) Encrypt the output of step(3) using the Blowfish algorithm, with the modified subkeys.<br>
* (6) Replace P3 and P4 with the output of step (5)<br>
* (7) Continue the process, replacing all elements of the P-array and then all four S-boxes in order, with the output of the continuously changing Blowfish algorithm
*/ */
processTable(0, 0, P); processTable(0, 0, P);
processTable(P[P_SZ - 2], P[P_SZ - 1], S0); processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
@@ -1243,61 +1211,246 @@ public class BlowfishEngine
} }
/** /**
* Encrypt the given input starting at the given offset and place the result in the provided buffer starting at the given offset. The input will be an exact multiple of our blocksize. * Method to encrypt the block at the given index.<br>
* @param src * The encrypted block goes directly to the source array at the given index.
* @param srcIndex * @param src source array with the plain data
* @param dst * @param srcIndex index where the block to encrypt is located
* @param dstIndex * @throws IllegalStateException The cipher was not yet initialized
* @throws IOException The source array is too small to hold a block at the given index
*/ */
private void encryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex) public void tryEncryptBlock(byte[] src, int srcIndex) throws IOException
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialized");
}
if ((srcIndex + BLOCK_SIZE) > src.length)
{
throw new IOException("input buffer too short");
}
encryptBlock(src, srcIndex);
}
/**
* Method to encrypt the block at the given index.<br>
* The encrypted block goes to the destination array at the given index.
* @param src source array with the plain data
* @param srcIndex index where the block to encrypt is located
* @param dst destination array the encryption will go to
* @param dstIndex index where the encrypted block is to be stored
* @throws IllegalStateException The cipher was not yet initialized
* @throws IOException The source or destination array is too small to hold a block at the given index
*/
public void tryEncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex) throws IOException
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialized");
}
if ((srcIndex + BLOCK_SIZE) > src.length)
{
throw new IOException("input buffer too short");
}
if ((dstIndex + BLOCK_SIZE) > dst.length)
{
throw new IOException("output buffer too short");
}
encryptBlock(src, srcIndex, dst, dstIndex);
}
/**
* Method to encrypt the block at the given index.<br>
* The encrypted block goes directly to the source array at the given<br>
* index.<br>
* <br>
* This method does not perform any error checking. This could be<br>
* usefull when code calling this method performs size checks already or<br>
* perfroming steps to ensure nothing can go wrong.<br>
* <br>
* If you want error checking use {@link #tryEncryptBlock(byte[], int)}.
* @param src source array with the plain data
* @param srcIndex index where the block to encrypt is located
*/
public void encryptBlock(byte[] src, int srcIndex)
{
encryptBlock(src, srcIndex, src, srcIndex);
}
/**
* Method to encrypt the block at the given index.<br>
* The encrypted block goes to the destination array at the given index.<br>
* <br>
* This method does not perform any error checking. This could be<br>
* usefull when code calling this method performs size checks already or<br>
* perfroming steps to ensure nothing can go wrong.<br>
* <br>
* If you want error checking use {@link #tryEncryptBlock(byte[], int, byte[], int)}.
* @param src source array with the plain data
* @param srcIndex index where the block to encrypt is located
* @param dst destination array the encryption will go to
* @param dstIndex index where the encrypted block is to be stored
*/
public void encryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{ {
int xl = bytesTo32bits(src, srcIndex); int xl = bytesTo32bits(src, srcIndex);
int xr = bytesTo32bits(src, srcIndex + 4); int xr = bytesTo32bits(src, srcIndex + 4);
xl ^= P[0]; xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2) xr ^= func(xl) ^ P[1];
{ xl ^= func(xr) ^ P[2];
xr ^= func(xl) ^ P[i]; xr ^= func(xl) ^ P[3];
xl ^= func(xr) ^ P[i + 1]; xl ^= func(xr) ^ P[4];
} xr ^= func(xl) ^ P[5];
xl ^= func(xr) ^ P[6];
xr ^= P[ROUNDS + 1]; xr ^= func(xl) ^ P[7];
xl ^= func(xr) ^ P[8];
xr ^= func(xl) ^ P[9];
xl ^= func(xr) ^ P[10];
xr ^= func(xl) ^ P[11];
xl ^= func(xr) ^ P[12];
xr ^= func(xl) ^ P[13];
xl ^= func(xr) ^ P[14];
xr ^= func(xl) ^ P[15];
xl ^= func(xr) ^ P[16];
xr ^= P[17];
bits32ToBytes(xr, dst, dstIndex); bits32ToBytes(xr, dst, dstIndex);
bits32ToBytes(xl, dst, dstIndex + 4); bits32ToBytes(xl, dst, dstIndex + 4);
} }
/** /**
* Decrypt the given input starting at the given offset and place the result in the provided buffer starting at the given offset. The input will be an exact multiple of our blocksize. * Method to decrypt the block at the given index.<br>
* @param src * The decrypted block goes directly to the source array at the given<br>
* @param srcIndex * index.
* @param dst * @param src source array with the encrypted data
* @param dstIndex * @param srcIndex index where the block to decrypt is located
* @throws IllegalStateException The cipher was not yet initialized
* @throws IOException The source array is too small to hold a block at the given index
*/ */
private void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex) public void tryDecryptBlock(byte[] src, int srcIndex) throws IOException
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialized");
}
if ((srcIndex + BLOCK_SIZE) > src.length)
{
throw new IOException("input buffer too short");
}
decryptBlock(src, srcIndex);
}
/**
* Method to decrypt the block at the given index.<br>
* The decrypted block goes to the destination array at the given index.<br>
* @param src source array with the plain data
* @param srcIndex index where the block to decrypt is located
* @param dst destination array the decryption will go to
* @param dstIndex index where the decrypted block is to be stored
* @throws IllegalStateException The cipher was not yet initialized
* @throws IOException The source or destination array is too small to hold a block at the given index
*/
public void tryDecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex) throws IOException
{
if (workingKey == null)
{
throw new IllegalStateException("Blowfish not initialized");
}
if ((srcIndex + BLOCK_SIZE) > src.length)
{
throw new IOException("input buffer too short");
}
if ((dstIndex + BLOCK_SIZE) > src.length)
{
throw new IOException("output buffer too short");
}
decryptBlock(src, srcIndex, dst, dstIndex);
}
/**
* Method to decrypt the block at the given index.<br>
* The decrypted block goes directly to the source array at the given<br>
* index.<br>
* <br>
* This method does not perform any error checking. This could be<br>
* usefull when code calling this method performs size checks already or<br>
* perfroming steps to ensure nothing can go wrong.<br>
* <br>
* If you want error checking use {@link #tryDecryptBlock(byte[], int)}.
* @param src source array with the encrypted data
* @param srcIndex index where the block to decrypt is located
*/
public void decryptBlock(byte[] src, int srcIndex)
{
decryptBlock(src, srcIndex, src, srcIndex);
}
/**
* Method to decrypt the block at the given index.<br>
* The decrypted block goes to the destination array at the given index.<br>
* <br>
* This method does not perform any error checking. This could be<br>
* usefull when code calling this method performs size checks already or<br>
* perfroming steps to ensure nothing can go wrong.<br>
* <br>
* If you want error checking use {@link #tryDecryptBlock(byte[], int, byte[], int)}.
* @param src source array with the plain data
* @param srcIndex index where the block to decrypt is located
* @param dst destination array the decryption will go to
* @param dstIndex index where the decrypted block is to be stored
* @throws IllegalStateException The cipher was not yet initialized
*/
public void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{ {
int xl = bytesTo32bits(src, srcIndex); int xl = bytesTo32bits(src, srcIndex);
int xr = bytesTo32bits(src, srcIndex + 4); int xr = bytesTo32bits(src, srcIndex + 4);
xl ^= P[ROUNDS + 1]; xl ^= P[17];
for (int i = ROUNDS; i > 0; i -= 2) xr ^= func(xl) ^ P[16];
{ xl ^= func(xr) ^ P[15];
xr ^= func(xl) ^ P[i]; xr ^= func(xl) ^ P[14];
xl ^= func(xr) ^ P[i - 1]; xl ^= func(xr) ^ P[13];
} xr ^= func(xl) ^ P[12];
xl ^= func(xr) ^ P[11];
xr ^= func(xl) ^ P[10];
xl ^= func(xr) ^ P[9];
xr ^= func(xl) ^ P[8];
xl ^= func(xr) ^ P[7];
xr ^= func(xl) ^ P[6];
xl ^= func(xr) ^ P[5];
xr ^= func(xl) ^ P[4];
xl ^= func(xr) ^ P[3];
xr ^= func(xl) ^ P[2];
xl ^= func(xr) ^ P[1];
xr ^= P[0]; xr ^= P[0];
bits32ToBytes(xr, dst, dstIndex); bits32ToBytes(xr, dst, dstIndex);
bits32ToBytes(xl, dst, dstIndex + 4); bits32ToBytes(xl, dst, dstIndex + 4);
} }
private int bytesTo32bits(byte[] b, int i) /**
* Method to construct an int from the source array.<br>
* 4 bytes are used from the given index.<br>
* <br>
* This method does not do any error checking.
* @param src source array with the bytes
* @param srcIndex the index to extract the int from
* @return the extracted integer
*/
private int bytesTo32bits(byte[] src, int srcIndex)
{ {
return ((b[i + 3] & 0xff) << 24) | ((b[i + 2] & 0xff) << 16) | ((b[i + 1] & 0xff) << 8) | (b[i] & 0xff); return ((src[srcIndex + 3] & 0xff) << 24) | ((src[srcIndex + 2] & 0xff) << 16) | ((src[srcIndex + 1] & 0xff) << 8) | (src[srcIndex] & 0xff);
} }
private void bits32ToBytes(int in, byte[] b, int offset) /**
* Method to decompose an int into a byte array.<br>
* <br>
* This method does not do any error checking.
* @param in the integer to decompose into bytes
* @param dst the destination array the decomposed int goes to
* @param dstIndex the index in the destination array the decomposed int will be stored at
*/
private void bits32ToBytes(int in, byte[] dst, int dstIndex)
{ {
b[offset] = (byte) in; dst[dstIndex] = (byte) in;
b[offset + 1] = (byte) (in >> 8); dst[dstIndex + 1] = (byte) (in >> 8);
b[offset + 2] = (byte) (in >> 16); dst[dstIndex + 2] = (byte) (in >> 16);
b[offset + 3] = (byte) (in >> 24); dst[dstIndex + 3] = (byte) (in >> 24);
} }
} }

View File

@@ -0,0 +1,148 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.commons.util.crypt;
import javax.crypto.SecretKey;
import org.l2jmobius.commons.network.ICrypt;
import org.l2jmobius.commons.util.Rnd;
import io.netty.buffer.ByteBuf;
/**
* @author NosBit
*/
public class LoginCrypt implements ICrypt
{
private static final byte[] STATIC_BLOWFISH_KEY =
{
(byte) 0x6b,
(byte) 0x60,
(byte) 0xcb,
(byte) 0x5b,
(byte) 0x82,
(byte) 0xce,
(byte) 0x90,
(byte) 0xb1,
(byte) 0xcc,
(byte) 0x2b,
(byte) 0x6c,
(byte) 0x55,
(byte) 0x6c,
(byte) 0x6c,
(byte) 0x6c,
(byte) 0x6c
};
private static final BlowfishEngine STATIC_BLOWFISH_ENGINE = new BlowfishEngine();
static
{
STATIC_BLOWFISH_ENGINE.init(STATIC_BLOWFISH_KEY);
}
private final BlowfishEngine _blowfishEngine = new BlowfishEngine();
private boolean _static = true;
public LoginCrypt(SecretKey blowfishKey)
{
_blowfishEngine.init(blowfishKey.getEncoded());
}
/*
* (non-Javadoc)
* @see com.l2jserver.commons.network.ICrypt#encrypt(io.netty.buffer.ByteBuf)
*/
@Override
public void encrypt(ByteBuf buf)
{
// Checksum & XOR Key or Checksum only
buf.writeZero(_static ? 16 : 12);
// Padding
buf.writeZero(8 - (buf.readableBytes() % 8));
if (_static)
{
_static = false;
int key = Rnd.nextInt();
buf.skipBytes(4); // The first 4 bytes are ignored
while (buf.readerIndex() < (buf.writerIndex() - 8))
{
int data = buf.readIntLE();
key += data;
data ^= key;
buf.setIntLE(buf.readerIndex() - 4, data);
}
buf.setIntLE(buf.readerIndex(), key);
buf.resetReaderIndex();
final byte[] block = new byte[8];
while (buf.isReadable(8))
{
buf.readBytes(block);
STATIC_BLOWFISH_ENGINE.encryptBlock(block, 0);
buf.setBytes(buf.readerIndex() - block.length, block);
}
}
else
{
int checksum = 0;
while (buf.isReadable(8))
{
checksum ^= buf.readIntLE();
}
buf.setIntLE(buf.readerIndex(), checksum);
buf.resetReaderIndex();
final byte[] block = new byte[8];
while (buf.isReadable(8))
{
buf.readBytes(block);
_blowfishEngine.encryptBlock(block, 0);
buf.setBytes(buf.readerIndex() - block.length, block);
}
}
}
/*
* (non-Javadoc)
* @see com.l2jserver.commons.network.ICrypt#decrypt(io.netty.buffer.ByteBuf)
*/
@Override
public void decrypt(ByteBuf buf)
{
// Packet size must be multiple of 8
if ((buf.readableBytes() % 8) != 0)
{
buf.clear();
return;
}
final byte[] block = new byte[8];
while (buf.isReadable(8))
{
buf.readBytes(block);
_blowfishEngine.decryptBlock(block, 0);
buf.setBytes(buf.readerIndex() - block.length, block);
}
// TODO: verify checksum also dont forget!
}
}

View File

@@ -14,29 +14,27 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.commons.crypt; package org.l2jmobius.commons.util.crypt;
import java.io.IOException;
import java.util.logging.Logger;
/** /**
* @version $Revision: 1.3.4.1 $ $Date: 2005/03/27 15:30:09 $ * Class to use a blowfish cipher with ECB processing.<br>
* Static methods are present to append/check the checksum of<br>
* packets exchanged between the following partners:<br>
* Login Server <-> Game Client<br>
* Login Server <-> Game Server<br>
* Also a static method is provided for the initial xor encryption between Login Server <-> Game Client.
*/ */
public class NewCrypt public class NewCrypt
{ {
protected static final Logger LOGGER = Logger.getLogger(NewCrypt.class.getName()); private final BlowfishEngine _cipher;
BlowfishEngine _crypt;
BlowfishEngine _decrypt;
/** /**
* @param blowfishKey * @param blowfishKey
*/ */
public NewCrypt(byte[] blowfishKey) public NewCrypt(byte[] blowfishKey)
{ {
_crypt = new BlowfishEngine(); _cipher = new BlowfishEngine();
_crypt.init(true, blowfishKey); _cipher.init(blowfishKey);
_decrypt = new BlowfishEngine();
_decrypt.init(false, blowfishKey);
} }
public NewCrypt(String key) public NewCrypt(String key)
@@ -44,11 +42,24 @@ public class NewCrypt
this(key.getBytes()); this(key.getBytes());
} }
/**
* Equivalent to calling {@link #verifyChecksum(byte[], int, int)} with parameters (raw, 0, raw.length)
* @param raw data array to be verified
* @return true when the checksum of the data is valid, false otherwise
*/
public static boolean verifyChecksum(byte[] raw) public static boolean verifyChecksum(byte[] raw)
{ {
return verifyChecksum(raw, 0, raw.length); return verifyChecksum(raw, 0, raw.length);
} }
/**
* Method to verify the checksum of a packet received by login server from game client.<br>
* This is also used for game server <-> login server communication.
* @param raw data array to be verified
* @param offset at which offset to start verifying
* @param size number of bytes to verify
* @return true if the checksum of the data is valid, false otherwise
*/
public static boolean verifyChecksum(byte[] raw, int offset, int size) public static boolean verifyChecksum(byte[] raw, int offset, int size)
{ {
// check if size is multiple of 4 and if there is more then only the checksum // check if size is multiple of 4 and if there is more then only the checksum
@@ -80,11 +91,21 @@ public class NewCrypt
return check == chksum; return check == chksum;
} }
/**
* Equivalent to calling {@link #appendChecksum(byte[], int, int)} with parameters (raw, 0, raw.length)
* @param raw data array to compute the checksum from
*/
public static void appendChecksum(byte[] raw) public static void appendChecksum(byte[] raw)
{ {
appendChecksum(raw, 0, raw.length); appendChecksum(raw, 0, raw.length);
} }
/**
* Method to append packet checksum at the end of the packet.
* @param raw data array to compute the checksum from
* @param offset offset where to start in the data array
* @param size number of bytes to compute the checksum from
*/
public static void appendChecksum(byte[] raw, int offset, int size) public static void appendChecksum(byte[] raw, int offset, int size)
{ {
long chksum = 0; long chksum = 0;
@@ -114,7 +135,8 @@ public class NewCrypt
} }
/** /**
* Packet is first XOR encoded with <code>key</code> Then, the last 4 bytes are overwritten with the the XOR "key". Thus this assume that there is enough room for the key to fit without overwriting data. * Packet is first XOR encoded with <code>key</code> then, the last 4 bytes are overwritten with the the XOR "key".<br>
* Thus this assume that there is enough room for the key to fit without overwriting data.
* @param raw The raw bytes to be encrypted * @param raw The raw bytes to be encrypted
* @param key The 4 bytes (int) XOR key * @param key The 4 bytes (int) XOR key
*/ */
@@ -124,13 +146,14 @@ public class NewCrypt
} }
/** /**
* Packet is first XOR encoded with <code>key</code> Then, the last 4 bytes are overwritten with the the XOR "key". Thus this assume that there is enough room for the key to fit without overwriting data. * Packet is first XOR encoded with <code>key</code> then, the last 4 bytes are overwritten with the the XOR "key".<br>
* Thus this assume that there is enough room for the key to fit without overwriting data.
* @param raw The raw bytes to be encrypted * @param raw The raw bytes to be encrypted
* @param offset The begining of the data to be encrypted * @param offset The beginning of the data to be encrypted
* @param size Length of the data to be encrypted * @param size Length of the data to be encrypted
* @param key The 4 bytes (int) XOR key * @param key The 4 bytes (int) XOR key
*/ */
public static void encXORPass(byte[] raw, int offset, int size, int key) static void encXORPass(byte[] raw, int offset, int size, int key)
{ {
final int stop = size - 8; final int stop = size - 8;
int pos = 4 + offset; int pos = 4 + offset;
@@ -160,55 +183,36 @@ public class NewCrypt
raw[pos++] = (byte) ((ecx >> 24) & 0xFF); raw[pos++] = (byte) ((ecx >> 24) & 0xFF);
} }
public byte[] decrypt(byte[] raw) throws IOException /**
* Method to decrypt using Blowfish-Blockcipher in ECB mode.<br>
* The results will be directly placed inside {@code raw} array.<br>
* This method does not do any error checking, since the calling code<br>
* should ensure sizes.
* @param raw the data array to be decrypted
* @param offset the offset at which to start decrypting
* @param size the number of bytes to be decrypted
*/
public void decrypt(byte[] raw, int offset, int size)
{ {
final byte[] result = new byte[raw.length]; for (int i = offset; i < (offset + size); i += 8)
final int count = raw.length / 8;
for (int i = 0; i < count; i++)
{ {
_decrypt.processBlock(raw, i * 8, result, i * 8); _cipher.decryptBlock(raw, i);
} }
return result;
} }
public void decrypt(byte[] raw, int offset, int size) throws IOException /**
* Method to encrypt using Blowfish-Blockcipher in ECB mode.<br>
* The results will be directly placed inside {@code raw} array.<br>
* This method does not do any error checking, since the calling code should ensure sizes.
* @param raw the data array to be decrypted
* @param offset the offset at which to start decrypting
* @param size the number of bytes to be decrypted
*/
public void crypt(byte[] raw, int offset, int size)
{ {
final byte[] result = new byte[size]; for (int i = offset; i < (offset + size); i += 8)
final int count = size / 8;
for (int i = 0; i < count; i++)
{ {
_decrypt.processBlock(raw, offset + (i * 8), result, i * 8); _cipher.encryptBlock(raw, i);
} }
// TODO can the crypt and decrypt go direct to the array
System.arraycopy(result, 0, raw, offset, size);
}
public byte[] crypt(byte[] raw) throws IOException
{
final int count = raw.length / 8;
final byte[] result = new byte[raw.length];
for (int i = 0; i < count; i++)
{
_crypt.processBlock(raw, i * 8, result, i * 8);
}
return result;
}
public void crypt(byte[] raw, int offset, int size) throws IOException
{
final int count = size / 8;
final byte[] result = new byte[size];
for (int i = 0; i < count; i++)
{
_crypt.processBlock(raw, offset + (i * 8), result, i * 8);
}
// TODO can the crypt and decrypt go direct to the array
System.arraycopy(result, 0, raw, offset, size);
} }
} }

View File

@@ -14,16 +14,19 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.l2jmobius.commons.crypt; package org.l2jmobius.commons.util.crypt;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.Key;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.util.logging.Logger;
public class ScrambledKeyPair public class ScrambledKeyPair
{ {
public KeyPair _pair; private static final Logger LOGGER = Logger.getLogger(ScrambledKeyPair.class.getName());
public byte[] _scrambledModulus; private final KeyPair _pair;
private final byte[] _scrambledModulus;
public ScrambledKeyPair(KeyPair pPair) public ScrambledKeyPair(KeyPair pPair)
{ {
@@ -41,7 +44,6 @@ public class ScrambledKeyPair
System.arraycopy(scrambledMod, 1, temp, 0, 0x80); System.arraycopy(scrambledMod, 1, temp, 0, 0x80);
scrambledMod = temp; scrambledMod = temp;
} }
// step 1 : 0x4d-0x50 <-> 0x00-0x04 // step 1 : 0x4d-0x50 <-> 0x00-0x04
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
@@ -49,25 +51,38 @@ public class ScrambledKeyPair
scrambledMod[0x00 + i] = scrambledMod[0x4d + i]; scrambledMod[0x00 + i] = scrambledMod[0x4d + i];
scrambledMod[0x4d + i] = temp; scrambledMod[0x4d + i] = temp;
} }
// step 2 : xor first 0x40 bytes with last 0x40 bytes // step 2 : xor first 0x40 bytes with last 0x40 bytes
for (int i = 0; i < 0x40; i++) for (int i = 0; i < 0x40; i++)
{ {
scrambledMod[i] = (byte) (scrambledMod[i] ^ scrambledMod[0x40 + i]); scrambledMod[i] = (byte) (scrambledMod[i] ^ scrambledMod[0x40 + i]);
} }
// step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38 // step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
scrambledMod[0x0d + i] = (byte) (scrambledMod[0x0d + i] ^ scrambledMod[0x34 + i]); scrambledMod[0x0d + i] = (byte) (scrambledMod[0x0d + i] ^ scrambledMod[0x34 + i]);
} }
// step 4 : xor last 0x40 bytes with first 0x40 bytes // step 4 : xor last 0x40 bytes with first 0x40 bytes
for (int i = 0; i < 0x40; i++) for (int i = 0; i < 0x40; i++)
{ {
scrambledMod[0x40 + i] = (byte) (scrambledMod[0x40 + i] ^ scrambledMod[i]); scrambledMod[0x40 + i] = (byte) (scrambledMod[0x40 + i] ^ scrambledMod[i]);
} }
LOGGER.finer("Modulus was scrambled");
return scrambledMod; return scrambledMod;
} }
public byte[] getScrambledModulus()
{
return _scrambledModulus;
}
public Key getPrivateKey()
{
return _pair.getPrivate();
}
public Key getPublicKey()
{
return _pair.getPublic();
}
} }

View File

@@ -17,12 +17,10 @@
package org.l2jmobius.gameserver; package org.l2jmobius.gameserver;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Calendar; import java.util.Calendar;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -31,8 +29,6 @@ import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.commons.enums.ServerMode; import org.l2jmobius.commons.enums.ServerMode;
import org.l2jmobius.commons.mmocore.SelectorConfig;
import org.l2jmobius.commons.mmocore.SelectorThread;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.commons.util.DeadlockDetector; import org.l2jmobius.commons.util.DeadlockDetector;
import org.l2jmobius.commons.util.Util; import org.l2jmobius.commons.util.Util;
@@ -121,8 +117,8 @@ import org.l2jmobius.gameserver.model.siege.clanhalls.BanditStrongholdSiege;
import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle; import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle;
import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance; import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawn;
import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.ClientNetworkManager;
import org.l2jmobius.gameserver.network.GamePacketHandler; import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
import org.l2jmobius.gameserver.script.EventDroplist; import org.l2jmobius.gameserver.script.EventDroplist;
import org.l2jmobius.gameserver.script.faenor.FaenorScriptEngine; import org.l2jmobius.gameserver.script.faenor.FaenorScriptEngine;
import org.l2jmobius.gameserver.scripting.ScriptEngineManager; import org.l2jmobius.gameserver.scripting.ScriptEngineManager;
@@ -134,14 +130,16 @@ public class GameServer
{ {
private static final Logger LOGGER = Logger.getLogger(GameServer.class.getName()); private static final Logger LOGGER = Logger.getLogger(GameServer.class.getName());
private static SelectorThread<GameClient> _selectorThread;
private static LoginServerThread _loginThread;
private static GamePacketHandler _gamePacketHandler;
private static TelnetStatusThread _statusServer; private static TelnetStatusThread _statusServer;
private static GameServer INSTANCE; private static GameServer INSTANCE;
public static final Calendar dateTimeServerStarted = Calendar.getInstance(); public static final Calendar dateTimeServerStarted = Calendar.getInstance();
public long getUsedMemoryMB()
{
return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576;
}
public GameServer() throws Exception public GameServer() throws Exception
{ {
final long serverLoadStart = Chronos.currentTimeMillis(); final long serverLoadStart = Chronos.currentTimeMillis();
@@ -476,17 +474,6 @@ public class GameServer
{ {
PrecautionaryRestartManager.getInstance(); PrecautionaryRestartManager.getInstance();
} }
System.gc();
Util.printSection("Info");
LOGGER.info("Maximum Numbers of Connected Players: " + Config.MAXIMUM_ONLINE_USERS);
LOGGER.info("GameServer Started, free memory " + (((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory()) + Runtime.getRuntime().freeMemory()) / 1048576) + " Mb of " + (Runtime.getRuntime().maxMemory() / 1048576) + " Mb");
LOGGER.info("Used memory: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576) + " MB");
Util.printSection("Status");
LOGGER.info("Server Loaded in " + ((Chronos.currentTimeMillis() - serverLoadStart) / 1000) + " seconds.");
// Load telnet status // Load telnet status
Util.printSection("Telnet"); Util.printSection("Telnet");
if (Config.IS_TELNET_ENABLED) if (Config.IS_TELNET_ENABLED)
@@ -500,47 +487,24 @@ public class GameServer
} }
Util.printSection("Login"); Util.printSection("Login");
_loginThread = LoginServerThread.getInstance(); ClientNetworkManager.getInstance().start();
_loginThread.start();
final SelectorConfig sc = new SelectorConfig(); if (Boolean.getBoolean("newLoginServer"))
sc.MAX_READ_PER_PASS = Config.MMO_MAX_READ_PER_PASS;
sc.MAX_SEND_PER_PASS = Config.MMO_MAX_SEND_PER_PASS;
sc.SLEEP_TIME = Config.MMO_SELECTOR_SLEEP_TIME;
sc.HELPER_BUFFER_COUNT = Config.MMO_HELPER_BUFFER_COUNT;
_gamePacketHandler = new GamePacketHandler();
_selectorThread = new SelectorThread<>(sc, _gamePacketHandler, _gamePacketHandler, _gamePacketHandler);
InetAddress bindAddress = null;
if (!Config.GAMESERVER_HOSTNAME.equals("*"))
{ {
try LoginServerNetworkManager.getInstance().connect();
{ }
bindAddress = InetAddress.getByName(Config.GAMESERVER_HOSTNAME); else
} {
catch (UnknownHostException e1) LoginServerThread.getInstance().start();
{
LOGGER.warning("The GameServer bind address is invalid, using all avaliable IPs. Reason: " + e1);
}
} }
try System.gc();
{ final long totalMem = Runtime.getRuntime().maxMemory() / 1048576;
_selectorThread.openServerSocket(bindAddress, Config.PORT_GAME); LOGGER.info(getClass().getSimpleName() + ": Started, using " + getUsedMemoryMB() + " of " + totalMem + " MB total memory.");
} LOGGER.info(getClass().getSimpleName() + ": Maximum number of connected players is " + Config.MAXIMUM_ONLINE_USERS + ".");
catch (IOException e) LOGGER.info(getClass().getSimpleName() + ": Server loaded in " + ((Chronos.currentTimeMillis() - serverLoadStart) / 1000) + " seconds.");
{
LOGGER.severe("Failed to open server socket. Reason: " + e);
System.exit(1);
}
_selectorThread.start();
}
public static SelectorThread<GameClient> getSelectorThread() Toolkit.getDefaultToolkit().beep();
{
return _selectorThread;
} }
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception

View File

@@ -42,19 +42,19 @@ import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.ConnectionState;
import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.gameserverpackets.AuthRequest; import org.l2jmobius.gameserver.network.loginserverpackets.game.AuthRequest;
import org.l2jmobius.gameserver.network.gameserverpackets.BlowFishKey; import org.l2jmobius.gameserver.network.loginserverpackets.game.BlowFishKey;
import org.l2jmobius.gameserver.network.gameserverpackets.ChangeAccessLevel; import org.l2jmobius.gameserver.network.loginserverpackets.game.ChangeAccessLevel;
import org.l2jmobius.gameserver.network.gameserverpackets.GameServerBasePacket; import org.l2jmobius.gameserver.network.loginserverpackets.game.GameServerBasePacket;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerAuthRequest; import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerAuthRequest;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerInGame; import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerInGame;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerLogout; import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerLogout;
import org.l2jmobius.gameserver.network.gameserverpackets.ServerStatus; import org.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
import org.l2jmobius.gameserver.network.loginserverpackets.AuthResponse; import org.l2jmobius.gameserver.network.loginserverpackets.login.AuthResponse;
import org.l2jmobius.gameserver.network.loginserverpackets.InitLS; import org.l2jmobius.gameserver.network.loginserverpackets.login.InitLS;
import org.l2jmobius.gameserver.network.loginserverpackets.KickPlayer; import org.l2jmobius.gameserver.network.loginserverpackets.login.KickPlayer;
import org.l2jmobius.gameserver.network.loginserverpackets.LoginServerFail; import org.l2jmobius.gameserver.network.loginserverpackets.login.LoginServerFail;
import org.l2jmobius.gameserver.network.loginserverpackets.PlayerAuthResponse; import org.l2jmobius.gameserver.network.loginserverpackets.login.PlayerAuthResponse;
import org.l2jmobius.gameserver.network.serverpackets.AuthLoginFail; import org.l2jmobius.gameserver.network.serverpackets.AuthLoginFail;
import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo; import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
@@ -296,10 +296,10 @@ public class LoginServerThread extends Thread
{ {
final PlayerInGame pig = new PlayerInGame(par.getAccount()); final PlayerInGame pig = new PlayerInGame(par.getAccount());
sendPacket(pig); sendPacket(pig);
wcToRemove.gameClient.setState(ConnectionState.AUTHENTICATED); wcToRemove.gameClient.setConnectionState(ConnectionState.AUTHENTICATED);
wcToRemove.gameClient.setSessionId(wcToRemove.session); wcToRemove.gameClient.setSessionId(wcToRemove.session);
final CharSelectInfo cl = new CharSelectInfo(wcToRemove.account, wcToRemove.gameClient.getSessionId().playOkID1); final CharSelectInfo cl = new CharSelectInfo(wcToRemove.account, wcToRemove.gameClient.getSessionId().playOkID1);
wcToRemove.gameClient.getConnection().sendPacket(cl); wcToRemove.gameClient.sendPacket(cl);
wcToRemove.gameClient.setCharSelection(cl.getCharInfo()); wcToRemove.gameClient.setCharSelection(cl.getCharInfo());
} }
else else

View File

@@ -37,8 +37,10 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.olympiad.Olympiad; import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.sevensigns.SevenSigns; import org.l2jmobius.gameserver.model.sevensigns.SevenSigns;
import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival; import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival;
import org.l2jmobius.gameserver.network.ClientNetworkManager;
import org.l2jmobius.gameserver.network.EventLoopGroupManager;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.gameserverpackets.ServerStatus; import org.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -320,13 +322,16 @@ public class Shutdown extends Thread
{ {
} }
// saveData sends messages to exit players, so shutdown selector after it
try try
{ {
// GameServer.getSelectorThread().setDaemon(true); ClientNetworkManager.getInstance().stop();
GameServer.getSelectorThread().shutdown(); EventLoopGroupManager.getInstance().shutdown();
LOGGER.info("Game Server: Selector thread has been shut down.");
} }
catch (Throwable t) catch (Throwable t)
{ {
// ignore
} }
// stop all threadpolls // stop all threadpolls
@@ -530,7 +535,7 @@ public class Shutdown extends Thread
if (player.getClient() != null) if (player.getClient() != null)
{ {
player.getClient().sendPacket(ServerClose.STATIC_PACKET); player.getClient().sendPacket(ServerClose.STATIC_PACKET);
player.getClient().close(0); player.getClient().close(false);
player.getClient().setPlayer(null); player.getClient().setPlayer(null);
player.setClient(null); player.setClient(null);
} }

View File

@@ -201,11 +201,11 @@ public class OfflineTradeTable
PlayerInstance player = null; PlayerInstance player = null;
try try
{ {
final GameClient client = new GameClient(null); final GameClient client = new GameClient();
player = PlayerInstance.load(rs.getInt("charId")); player = PlayerInstance.load(rs.getInt("charId"));
client.setPlayer(player); client.setPlayer(player);
client.setAccountName(player.getAccountName()); client.setAccountName(player.getAccountName());
client.setState(ConnectionState.IN_GAME); client.setConnectionState(ConnectionState.IN_GAME);
player.setClient(client); player.setClient(client);
player.setOfflineMode(true); player.setOfflineMode(true);
player.setOnlineStatus(false); player.setOnlineStatus(false);

View File

@@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.model.AccessLevel;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/** /**
@@ -302,7 +302,7 @@ public class AdminData implements IXmlReader
} }
} }
public static void broadcastToGMs(GameServerPacket packet) public static void broadcastToGMs(IClientOutgoingPacket packet)
{ {
for (PlayerInstance gm : getInstance().getAllGms(true)) for (PlayerInstance gm : getInstance().getAllGms(true))
{ {

View File

@@ -71,7 +71,7 @@ public class AdminDisconnect implements IAdminCommandHandler
BuilderUtil.sendSysMessage(activeChar, "Character " + player.getName() + " disconnected from server."); BuilderUtil.sendSysMessage(activeChar, "Character " + player.getName() + " disconnected from server.");
// Logout Character // Logout Character
player.sendPacket(new LeaveWorld()); player.sendPacket(LeaveWorld.STATIC_PACKET);
player.closeNetConnection(); player.closeNetConnection();
} }
} }

View File

@@ -1195,12 +1195,12 @@ public class AdminEditChar implements IAdminCommandHandler
final Map<String, Integer> dualboxIPs = new HashMap<>(); final Map<String, Integer> dualboxIPs = new HashMap<>();
for (PlayerInstance player : players) for (PlayerInstance player : players)
{ {
if ((player.getClient() == null) || (player.getClient().getConnection() == null) || (player.getClient().getConnection().getInetAddress() == null) || (player.getClient().getConnection().getInetAddress().getHostAddress() == null)) if ((player.getClient() == null) || (player.getClient().getConnectionAddress() == null) || (player.getClient().getConnectionAddress() == null) || (player.getClient().getConnectionAddress().getHostAddress() == null))
{ {
continue; continue;
} }
ip = player.getClient().getConnection().getInetAddress().getHostAddress(); ip = player.getClient().getConnectionAddress().getHostAddress();
if (ipMap.get(ip) == null) if (ipMap.get(ip) == null)
{ {
ipMap.put(ip, new ArrayList<PlayerInstance>()); ipMap.put(ip, new ArrayList<PlayerInstance>());
@@ -1260,12 +1260,12 @@ public class AdminEditChar implements IAdminCommandHandler
for (PlayerInstance player : players) for (PlayerInstance player : players)
{ {
if ((player.getClient() == null) || (player.getClient().getConnection() == null) || (player.getClient().getConnection().getInetAddress() == null) || (player.getClient().getConnection().getInetAddress().getHostAddress() == null)) if ((player.getClient() == null) || (player.getClient().getConnectionAddress() == null) || (player.getClient().getConnectionAddress() == null) || (player.getClient().getConnectionAddress().getHostAddress() == null))
{ {
continue; continue;
} }
ip = player.getClient().getConnection().getInetAddress().getHostAddress(); ip = player.getClient().getConnectionAddress().getHostAddress();
if (ip.equals(ipAdress)) if (ip.equals(ipAdress))
{ {
name = player.getName(); name = player.getName();

View File

@@ -29,7 +29,7 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.Earthquake; import org.l2jmobius.gameserver.network.serverpackets.Earthquake;
import org.l2jmobius.gameserver.network.serverpackets.ExRedSky; import org.l2jmobius.gameserver.network.serverpackets.ExRedSky;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound; import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SignsSky; import org.l2jmobius.gameserver.network.serverpackets.SignsSky;
@@ -666,7 +666,7 @@ public class AdminEffects implements IAdminCommandHandler
*/ */
private void adminAtmosphere(String type, String state, PlayerInstance activeChar) private void adminAtmosphere(String type, String state, PlayerInstance activeChar)
{ {
GameServerPacket packet = null; IClientOutgoingPacket packet = null;
switch (type) switch (type)
{ {

View File

@@ -23,9 +23,7 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.itemcontainer.Inventory; import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.CharInfo;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
import org.l2jmobius.gameserver.util.BuilderUtil; import org.l2jmobius.gameserver.util.BuilderUtil;
import org.l2jmobius.gameserver.util.IllegalPlayerAction; import org.l2jmobius.gameserver.util.IllegalPlayerAction;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
@@ -219,8 +217,7 @@ public class AdminEnchant implements IAdminCommandHandler
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(itemInstance); iu.addModifiedItem(itemInstance);
player.sendPacket(iu); player.sendPacket(iu);
player.broadcastPacket(new CharInfo(player)); player.broadcastUserInfo();
player.sendPacket(new UserInfo(player));
// informations // informations
BuilderUtil.sendSysMessage(activeChar, "Changed enchantment of " + player.getName() + "'s " + itemInstance.getItem().getName() + " from " + curEnchant + " to " + ench + "."); BuilderUtil.sendSysMessage(activeChar, "Changed enchantment of " + player.getName() + "'s " + itemInstance.getItem().getName() + " from " + curEnchant + " to " + ench + ".");

View File

@@ -22,7 +22,7 @@ import org.l2jmobius.Config;
import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread;
import org.l2jmobius.gameserver.handler.IAdminCommandHandler; import org.l2jmobius.gameserver.handler.IAdminCommandHandler;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.gameserverpackets.ServerStatus; import org.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import org.l2jmobius.gameserver.util.BuilderUtil; import org.l2jmobius.gameserver.util.BuilderUtil;

View File

@@ -238,7 +238,7 @@ public class SummonFriend implements ISkillHandler
final ConfirmDlg confirm = new ConfirmDlg(SystemMessageId.S1_WISHES_TO_SUMMON_YOU_FROM_S2_DO_YOU_ACCEPT.getId()); final ConfirmDlg confirm = new ConfirmDlg(SystemMessageId.S1_WISHES_TO_SUMMON_YOU_FROM_S2_DO_YOU_ACCEPT.getId());
confirm.addString(activePlayer.getName()); confirm.addString(activePlayer.getName());
confirm.addZoneName(activePlayer.getX(), activePlayer.getY(), activePlayer.getZ()); confirm.addZoneName(activePlayer.getX(), activePlayer.getY(), activePlayer.getZ());
confirm.addTime(30000); confirm.addTime(30000, targetPlayer);
confirm.addRequesterId(activePlayer.getObjectId()); confirm.addRequesterId(activePlayer.getObjectId());
targetPlayer.sendPacket(confirm); targetPlayer.sendPacket(confirm);
} }

View File

@@ -31,7 +31,7 @@ import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -179,7 +179,7 @@ public class PetitionManager
return _type.toString().replace("_", " "); return _type.toString().replace("_", " ");
} }
public void sendPetitionerPacket(GameServerPacket responsePacket) public void sendPetitionerPacket(IClientOutgoingPacket responsePacket)
{ {
if ((_petitioner == null) || !_petitioner.isOnline()) if ((_petitioner == null) || !_petitioner.isOnline())
{ {
@@ -189,7 +189,7 @@ public class PetitionManager
_petitioner.sendPacket(responsePacket); _petitioner.sendPacket(responsePacket);
} }
public void sendResponderPacket(GameServerPacket responsePacket) public void sendResponderPacket(IClientOutgoingPacket responsePacket)
{ {
if ((_responder == null) || !_responder.isOnline()) if ((_responder == null) || !_responder.isOnline())
{ {

View File

@@ -29,7 +29,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import org.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC; import org.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC;
import org.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC; import org.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/** /**
@@ -147,7 +147,7 @@ public class CommandChannel
* Broadcast packet to every channel member * Broadcast packet to every channel member
* @param gsp * @param gsp
*/ */
public void broadcastToChannelMembers(GameServerPacket gsp) public void broadcastToChannelMembers(IClientOutgoingPacket gsp)
{ {
if ((_parties != null) && !_parties.isEmpty()) if ((_parties != null) && !_parties.isEmpty())
{ {

View File

@@ -176,7 +176,7 @@ public class MacroList
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.info("Player: " + _owner.getName() + " IP:" + _owner.getClient().getConnection().getInetAddress().getHostAddress() + " try to use bug with macros"); LOGGER.info("Player: " + _owner.getName() + " IP:" + _owner.getClient().getConnectionAddress().getHostAddress() + " trird to use bug with macros.");
LOGGER.warning("could not store macro: " + e); LOGGER.warning("could not store macro: " + e);
} }
} }

View File

@@ -41,7 +41,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import org.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC; import org.l2jmobius.gameserver.network.serverpackets.ExCloseMPCC;
import org.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC; import org.l2jmobius.gameserver.network.serverpackets.ExOpenMPCC;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.PartyMemberPosition; import org.l2jmobius.gameserver.network.serverpackets.PartyMemberPosition;
import org.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAdd; import org.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAdd;
import org.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAll; import org.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAll;
@@ -281,7 +281,7 @@ public class Party
* Broadcasts packet to every party member * Broadcasts packet to every party member
* @param msg * @param msg
*/ */
public void broadcastToPartyMembers(GameServerPacket msg) public void broadcastToPartyMembers(IClientOutgoingPacket msg)
{ {
for (PlayerInstance member : _members) for (PlayerInstance member : _members)
{ {
@@ -327,7 +327,7 @@ public class Party
* @param player * @param player
* @param msg * @param msg
*/ */
public void broadcastToPartyMembers(PlayerInstance player, GameServerPacket msg) public void broadcastToPartyMembers(PlayerInstance player, IClientOutgoingPacket msg)
{ {
for (PlayerInstance member : _members) for (PlayerInstance member : _members)
{ {

View File

@@ -19,7 +19,7 @@ package org.l2jmobius.gameserver.model;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.clientpackets.GameClientPacket; import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/** /**
@@ -34,7 +34,7 @@ public class Request
protected PlayerInstance _partner; protected PlayerInstance _partner;
protected boolean _isRequestor; protected boolean _isRequestor;
protected boolean _isAnswerer; protected boolean _isAnswerer;
protected GameClientPacket _requestPacket; protected IClientIncomingPacket _requestPacket;
public Request(PlayerInstance player) public Request(PlayerInstance player)
{ {
@@ -70,7 +70,7 @@ public class Request
* Set the packet incomed from requester. * Set the packet incomed from requester.
* @param packet * @param packet
*/ */
private synchronized void setRequestPacket(GameClientPacket packet) private synchronized void setRequestPacket(IClientIncomingPacket packet)
{ {
_requestPacket = packet; _requestPacket = packet;
} }
@@ -78,7 +78,7 @@ public class Request
/** /**
* @return the packet originally incomed from requester. * @return the packet originally incomed from requester.
*/ */
public GameClientPacket getRequestPacket() public IClientIncomingPacket getRequestPacket()
{ {
return _requestPacket; return _requestPacket;
} }
@@ -89,7 +89,7 @@ public class Request
* @param packet * @param packet
* @return * @return
*/ */
public synchronized boolean setRequest(PlayerInstance partner, GameClientPacket packet) public synchronized boolean setRequest(PlayerInstance partner, IClientIncomingPacket packet)
{ {
if (partner == null) if (partner == null)
{ {

View File

@@ -113,7 +113,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ChangeMoveType;
import org.l2jmobius.gameserver.network.serverpackets.ChangeWaitType; import org.l2jmobius.gameserver.network.serverpackets.ChangeWaitType;
import org.l2jmobius.gameserver.network.serverpackets.CharMoveToLocation; import org.l2jmobius.gameserver.network.serverpackets.CharMoveToLocation;
import org.l2jmobius.gameserver.network.serverpackets.ExOlympiadSpelledInfo; import org.l2jmobius.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.MagicEffectIcons; import org.l2jmobius.gameserver.network.serverpackets.MagicEffectIcons;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceld; import org.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceld;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched; import org.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
@@ -366,7 +366,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
getAttackByList().add(creature); getAttackByList().add(creature);
} }
public void broadcastPacket(GameServerPacket mov) public void broadcastPacket(IClientOutgoingPacket mov)
{ {
for (PlayerInstance player : getKnownList().getKnownPlayers().values()) for (PlayerInstance player : getKnownList().getKnownPlayers().values())
{ {
@@ -374,7 +374,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
} }
} }
public void broadcastPacket(GameServerPacket mov, int radius) public void broadcastPacket(IClientOutgoingPacket mov, int radius)
{ {
for (PlayerInstance player : getKnownList().getKnownPlayers().values()) for (PlayerInstance player : getKnownList().getKnownPlayers().values())
{ {
@@ -507,7 +507,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
* <li>PlayerInstance</li><br> * <li>PlayerInstance</li><br>
* @param mov the mov * @param mov the mov
*/ */
public void sendPacket(GameServerPacket mov) public void sendPacket(IClientOutgoingPacket mov)
{ {
// default implementation // default implementation
} }

View File

@@ -526,7 +526,7 @@ public class DoorInstance extends Creature
// Send a Server->Client packet MyTargetSelected to the PlayerInstance player // Send a Server->Client packet MyTargetSelected to the PlayerInstance player
player.sendPacket(new MyTargetSelected(getObjectId(), 0)); player.sendPacket(new MyTargetSelected(getObjectId(), 0));
player.sendPacket(new DoorStatusUpdate(this)); player.sendPacket(new DoorStatusUpdate(this, player));
// Send a Server->Client packet ValidateLocation to correct the NpcInstance position and heading on the client // Send a Server->Client packet ValidateLocation to correct the NpcInstance position and heading on the client
player.sendPacket(new ValidateLocation(this)); player.sendPacket(new ValidateLocation(this));
@@ -577,7 +577,7 @@ public class DoorInstance extends Creature
player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel())); player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel()));
if (isAutoAttackable(player)) if (isAutoAttackable(player))
{ {
player.sendPacket(new DoorStatusUpdate(this)); player.sendPacket(new DoorStatusUpdate(this, player));
} }
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
final StringBuilder html1 = new StringBuilder("<html><body><center><font color=\"LEVEL\">Door Information</font></center>"); final StringBuilder html1 = new StringBuilder("<html><body><center><font color=\"LEVEL\">Door Information</font></center>");
@@ -603,7 +603,7 @@ public class DoorInstance extends Creature
player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel())); player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel()));
if (isAutoAttackable(player)) if (isAutoAttackable(player))
{ {
player.sendPacket(new DoorStatusUpdate(this)); player.sendPacket(new DoorStatusUpdate(this, player));
} }
final NpcHtmlMessage reply = new NpcHtmlMessage(5); final NpcHtmlMessage reply = new NpcHtmlMessage(5);
@@ -627,10 +627,9 @@ public class DoorInstance extends Creature
return; return;
} }
final DoorStatusUpdate su = new DoorStatusUpdate(this);
for (PlayerInstance player : knownPlayers) for (PlayerInstance player : knownPlayers)
{ {
player.sendPacket(su); player.sendPacket(new DoorStatusUpdate(this, player));
} }
} }

View File

@@ -183,8 +183,8 @@ import org.l2jmobius.gameserver.network.serverpackets.ExOlympiadMode;
import org.l2jmobius.gameserver.network.serverpackets.ExOlympiadUserInfo; import org.l2jmobius.gameserver.network.serverpackets.ExOlympiadUserInfo;
import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo; import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo;
import org.l2jmobius.gameserver.network.serverpackets.FriendList; import org.l2jmobius.gameserver.network.serverpackets.FriendList;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket;
import org.l2jmobius.gameserver.network.serverpackets.HennaInfo; import org.l2jmobius.gameserver.network.serverpackets.HennaInfo;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.ItemList;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
@@ -644,7 +644,7 @@ public class PlayerInstance extends Playable
@Override @Override
public void doAttack(Creature target) public void doAttack(Creature target)
{ {
if (Creature.isInsidePeaceZone(PlayerInstance.this, target)) if (isInsidePeaceZone(PlayerInstance.this, target))
{ {
sendPacket(ActionFailed.STATIC_PACKET); sendPacket(ActionFailed.STATIC_PACKET);
return; return;
@@ -2076,7 +2076,7 @@ public class PlayerInstance extends Playable
setOverloaded(false); setOverloaded(false);
_curWeightPenalty = 0; _curWeightPenalty = 0;
super.removeSkill(getKnownSkill(4270)); super.removeSkill(getKnownSkill(4270));
Broadcast.toKnownPlayers(this, new CharInfo(this)); Broadcast.toKnownPlayers(this, new CharInfo(this, isGM() && getAppearance().isInvisible()));
} }
else else
{ {
@@ -2120,7 +2120,7 @@ public class PlayerInstance extends Playable
sendSkillList(); // Fix visual bug sendSkillList(); // Fix visual bug
} }
Broadcast.toKnownPlayers(this, new CharInfo(this)); Broadcast.toKnownPlayers(this, new CharInfo(this, isGM() && getAppearance().isInvisible()));
} }
} }
} }
@@ -4873,7 +4873,36 @@ public class PlayerInstance extends Playable
{ {
// Send a Server->Client packet UserInfo to this PlayerInstance // Send a Server->Client packet UserInfo to this PlayerInstance
sendPacket(new UserInfo(this)); sendPacket(new UserInfo(this));
Broadcast.toKnownPlayers(this, new CharInfo(this));
// Broadcast char info to known players
broadcastCharInfo();
}
public void broadcastCharInfo()
{
final CharInfo charInfo = new CharInfo(this, false);
for (PlayerInstance player : getKnownList().getKnownPlayers().values())
{
if (player == null)
{
continue;
}
try
{
if (player.isGM() && getAppearance().isInvisible())
{
player.sendPacket(new CharInfo(this, true));
}
else
{
player.sendPacket(charInfo);
}
}
catch (NullPointerException e)
{
}
}
} }
/** /**
@@ -4887,7 +4916,7 @@ public class PlayerInstance extends Playable
} }
@Override @Override
public void broadcastPacket(GameServerPacket mov) public void broadcastPacket(IClientOutgoingPacket mov)
{ {
final boolean isCharInfo = mov instanceof CharInfo; final boolean isCharInfo = mov instanceof CharInfo;
if (!isCharInfo) if (!isCharInfo)
@@ -4916,7 +4945,7 @@ public class PlayerInstance extends Playable
} }
@Override @Override
public void broadcastPacket(GameServerPacket mov, int radius) public void broadcastPacket(IClientOutgoingPacket mov, int radius)
{ {
final boolean isCharInfo = mov instanceof CharInfo; final boolean isCharInfo = mov instanceof CharInfo;
if (!isCharInfo) if (!isCharInfo)
@@ -6211,8 +6240,8 @@ public class PlayerInstance extends Playable
// Anti FARM same IP // Anti FARM same IP
if (Config.ANTI_FARM_IP_ENABLED && (_client != null) && (targetPlayer.getClient() != null)) if (Config.ANTI_FARM_IP_ENABLED && (_client != null) && (targetPlayer.getClient() != null))
{ {
final String ip1 = _client.getConnection().getInetAddress().getHostAddress(); final String ip1 = _client.getConnectionAddress().getHostAddress();
final String ip2 = targetPlayer.getClient().getConnection().getInetAddress().getHostAddress(); final String ip2 = targetPlayer.getClient().getConnectionAddress().getHostAddress();
if (ip1.equals(ip2)) if (ip1.equals(ip2))
{ {
sendMessage("Farm is punishable with Ban! GM informed."); sendMessage("Farm is punishable with Ban! GM informed.");
@@ -6232,9 +6261,9 @@ public class PlayerInstance extends Playable
private void addItemReward(PlayerInstance targetPlayer) private void addItemReward(PlayerInstance targetPlayer)
{ {
// IP check // IP check
if ((targetPlayer.getClient() != null) && (targetPlayer.getClient().getConnection() != null)) if ((targetPlayer.getClient() != null) && (targetPlayer.getClient().getConnectionAddress() != null))
{ {
if (targetPlayer.getClient().getConnection().getInetAddress() != _client.getConnection().getInetAddress()) if (targetPlayer.getClient().getConnectionAddress() != _client.getConnectionAddress())
{ {
if ((targetPlayer.getKarma() > 0) || (targetPlayer.getPvpFlag() > 0)) // killing target pk or in pvp if ((targetPlayer.getKarma() > 0) || (targetPlayer.getPvpFlag() > 0)) // killing target pk or in pvp
{ {
@@ -11240,7 +11269,7 @@ public class PlayerInstance extends Playable
* Send a Server->Client packet StatusUpdate to the PlayerInstance. * Send a Server->Client packet StatusUpdate to the PlayerInstance.
*/ */
@Override @Override
public void sendPacket(GameServerPacket packet) public void sendPacket(IClientOutgoingPacket packet)
{ {
if (_client != null) if (_client != null)
{ {
@@ -14886,12 +14915,12 @@ public class PlayerInstance extends Playable
boolean canMultiBox = true; boolean canMultiBox = true;
int boxCount = 1; int boxCount = 1;
final List<String> activeBoxes = new ArrayList<>(); final List<String> activeBoxes = new ArrayList<>();
if ((_client != null) && (_client.getConnection() != null) && !_client.getConnection().isClosed() && (_client.getConnection().getInetAddress() != null)) if ((_client != null) && (_client.getConnectionAddress() != null) && !_client.isDetached() && (_client.getConnectionAddress() != null))
{ {
final String playerIP = _client.getConnection().getInetAddress().getHostAddress(); final String playerIP = _client.getConnectionAddress().getHostAddress();
for (PlayerInstance player : World.getInstance().getAllPlayers()) for (PlayerInstance player : World.getInstance().getAllPlayers())
{ {
if ((player != null) && (player != this) && player.isOnline() && (player.getClient() != null) && (player.getClient().getConnection() != null) && !player.getClient().getConnection().isClosed() && (player.getClient().getConnection().getInetAddress() != null) && playerIP.equals(player.getClient().getConnection().getInetAddress().getHostAddress())) if ((player != null) && (player != this) && player.isOnline() && (player.getClient() != null) && (player.getClient().getConnectionAddress() != null) && !player.getClient().isDetached() && (player.getClient().getConnectionAddress() != null) && playerIP.equals(player.getClient().getConnectionAddress().getHostAddress()))
{ {
boxCount++; boxCount++;
activeBoxes.add(player.getName()); activeBoxes.add(player.getName());
@@ -14923,12 +14952,12 @@ public class PlayerInstance extends Playable
*/ */
public void refreshOtherBoxes() public void refreshOtherBoxes()
{ {
if ((_client != null) && (_client.getConnection() != null) && !_client.getConnection().isClosed() && (_client.getConnection().getInetAddress() != null)) if ((_client != null) && (_client.getConnectionAddress() != null) && !_client.isDetached() && (_client.getConnectionAddress() != null))
{ {
final String playerIP = _client.getConnection().getInetAddress().getHostAddress(); final String playerIP = _client.getConnectionAddress().getHostAddress();
for (PlayerInstance player : World.getInstance().getAllPlayers()) for (PlayerInstance player : World.getInstance().getAllPlayers())
{ {
if ((player != null) && (player != this) && player.isOnline() && (player.getClient() != null) && (player.getClient().getConnection() != null) && !player.getClient().getConnection().isClosed() && !player.getName().equals(getName()) && playerIP.equals(player.getClient().getConnection().getInetAddress().getHostAddress())) if ((player != null) && (player != this) && player.isOnline() && (player.getClient() != null) && (player.getClient().getConnectionAddress() != null) && !player.getClient().isDetached() && !player.getName().equals(getName()) && playerIP.equals(player.getClient().getConnectionAddress().getHostAddress()))
{ {
player._activeBoxes = _activeBoxes; player._activeBoxes = _activeBoxes;
player._activeBoxCharacters = _activeBoxCharacters; player._activeBoxCharacters = _activeBoxCharacters;

View File

@@ -139,7 +139,7 @@ public class PlayerKnownList extends PlayableKnownList
{ {
activeChar.sendPacket(new DoorInfo((DoorInstance) object, false)); activeChar.sendPacket(new DoorInfo((DoorInstance) object, false));
} }
activeChar.sendPacket(new DoorStatusUpdate((DoorInstance) object)); activeChar.sendPacket(new DoorStatusUpdate((DoorInstance) object, activeChar));
} }
else if (object.isBoat()) else if (object.isBoat())
{ {
@@ -180,7 +180,7 @@ public class PlayerKnownList extends PlayableKnownList
if (otherPlayer.isInBoat()) if (otherPlayer.isInBoat())
{ {
otherPlayer.getPosition().setWorldPosition(otherPlayer.getBoat().getLocation()); otherPlayer.getPosition().setWorldPosition(otherPlayer.getBoat().getLocation());
activeChar.sendPacket(new CharInfo(otherPlayer)); activeChar.sendPacket(new CharInfo(otherPlayer, activeChar.isGM() && otherPlayer.getAppearance().isInvisible()));
final int relation = otherPlayer.getRelation(activeChar); final int relation = otherPlayer.getRelation(activeChar);
if ((otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null) && (otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation)) if ((otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null) && (otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation))
@@ -192,7 +192,7 @@ public class PlayerKnownList extends PlayableKnownList
} }
else else
{ {
activeChar.sendPacket(new CharInfo(otherPlayer)); activeChar.sendPacket(new CharInfo(otherPlayer, activeChar.isGM() && otherPlayer.getAppearance().isInvisible()));
final int relation = otherPlayer.getRelation(activeChar); final int relation = otherPlayer.getRelation(activeChar);
if ((otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null) && (otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation)) if ((otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null) && (otherPlayer.getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation))

View File

@@ -46,7 +46,7 @@ import org.l2jmobius.gameserver.model.itemcontainer.ItemContainer;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.ItemList;
import org.l2jmobius.gameserver.network.serverpackets.PledgeReceiveSubPledgeCreated; import org.l2jmobius.gameserver.network.serverpackets.PledgeReceiveSubPledgeCreated;
import org.l2jmobius.gameserver.network.serverpackets.PledgeShowInfoUpdate; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowInfoUpdate;
@@ -1125,7 +1125,7 @@ public class Clan
} }
} }
public void broadcastToOnlineAllyMembers(GameServerPacket packet) public void broadcastToOnlineAllyMembers(IClientOutgoingPacket packet)
{ {
if (_allyId == 0) if (_allyId == 0)
{ {
@@ -1141,7 +1141,7 @@ public class Clan
} }
} }
public void broadcastToOnlineMembers(GameServerPacket packet) public void broadcastToOnlineMembers(IClientOutgoingPacket packet)
{ {
for (ClanMember member : _members.values()) for (ClanMember member : _members.values())
{ {
@@ -1159,7 +1159,7 @@ public class Clan
} }
} }
public void broadcastToOtherOnlineMembers(GameServerPacket packet, PlayerInstance player) public void broadcastToOtherOnlineMembers(IClientOutgoingPacket packet, PlayerInstance player)
{ {
for (ClanMember member : _members.values()) for (ClanMember member : _members.values())
{ {

View File

@@ -46,8 +46,8 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.FortressSiegeInfo;
import org.l2jmobius.gameserver.network.serverpackets.RelationChanged; import org.l2jmobius.gameserver.network.serverpackets.RelationChanged;
import org.l2jmobius.gameserver.network.serverpackets.SiegeInfo;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.network.serverpackets.UserInfo; import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
@@ -784,7 +784,7 @@ public class FortSiege
*/ */
public void listRegisterClan(PlayerInstance player) public void listRegisterClan(PlayerInstance player)
{ {
player.sendPacket(new FortressSiegeInfo(getFort())); player.sendPacket(new SiegeInfo(getFort(), player));
} }
/** /**

View File

@@ -951,7 +951,7 @@ public class Siege
*/ */
public void listRegisterClan(PlayerInstance player) public void listRegisterClan(PlayerInstance player)
{ {
player.sendPacket(new SiegeInfo(getCastle())); player.sendPacket(new SiegeInfo(getCastle(), player));
} }
/** /**

View File

@@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/** /**
* Abstract base class for any zone type Handles basic operations * Abstract base class for any zone type Handles basic operations
@@ -331,7 +331,7 @@ public abstract class ZoneType
* Broadcasts packet to all players inside the zone * Broadcasts packet to all players inside the zone
* @param packet * @param packet
*/ */
public void broadcastPacket(GameServerPacket packet) public void broadcastPacket(IClientOutgoingPacket packet)
{ {
if (_characterList.isEmpty()) if (_characterList.isEmpty())
{ {

View File

@@ -0,0 +1,50 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import java.nio.ByteOrder;
import org.l2jmobius.commons.network.codecs.CryptCodec;
import org.l2jmobius.commons.network.codecs.LengthFieldBasedFrameEncoder;
import org.l2jmobius.commons.network.codecs.PacketDecoder;
import org.l2jmobius.commons.network.codecs.PacketEncoder;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
/**
* @author Nos
*/
public class ClientInitializer extends ChannelInitializer<SocketChannel>
{
private static final LengthFieldBasedFrameEncoder LENGTH_ENCODER = new LengthFieldBasedFrameEncoder();
private static final PacketEncoder PACKET_ENCODER = new PacketEncoder(0x8000 - 2);
@Override
protected void initChannel(SocketChannel ch)
{
final GameClient client = new GameClient();
ch.pipeline().addLast("length-decoder", new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 0x8000 - 2, 0, 2, -2, 2, false));
ch.pipeline().addLast("length-encoder", LENGTH_ENCODER);
ch.pipeline().addLast("crypt-codec", new CryptCodec(client.getCrypt()));
// ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
ch.pipeline().addLast("packet-decoder", new PacketDecoder<>(IncomingPackets.PACKET_ARRAY, client));
ch.pipeline().addLast("packet-encoder", PACKET_ENCODER);
ch.pipeline().addLast(client);
}
}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.NetworkManager;
/**
* @author Nos
*/
public class ClientNetworkManager extends NetworkManager
{
protected ClientNetworkManager()
{
super(EventLoopGroupManager.getInstance().getBossGroup(), EventLoopGroupManager.getInstance().getWorkerGroup(), new ClientInitializer(), Config.GAMESERVER_HOSTNAME, Config.PORT_GAME);
}
public static ClientNetworkManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final ClientNetworkManager INSTANCE = new ClientNetworkManager();
}
}

View File

@@ -16,13 +16,23 @@
*/ */
package org.l2jmobius.gameserver.network; package org.l2jmobius.gameserver.network;
import org.l2jmobius.commons.network.IConnectionState;
/** /**
* @author KenM * @author KenM
*/ */
public enum ConnectionState public enum ConnectionState implements IConnectionState
{ {
CONNECTED, CONNECTED,
DISCONNECTED,
CLOSING,
AUTHENTICATED, AUTHENTICATED,
ENTERING, ENTERING,
IN_GAME IN_GAME;
public static final ConnectionState[] ENTERING_AND_IN_GAME = new ConnectionState[]
{
ConnectionState.ENTERING,
ConnectionState.IN_GAME
};
} }

View File

@@ -0,0 +1,117 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import org.l2jmobius.commons.network.ICrypt;
import io.netty.buffer.ByteBuf;
/**
* @author KenM
*/
public class Crypt implements ICrypt
{
// private final GameClient _client;
private final byte[] _inKey = new byte[8];
private final byte[] _outKey = new byte[8];
private boolean _isEnabled;
public Crypt(GameClient client)
{
// _client = client;
}
public void setKey(byte[] key)
{
System.arraycopy(key, 0, _inKey, 0, 8);
System.arraycopy(key, 0, _outKey, 0, 8);
}
@Override
public void encrypt(ByteBuf buf)
{
if (!_isEnabled)
{
_isEnabled = true;
onPacketSent(buf);
return;
}
onPacketSent(buf);
int a = 0;
while (buf.isReadable())
{
final int b = buf.readByte() & 0xFF;
a = b ^ _outKey[(buf.readerIndex() - 1) & 7] ^ a;
buf.setByte(buf.readerIndex() - 1, a);
}
shiftKey(_outKey, buf.writerIndex());
}
@Override
public void decrypt(ByteBuf buf)
{
if (!_isEnabled)
{
onPacketReceive(buf);
return;
}
int a = 0;
while (buf.isReadable())
{
final int b = buf.readByte() & 0xFF;
buf.setByte(buf.readerIndex() - 1, b ^ _inKey[(buf.readerIndex() - 1) & 7] ^ a);
a = b;
}
shiftKey(_inKey, buf.writerIndex());
onPacketReceive(buf);
}
private void onPacketSent(ByteBuf buf)
{
final byte[] data = new byte[buf.writerIndex()];
buf.getBytes(0, data);
// EventDispatcher.getInstance().notifyEvent(new OnPacketSent(_client, data));
}
private void onPacketReceive(ByteBuf buf)
{
final byte[] data = new byte[buf.writerIndex()];
buf.getBytes(0, data);
// EventDispatcher.getInstance().notifyEvent(new OnPacketReceived(_client, data));
}
private void shiftKey(byte[] key, int size)
{
int old = key[0] & 0xff;
old |= (key[1] << 8) & 0xff00;
old |= (key[2] << 0x10) & 0xff0000;
old |= (key[3] << 0x18) & 0xff000000;
old += size;
key[0] = (byte) (old & 0xff);
key[1] = (byte) ((old >> 0x08) & 0xff);
key[2] = (byte) ((old >> 0x10) & 0xff);
key[3] = (byte) ((old >> 0x18) & 0xff);
}
}

View File

@@ -0,0 +1,56 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import org.l2jmobius.Config;
import io.netty.channel.nio.NioEventLoopGroup;
/**
* @author Nos
*/
public class EventLoopGroupManager
{
private final NioEventLoopGroup _bossGroup = new NioEventLoopGroup(1);
private final NioEventLoopGroup _workerGroup = new NioEventLoopGroup(Config.IO_PACKET_THREAD_CORE_SIZE);
public NioEventLoopGroup getBossGroup()
{
return _bossGroup;
}
public NioEventLoopGroup getWorkerGroup()
{
return _workerGroup;
}
public void shutdown()
{
_bossGroup.shutdownGracefully();
_workerGroup.shutdownGracefully();
}
public static EventLoopGroupManager getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final EventLoopGroupManager INSTANCE = new EventLoopGroupManager();
}
}

View File

@@ -0,0 +1,146 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
import org.l2jmobius.commons.network.IConnectionState;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.network.IIncomingPackets;
import org.l2jmobius.gameserver.network.clientpackets.AnswerJoinPartyRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestAskJoinPartyRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestAutoSoulShot;
import org.l2jmobius.gameserver.network.clientpackets.RequestChangePartyLeader;
import org.l2jmobius.gameserver.network.clientpackets.RequestDismissPartyRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestExAcceptJoinMPCC;
import org.l2jmobius.gameserver.network.clientpackets.RequestExAskJoinMPCC;
import org.l2jmobius.gameserver.network.clientpackets.RequestExEnchantSkill;
import org.l2jmobius.gameserver.network.clientpackets.RequestExEnchantSkillInfo;
import org.l2jmobius.gameserver.network.clientpackets.RequestExMPCCShowPartyMembersInfo;
import org.l2jmobius.gameserver.network.clientpackets.RequestExMagicSkillUseGround;
import org.l2jmobius.gameserver.network.clientpackets.RequestExOustFromMPCC;
import org.l2jmobius.gameserver.network.clientpackets.RequestExPledgeCrestLarge;
import org.l2jmobius.gameserver.network.clientpackets.RequestExSetPledgeCrestLarge;
import org.l2jmobius.gameserver.network.clientpackets.RequestExitPartyMatchingWaitingRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestGetBossRecord;
import org.l2jmobius.gameserver.network.clientpackets.RequestListPartyMatchingWaitingRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestManorList;
import org.l2jmobius.gameserver.network.clientpackets.RequestOlympiadMatchList;
import org.l2jmobius.gameserver.network.clientpackets.RequestOlympiadObserverEnd;
import org.l2jmobius.gameserver.network.clientpackets.RequestOustFromPartyRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestPCCafeCouponUse;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeMemberInfo;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeMemberPowerInfo;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgePowerGradeList;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeReorganizeMember;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeSetAcademyMaster;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeSetMemberPowerGrade;
import org.l2jmobius.gameserver.network.clientpackets.RequestPledgeWarList;
import org.l2jmobius.gameserver.network.clientpackets.RequestProcureCropList;
import org.l2jmobius.gameserver.network.clientpackets.RequestSetCrop;
import org.l2jmobius.gameserver.network.clientpackets.RequestSetSeed;
import org.l2jmobius.gameserver.network.clientpackets.RequestWithdrawPartyRoom;
import org.l2jmobius.gameserver.network.clientpackets.RequestWriteHeroWords;
/**
* @author Mobius
*/
public enum ExIncomingPackets implements IIncomingPackets<GameClient>
{
REQUEST_OUST_FROM_PARTY_ROOM(0x01, RequestOustFromPartyRoom::new, ConnectionState.IN_GAME),
REQUEST_DISMISS_PARTY_ROOM(0x02, RequestDismissPartyRoom::new, ConnectionState.IN_GAME),
REQUEST_WITHDRAW_PARTY_ROOM(0x03, RequestWithdrawPartyRoom::new, ConnectionState.IN_GAME),
REQUEST_CHANGE_PARTY_LEADER(0x04, RequestChangePartyLeader::new, ConnectionState.IN_GAME),
REQUEST_AUTO_SOUL_SHOT(0x05, RequestAutoSoulShot::new, ConnectionState.IN_GAME),
REQUEST_EX_ENCHANT_SKILL_INFO(0x06, RequestExEnchantSkillInfo::new, ConnectionState.IN_GAME),
REQUEST_EX_ENCHANT_SKILL(0x07, RequestExEnchantSkill::new, ConnectionState.IN_GAME),
REQUEST_MANOR_LIST(0x08, RequestManorList::new, ConnectionState.IN_GAME),
REQUEST_PROCURE_CROP_LIST(0x09, RequestProcureCropList::new, ConnectionState.IN_GAME),
REQUEST_SET_SEED(0x0A, RequestSetSeed::new, ConnectionState.IN_GAME),
REQUEST_SET_CROP(0x0B, RequestSetCrop::new, ConnectionState.IN_GAME),
REQUEST_WRITE_HERO_WORDS(0x0C, RequestWriteHeroWords::new, ConnectionState.IN_GAME),
REQUEST_EX_ASK_JOIN_MPCC(0x0D, RequestExAskJoinMPCC::new, ConnectionState.IN_GAME),
REQUEST_EX_ACCEPT_JOIN_MPCC(0x0E, RequestExAcceptJoinMPCC::new, ConnectionState.IN_GAME),
REQUEST_EX_OUST_FROM_MPCC(0x0F, RequestExOustFromMPCC::new, ConnectionState.IN_GAME),
REQUEST_EX_PLEDGE_CREST_LARGE(0x10, RequestExPledgeCrestLarge::new, ConnectionState.IN_GAME),
REQUEST_EX_SET_PLEDGE_CREST_LARGE(0x11, RequestExSetPledgeCrestLarge::new, ConnectionState.IN_GAME),
REQUEST_OLYMPIAD_OBSERVER_END(0x12, RequestOlympiadObserverEnd::new, ConnectionState.IN_GAME),
REQUEST_OLYMPIAD_MATCH_LIST(0x13, RequestOlympiadMatchList::new, ConnectionState.IN_GAME),
REQUEST_ASK_JOIN_PARTY_ROOM(0x14, RequestAskJoinPartyRoom::new, ConnectionState.IN_GAME),
ANSWER_JOIN_PARTY_ROOM(0x15, AnswerJoinPartyRoom::new, ConnectionState.IN_GAME),
REQUEST_LIST_PARTY_MATCHING_WAITING_ROOM(0x16, RequestListPartyMatchingWaitingRoom::new, ConnectionState.IN_GAME),
REQUEST_EXIT_PARTY_MATCHING_WAITING_ROOM(0x17, RequestExitPartyMatchingWaitingRoom::new, ConnectionState.IN_GAME),
REQUEST_GET_BOSS_RECORD(0x18, RequestGetBossRecord::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_SET_ACADEMY_MASTER(0x19, RequestPledgeSetAcademyMaster::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_POWER_GRADE_LIST(0x1A, RequestPledgePowerGradeList::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_MEMBER_POWER_INFO(0x1B, RequestPledgeMemberPowerInfo::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_SET_MEMBER_POWER_GRADE(0x1C, RequestPledgeSetMemberPowerGrade::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_MEMBER_INFO(0x1D, RequestPledgeMemberInfo::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_WAR_LIST(0x1E, RequestPledgeWarList::new, ConnectionState.IN_GAME),
REQUEST_PC_CAFE_COUPON_USE(0x20, RequestPCCafeCouponUse::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_REORGANIZE_MEMBER(0x24, RequestPledgeReorganizeMember::new, ConnectionState.IN_GAME),
REQUEST_EX_MPCC_SHOW_PARTY_MEMBERS_INFO(0x25, RequestExMPCCShowPartyMembersInfo::new, ConnectionState.IN_GAME),
REQUEST_EX_MAGIC_SKILL_USE_GROUND(0x2F, RequestExMagicSkillUseGround::new, ConnectionState.IN_GAME);
public static final ExIncomingPackets[] PACKET_ARRAY;
static
{
final short maxPacketId = (short) Arrays.stream(values()).mapToInt(IIncomingPackets::getPacketId).max().orElse(0);
PACKET_ARRAY = new ExIncomingPackets[maxPacketId + 1];
for (ExIncomingPackets incomingPacket : values())
{
PACKET_ARRAY[incomingPacket.getPacketId()] = incomingPacket;
}
}
private int _packetId;
private Supplier<IIncomingPacket<GameClient>> _incomingPacketFactory;
private Set<IConnectionState> _connectionStates;
ExIncomingPackets(int packetId, Supplier<IIncomingPacket<GameClient>> incomingPacketFactory, IConnectionState... connectionStates)
{
// packetId is an unsigned short
if (packetId > 0xFFFF)
{
throw new IllegalArgumentException("packetId must not be bigger than 0xFFFF");
}
_packetId = packetId;
_incomingPacketFactory = incomingPacketFactory != null ? incomingPacketFactory : () -> null;
_connectionStates = new HashSet<>(Arrays.asList(connectionStates));
}
@Override
public int getPacketId()
{
return _packetId;
}
@Override
public IIncomingPacket<GameClient> newIncomingPacket()
{
return _incomingPacketFactory.get();
}
@Override
public Set<IConnectionState> getConnectionStates()
{
return _connectionStates;
}
}

View File

@@ -17,25 +17,25 @@
package org.l2jmobius.gameserver.network; package org.l2jmobius.gameserver.network;
import java.net.InetAddress; import java.net.InetAddress;
import java.nio.ByteBuffer; import java.net.InetSocketAddress;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.commons.mmocore.MMOClient; import org.l2jmobius.commons.network.ChannelInboundHandler;
import org.l2jmobius.commons.mmocore.MMOConnection; import org.l2jmobius.commons.network.ICrypt;
import org.l2jmobius.commons.mmocore.ReceivablePacket; import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread;
import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.LoginServerThread.SessionKey;
@@ -53,15 +53,24 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.model.olympiad.Olympiad; import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.util.EventData; import org.l2jmobius.gameserver.util.EventData;
import org.l2jmobius.gameserver.util.FloodProtectors; import org.l2jmobius.gameserver.util.FloodProtectors;
public class GameClient extends MMOClient<MMOConnection<GameClient>> implements Runnable import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
/**
* Represents a client connected on Game Server.
* @author KenM
*/
public class GameClient extends ChannelInboundHandler<GameClient>
{ {
protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName()); protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName());
protected static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting");
private final static byte[] CRYPT_KEY = private final static byte[] CRYPT_KEY =
{ {
@@ -77,25 +86,104 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final FloodProtectors _floodProtectors = new FloodProtectors(this);
private final ReentrantLock _playerLock = new ReentrantLock(); private final ReentrantLock _playerLock = new ReentrantLock();
private final List<Integer> _charSlotMapping = new ArrayList<>(); private final Crypt _crypt;
private final ReentrantLock _queueLock = new ReentrantLock(); private InetAddress _addr;
private final ArrayBlockingQueue<ReceivablePacket<GameClient>> _packetQueue; private Channel _channel;
private final GameCrypt _crypt;
private ConnectionState _state;
private String _accountName; private String _accountName;
private SessionKey _sessionId; private SessionKey _sessionId;
private ScheduledFuture<?> _cleanupTask = null; private PlayerInstance _player;
private final List<Integer> _charSlotMapping = new ArrayList<>();
private volatile boolean _isDetached = false; private volatile boolean _isDetached = false;
private boolean _isAuthedGG; private boolean _isAuthedGG;
private int _protocolVersion; private int _protocolVersion;
protected PlayerInstance _player; private ScheduledFuture<?> _cleanupTask = null;
public GameClient(MMOConnection<GameClient> con) public GameClient()
{ {
super(con); _crypt = new Crypt(this);
_state = ConnectionState.CONNECTED; }
_crypt = new GameCrypt();
_packetQueue = new ArrayBlockingQueue<>(Config.CLIENT_PACKET_QUEUE_SIZE); @Override
public void channelActive(ChannelHandlerContext ctx)
{
super.channelActive(ctx);
setConnectionState(ConnectionState.CONNECTED);
final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
_addr = address.getAddress();
_channel = ctx.channel();
LOGGER_ACCOUNTING.finer("Client Connected: " + ctx.channel());
}
@Override
public void channelInactive(ChannelHandlerContext ctx)
{
LOGGER_ACCOUNTING.finer("Client Disconnected: " + ctx.channel());
LoginServerThread.getInstance().sendLogout(getAccountName());
if ((_player == null) || !_player.isInOfflineMode())
{
// no long running tasks here, do it async
try
{
ThreadPool.execute(new DisconnectTask());
}
catch (RejectedExecutionException e)
{
// server is closing
}
}
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, IIncomingPacket<GameClient> packet)
{
try
{
packet.run(this);
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Exception for: " + toString() + " on packet.run: " + packet.getClass().getSimpleName(), e);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
}
public void closeNow()
{
if (_channel != null)
{
_channel.close();
}
synchronized (this)
{
if (_cleanupTask != null)
{
cancelCleanup();
}
_cleanupTask = ThreadPool.schedule(new CleanupTask(), 0); // delayed?
}
}
public void close(IClientOutgoingPacket packet)
{
sendPacket(packet);
closeNow();
}
public void close(boolean toLoginScreen)
{
close(toLoginScreen ? ServerClose.STATIC_PACKET : LeaveWorld.STATIC_PACKET);
}
public Channel getChannel()
{
return _channel;
} }
public byte[] enableCrypt() public byte[] enableCrypt()
@@ -104,33 +192,13 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return CRYPT_KEY; return CRYPT_KEY;
} }
public ConnectionState getState() /**
* For loaded offline traders returns localhost address.
* @return cached connection IP address, for checking detached clients.
*/
public InetAddress getConnectionAddress()
{ {
return _state; return _addr;
}
public void setState(ConnectionState pState)
{
if (_state != pState)
{
_state = pState;
_packetQueue.clear();
}
}
@Override
public boolean decrypt(ByteBuffer buf, int size)
{
_crypt.decrypt(buf.array(), buf.position(), size);
return true;
}
@Override
public boolean encrypt(ByteBuffer buf, int size)
{
_crypt.encrypt(buf.array(), buf.position(), size);
buf.position(buf.position() + size);
return true;
} }
public PlayerInstance getPlayer() public PlayerInstance getPlayer()
@@ -152,16 +220,16 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return _playerLock; return _playerLock;
} }
public boolean isAuthedGG()
{
return _isAuthedGG;
}
public void setGameGuardOk(boolean value) public void setGameGuardOk(boolean value)
{ {
_isAuthedGG = value; _isAuthedGG = value;
} }
public boolean isAuthedGG()
{
return _isAuthedGG;
}
public void setAccountName(String pAccountName) public void setAccountName(String pAccountName)
{ {
_accountName = pAccountName; _accountName = pAccountName;
@@ -182,18 +250,26 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return _sessionId; return _sessionId;
} }
public void sendPacket(GameServerPacket gsp) public void sendPacket(IClientOutgoingPacket packet)
{ {
if (_isDetached) if (_isDetached || (packet == null))
{ {
return; return;
} }
if (getConnection() != null) // Write into the channel.
{ _channel.writeAndFlush(packet);
getConnection().sendPacket(gsp);
gsp.runImpl(); // Run packet implementation.
} packet.runImpl(_player);
}
/**
* @param smId
*/
public void sendPacket(SystemMessageId smId)
{
sendPacket(new SystemMessage(smId));
} }
public boolean isDetached() public boolean isDetached()
@@ -208,17 +284,17 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
/** /**
* Method to handle character deletion * Method to handle character deletion
* @param charslot * @param characterSlot
* @return a byte: * @return a byte:
* <li>-1: Error: No char was found for such charslot, caught exception, etc... * <li>-1: Error: No char was found for such charslot, caught exception, etc...
* <li>0: character is not member of any clan, proceed with deletion * <li>0: character is not member of any clan, proceed with deletion
* <li>1: character is member of a clan, but not clan leader * <li>1: character is member of a clan, but not clan leader
* <li>2: character is clan leader * <li>2: character is clan leader
*/ */
public byte markToDeleteChar(int charslot) public byte markToDeleteChar(int characterSlot)
{ {
final int objid = getObjectIdForSlot(charslot); final int objectId = getObjectIdForSlot(characterSlot);
if (objid < 0) if (objectId < 0)
{ {
return -1; return -1;
} }
@@ -228,7 +304,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
try (Connection con = DatabaseFactory.getConnection()) try (Connection con = DatabaseFactory.getConnection())
{ {
PreparedStatement statement = con.prepareStatement("SELECT clanId from characters WHERE charId=?"); PreparedStatement statement = con.prepareStatement("SELECT clanId from characters WHERE charId=?");
statement.setInt(1, objid); statement.setInt(1, objectId);
final ResultSet rs = statement.executeQuery(); final ResultSet rs = statement.executeQuery();
rs.next(); rs.next();
@@ -241,7 +317,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{ {
answer = 0; // jeezes! answer = 0; // jeezes!
} }
else if (clan.getLeaderId() == objid) else if (clan.getLeaderId() == objectId)
{ {
answer = 2; answer = 2;
} }
@@ -256,13 +332,13 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{ {
if (Config.DELETE_DAYS == 0) if (Config.DELETE_DAYS == 0)
{ {
deleteCharByObjId(objid); deleteCharByObjId(objectId);
} }
else else
{ {
statement = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?"); statement = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?");
statement.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000 statement.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000
statement.setInt(2, objid); statement.setInt(2, objectId);
statement.execute(); statement.execute();
statement.close(); statement.close();
rs.close(); rs.close();
@@ -283,11 +359,11 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return answer; return answer;
} }
public void markRestoredChar(int charslot) public void markRestoredChar(int characterSlot)
{ {
// have to make sure active character must be nulled // have to make sure active character must be nulled
final int objid = getObjectIdForSlot(charslot); final int objectId = getObjectIdForSlot(characterSlot);
if (objid < 0) if (objectId < 0)
{ {
return; return;
} }
@@ -295,7 +371,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
try (Connection con = DatabaseFactory.getConnection()) try (Connection con = DatabaseFactory.getConnection())
{ {
final PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?"); final PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?");
statement.setInt(1, objid); statement.setInt(1, objectId);
statement.execute(); statement.execute();
statement.close(); statement.close();
} }
@@ -305,97 +381,97 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
} }
} }
public static void deleteCharByObjId(int objid) public static void deleteCharByObjId(int objectId)
{ {
if (objid < 0) if (objectId < 0)
{ {
return; return;
} }
try (Connection con = DatabaseFactory.getConnection()) try (Connection con = DatabaseFactory.getConnection())
{ {
PreparedStatement statement; PreparedStatement ps;
statement = con.prepareStatement("DELETE FROM character_friends WHERE char_id=? OR friend_id=?"); ps = con.prepareStatement("DELETE FROM character_friends WHERE char_id=? OR friend_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.setInt(2, objid); ps.setInt(2, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_macroses WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_macroses WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_quests WHERE char_id=?"); ps = con.prepareStatement("DELETE FROM character_quests WHERE char_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?"); ps = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM character_subclasses WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM character_subclasses WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM heroes WHERE charId=?"); ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?"); ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM seven_signs WHERE char_obj_id=?"); ps = con.prepareStatement("DELETE FROM seven_signs WHERE char_obj_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)"); ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM items WHERE owner_id=?"); ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?"); ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
statement = con.prepareStatement("DELETE FROM characters WHERE charId=?"); ps = con.prepareStatement("DELETE FROM characters WHERE charId=?");
statement.setInt(1, objid); ps.setInt(1, objectId);
statement.execute(); ps.execute();
statement.close(); ps.close();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -403,31 +479,31 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
} }
} }
public PlayerInstance loadCharFromDisk(int charslot) public PlayerInstance loadCharFromDisk(int characterSlot)
{ {
final int objId = getObjectIdForSlot(charslot); final int objectId = getObjectIdForSlot(characterSlot);
if (objId < 0) if (objectId < 0)
{ {
return null; return null;
} }
PlayerInstance character = World.getInstance().getPlayer(objId); PlayerInstance player = World.getInstance().getPlayer(objectId);
if (character != null) if (player != null)
{ {
// exploit prevention, should not happens in normal way // exploit prevention, should not happens in normal way
LOGGER.warning("Attempt of double login: " + character.getName() + "(" + objId + ") " + _accountName); LOGGER.warning("Attempt of double login: " + player.getName() + "(" + objectId + ") " + _accountName);
if (character.getClient() != null) if (player.getClient() != null)
{ {
character.getClient().closeNow(); player.getClient().closeNow();
} }
else else
{ {
character.deleteMe(); player.deleteMe();
try try
{ {
character.store(); player.store();
} }
catch (Exception e2) catch (Exception e2)
{ {
@@ -436,8 +512,8 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
} }
} }
character = PlayerInstance.load(objId); player = PlayerInstance.load(objectId);
return character; return player;
} }
public void setCharSelection(CharSelectInfoPackage[] chars) public void setCharSelection(CharSelectInfoPackage[] chars)
@@ -451,14 +527,6 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
} }
} }
public void close(GameServerPacket gsp)
{
if (getConnection() != null)
{
getConnection().close(gsp);
}
}
private int getObjectIdForSlot(int charslot) private int getObjectIdForSlot(int charslot)
{ {
if ((charslot < 0) || (charslot >= _charSlotMapping.size())) if ((charslot < 0) || (charslot >= _charSlotMapping.size()))
@@ -471,55 +539,9 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return objectId.intValue(); return objectId.intValue();
} }
@Override
public void onForcedDisconnection()
{
// the force operation will allow to not save client position to prevent again criticals and stuck
closeNow();
}
@Override
public void onDisconnection()
{
// no long running tasks here, do it async
try
{
ThreadPool.execute(new DisconnectTask());
}
catch (RejectedExecutionException e)
{
// server is closing
}
}
/**
* Close client connection with {@link ServerClose} packet
*/
public void closeNow()
{
close(0);
}
/**
* Close client connection with {@link ServerClose} packet
* @param delay
*/
public void close(int delay)
{
close(ServerClose.STATIC_PACKET);
synchronized (this)
{
if (_cleanupTask != null)
{
cancelCleanup();
}
_cleanupTask = ThreadPool.schedule(new CleanupTask(), delay); // delayed
}
}
public String getIpAddress() public String getIpAddress()
{ {
final InetAddress address = getConnection().getInetAddress(); final InetAddress address = _addr;
String ip; String ip;
if (address == null) if (address == null)
{ {
@@ -540,20 +562,22 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{ {
try try
{ {
switch (_state) final InetAddress address = _addr;
final ConnectionState state = (ConnectionState) getConnectionState();
switch (state)
{ {
case CONNECTED: case CONNECTED:
{ {
return "[IP: " + getIpAddress() + "]"; return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
} }
case AUTHENTICATED: case AUTHENTICATED:
{ {
return "[Account: " + _accountName + " - IP: " + getIpAddress() + "]"; return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
} }
case ENTERING: case ENTERING:
case IN_GAME: case IN_GAME:
{ {
return "[Character: " + (_player == null ? "disconnected" : _player.getName()) + " - Account: " + _accountName + " - IP: " + getIpAddress() + "]"; return "[Character: " + (_player == null ? "disconnected" : _player.getName() + "[" + _player.getObjectId() + "]") + " - Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
} }
default: default:
{ {
@@ -777,72 +801,6 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return _isDetached; return _isDetached;
} }
/**
* Add packet to the queue and start worker thread if needed
* @param packet
*/
public void execute(ReceivablePacket<GameClient> packet)
{
if (!_packetQueue.offer(packet))
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if (_queueLock.isLocked())
{
return;
}
try
{
ThreadPool.execute(this);
}
catch (RejectedExecutionException e)
{
}
}
@Override
public void run()
{
if (!_queueLock.tryLock())
{
return;
}
try
{
while (true)
{
final ReceivablePacket<GameClient> packet = _packetQueue.poll();
if (packet == null)
{
return;
}
if (_isDetached) // clear queue immediately after detach
{
_packetQueue.clear();
return;
}
try
{
packet.run();
}
catch (Exception e)
{
LOGGER.warning("Exception during execution " + packet.getClass().getSimpleName() + ", client: " + this + "," + e.getMessage());
}
}
}
finally
{
_queueLock.unlock();
}
}
public void setProtocolVersion(int version) public void setProtocolVersion(int version)
{ {
_protocolVersion = version; _protocolVersion = version;
@@ -852,4 +810,9 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{ {
return _protocolVersion; return _protocolVersion;
} }
public ICrypt getCrypt()
{
return _crypt;
}
} }

View File

@@ -1,90 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
/**
* @author KenM
*/
public class GameCrypt
{
private final byte[] _inKey = new byte[8];
private final byte[] _outKey = new byte[8];
private boolean _isEnabled;
public void setKey(byte[] key)
{
System.arraycopy(key, 0, _inKey, 0, 8);
System.arraycopy(key, 0, _outKey, 0, 8);
}
public void decrypt(byte[] raw, int offset, int size)
{
if (!_isEnabled)
{
return;
}
int temp = 0;
for (int i = 0; i < size; i++)
{
final int temp2 = raw[offset + i] & 0xFF;
raw[offset + i] = (byte) (temp2 ^ _inKey[i & 7] ^ temp);
temp = temp2;
}
int old = _inKey[0] & 0xff;
old |= (_inKey[1] << 8) & 0xff00;
old |= (_inKey[2] << 0x10) & 0xff0000;
old |= (_inKey[3] << 0x18) & 0xff000000;
old += size;
_inKey[0] = (byte) (old & 0xff);
_inKey[1] = (byte) ((old >> 0x08) & 0xff);
_inKey[2] = (byte) ((old >> 0x10) & 0xff);
_inKey[3] = (byte) ((old >> 0x18) & 0xff);
}
public void encrypt(byte[] raw, int offset, int size)
{
if (!_isEnabled)
{
_isEnabled = true;
return;
}
int temp = 0;
for (int i = 0; i < size; i++)
{
final int temp2 = raw[offset + i] & 0xFF;
temp = temp2 ^ _outKey[i & 7] ^ temp;
raw[offset + i] = (byte) temp;
}
int old = _outKey[0] & 0xff;
old |= (_outKey[1] << 8) & 0xff00;
old |= (_outKey[2] << 0x10) & 0xff0000;
old |= (_outKey[3] << 0x18) & 0xff000000;
old += size;
_outKey[0] = (byte) (old & 0xff);
_outKey[1] = (byte) ((old >> 0x08) & 0xff);
_outKey[2] = (byte) ((old >> 0x10) & 0xff);
_outKey[3] = (byte) ((old >> 0x18) & 0xff);
}
}

View File

@@ -0,0 +1,239 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
import org.l2jmobius.commons.network.IConnectionState;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.network.IIncomingPackets;
import org.l2jmobius.gameserver.network.clientpackets.*;
/**
* @author Mobius
*/
public enum IncomingPackets implements IIncomingPackets<GameClient>
{
PROTOCOL_VERSION(0x00, ProtocolVersion::new, ConnectionState.CONNECTED),
AUTH_LOGIN(0x08, AuthLogin::new, ConnectionState.CONNECTED),
LOGOUT(0x09, Logout::new, ConnectionState.AUTHENTICATED, ConnectionState.IN_GAME),
CHARACTER_CREATE(0x0B, CharacterCreate::new, ConnectionState.AUTHENTICATED),
CHARACTER_DELETE(0x0C, CharacterDelete::new, ConnectionState.AUTHENTICATED),
CHARACTER_SELECT(0x0D, CharacterSelected::new, ConnectionState.AUTHENTICATED),
NEW_CHARACTER(0x0E, NewCharacter::new, ConnectionState.AUTHENTICATED),
CHARACTER_RESTORE(0x62, CharacterRestore::new, ConnectionState.AUTHENTICATED),
REQUEST_PLEDGE_CREST(0x68, RequestPledgeCrest::new, ConnectionState.AUTHENTICATED, ConnectionState.IN_GAME),
ENTER_WORLD(0x03, EnterWorld::new, ConnectionState.ENTERING),
MOVE_BACKWARD_TO_LOCATION(0x01, MoveBackwardToLocation::new, ConnectionState.IN_GAME),
ACTION(0x04, Action::new, ConnectionState.IN_GAME),
ATTACK_REQUEST(0x0A, AttackRequest::new, ConnectionState.IN_GAME),
REQUEST_ITEM_LIST(0x0F, RequestItemList::new, ConnectionState.IN_GAME),
REQUEST_UN_EQUIP_ITEM(0x11, RequestUnEquipItem::new, ConnectionState.IN_GAME),
REQUEST_DROP_ITEM(0x12, RequestDropItem::new, ConnectionState.IN_GAME),
USE_ITEM(0x14, UseItem::new, ConnectionState.IN_GAME),
TRADE_REQUEST(0x15, TradeRequest::new, ConnectionState.IN_GAME),
ADD_TRADE_ITEM(0x16, AddTradeItem::new, ConnectionState.IN_GAME),
TRADE_DONE(0x17, TradeDone::new, ConnectionState.IN_GAME),
REQUEST_SOCIAL_ACTION(0x1B, RequestSocialAction::new, ConnectionState.IN_GAME),
CHANGE_MOVE_TYPE2(0x1C, ChangeMoveType2::new, ConnectionState.IN_GAME),
CHANGE_WAIT_TYPE2(0x1D, ChangeWaitType2::new, ConnectionState.IN_GAME),
REQUEST_SELL_ITEM(0x1E, RequestSellItem::new, ConnectionState.IN_GAME),
REQUEST_BUY_ITEM(0x1F, RequestBuyItem::new, ConnectionState.IN_GAME),
REQUEST_LINK_HTML(0x20, RequestLinkHtml::new, ConnectionState.IN_GAME),
REQUEST_BYPASS_TO_SERVER(0x21, RequestBypassToServer::new, ConnectionState.IN_GAME),
REQUEST_B_B_SWRITE(0x22, RequestBBSwrite::new, ConnectionState.IN_GAME),
REQUEST_JOIN_PLEDGE(0x24, RequestJoinPledge::new, ConnectionState.IN_GAME),
REQUEST_ANSWER_JOIN_PLEDGE(0x25, RequestAnswerJoinPledge::new, ConnectionState.IN_GAME),
REQUEST_WITHDRAWAL_PLEDGE(0x26, RequestWithdrawalPledge::new, ConnectionState.IN_GAME),
REQUEST_OUST_PLEDGE_MEMBER(0x27, RequestOustPledgeMember::new, ConnectionState.IN_GAME),
REQUEST_JOIN_PARTY(0x29, RequestJoinParty::new, ConnectionState.IN_GAME),
REQUEST_ANSWER_JOIN_PARTY(0x2A, RequestAnswerJoinParty::new, ConnectionState.IN_GAME),
REQUEST_WITH_DRAWAL_PARTY(0x2B, RequestWithDrawalParty::new, ConnectionState.IN_GAME),
REQUEST_OUST_PARTY_MEMBER(0x2C, RequestOustPartyMember::new, ConnectionState.IN_GAME),
REQUEST_MAGIC_SKILL_USE(0x2F, RequestMagicSkillUse::new, ConnectionState.IN_GAME),
APPEARING(0x30, Appearing::new, ConnectionState.IN_GAME),
SEND_WARE_HOUSE_DEPOSIT_LIST(0x31, SendWareHouseDepositList::new, ConnectionState.IN_GAME),
SEND_WARE_HOUSE_WITH_DRAW_LIST(0x32, SendWareHouseWithDrawList::new, ConnectionState.IN_GAME),
REQUEST_SHORT_CUT_REG(0x33, RequestShortCutReg::new, ConnectionState.IN_GAME),
REQUEST_SHORT_CUT_DEL(0x35, RequestShortCutDel::new, ConnectionState.IN_GAME),
CANNOT_MOVE_ANYMORE(0x36, CannotMoveAnymore::new, ConnectionState.IN_GAME),
REQUEST_TARGET_CANCELD(0x37, RequestTargetCanceld::new, ConnectionState.IN_GAME),
SAY2(0x38, Say2::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_MEMBER_LIST(0x3C, RequestPledgeMemberList::new, ConnectionState.IN_GAME),
REQUEST_SKILL_LIST(0x3F, RequestSkillList::new, ConnectionState.IN_GAME),
MOVE_WITH_DELTA(0x41, MoveWithDelta::new, ConnectionState.IN_GAME),
REQUEST_GET_ON_VEHICLE(0x42, RequestGetOnVehicle::new, ConnectionState.IN_GAME),
REQUEST_GET_OFF_VEHICLE(0x43, RequestGetOffVehicle::new, ConnectionState.IN_GAME),
ANSWER_TRADE_REQUEST(0x44, AnswerTradeRequest::new, ConnectionState.IN_GAME),
REQUEST_ACTION_USE(0x45, RequestActionUse::new, ConnectionState.IN_GAME),
REQUEST_RESTART(0x46, RequestRestart::new, ConnectionState.IN_GAME),
REQUEST_SIEGE_INFO(0x47, RequestSiegeInfo::new, ConnectionState.IN_GAME),
VALIDATE_POSITION(0x48, ValidatePosition::new, ConnectionState.IN_GAME),
START_ROTATING(0x4A, StartRotating::new, ConnectionState.IN_GAME),
FINISH_ROTATING(0x4B, FinishRotating::new, ConnectionState.IN_GAME),
REQUEST_START_PLEDGE_WAR(0x4D, RequestStartPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_REPLY_START_PLEDGE_WAR(0x4E, RequestReplyStartPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_STOP_PLEDGE_WAR(0x4F, RequestStopPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_REPLY_STOP_PLEDGE_WAR(0x50, RequestReplyStopPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_SURRENDER_PLEDGE_WAR(0x51, RequestSurrenderPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_REPLY_SURRENDER_PLEDGE_WAR(0x52, RequestReplySurrenderPledgeWar::new, ConnectionState.IN_GAME),
REQUEST_SET_PLEDGE_CREST(0x53, RequestSetPledgeCrest::new, ConnectionState.IN_GAME),
REQUEST_GIVE_NICK_NAME(0x55, RequestGiveNickName::new, ConnectionState.IN_GAME),
REQUEST_SHOW_BOARD(0x57, RequestShowBoard::new, ConnectionState.IN_GAME),
REQUEST_ENCHANT_ITEM(0x58, RequestEnchantItem::new, ConnectionState.IN_GAME),
REQUEST_DESTROY_ITEM(0x59, RequestDestroyItem::new, ConnectionState.IN_GAME),
SEND_BYPASS_BUILD_CMD(0x5B, SendBypassBuildCmd::new, ConnectionState.IN_GAME),
REQUEST_MOVE_TO_LOCATION_IN_VEHICLE(0x5C, RequestMoveToLocationInVehicle::new, ConnectionState.IN_GAME),
CANNOT_MOVE_ANYMORE_IN_VEHICLE(0x5D, CannotMoveAnymoreInVehicle::new, ConnectionState.IN_GAME),
REQUEST_FRIEND_INVITE(0x5E, RequestFriendInvite::new, ConnectionState.IN_GAME),
REQUEST_ANSWER_FRIEND_INVITE(0x5F, RequestAnswerFriendInvite::new, ConnectionState.IN_GAME),
REQUEST_FRIEND_LIST(0x60, RequestFriendList::new, ConnectionState.IN_GAME),
REQUEST_FRIEND_DEL(0x61, RequestFriendDel::new, ConnectionState.IN_GAME),
REQUEST_QUEST_LIST(0x63, RequestQuestList::new, ConnectionState.IN_GAME),
REQUEST_QUEST_ABORT(0x64, RequestQuestAbort::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_INFO(0x66, RequestPledgeInfo::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_EXTENDED_INFO(0x67, RequestPledgeExtendedInfo::new, ConnectionState.IN_GAME),
REQUEST_SURRENDER_PERSONALLY(0x69, RequestSurrenderPersonally::new, ConnectionState.IN_GAME),
REQUEST_AQUIRE_SKILL_INFO(0x6B, RequestAquireSkillInfo::new, ConnectionState.IN_GAME),
REQUEST_AQUIRE_SKILL(0x6C, RequestAquireSkill::new, ConnectionState.IN_GAME),
REQUEST_RESTART_POINT(0x6D, RequestRestartPoint::new, ConnectionState.IN_GAME),
REQUEST_G_M_COMMAND(0x6E, RequestGMCommand::new, ConnectionState.IN_GAME),
REQUEST_PARTY_MATCH_CONFIG(0x6F, RequestPartyMatchConfig::new, ConnectionState.IN_GAME),
REQUEST_PARTY_MATCH_LIST(0x70, RequestPartyMatchList::new, ConnectionState.IN_GAME),
REQUEST_PARTY_MATCH_DETAIL(0x71, RequestPartyMatchDetail::new, ConnectionState.IN_GAME),
REQUEST_CRYSTALLIZE_ITEM(0x72, RequestCrystallizeItem::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_MANAGE_SELL(0x73, RequestPrivateStoreManageSell::new, ConnectionState.IN_GAME),
SET_PRIVATE_STORE_LIST_SELL(0x74, SetPrivateStoreListSell::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_QUIT_SELL(0x76, RequestPrivateStoreQuitSell::new, ConnectionState.IN_GAME),
SET_PRIVATE_STORE_MSG_SELL(0x77, SetPrivateStoreMsgSell::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_BUY(0x79, RequestPrivateStoreBuy::new, ConnectionState.IN_GAME),
REQUEST_TUTORIAL_LINK_HTML(0x7B, RequestTutorialLinkHtml::new, ConnectionState.IN_GAME),
REQUEST_TUTORIAL_PASS_CMD_TO_SERVER(0x7C, RequestTutorialPassCmdToServer::new, ConnectionState.IN_GAME),
REQUEST_TUTORIAL_QUESTION_MARK(0x7D, RequestTutorialQuestionMark::new, ConnectionState.IN_GAME),
REQUEST_TUTORIAL_CLIENT_EVENT(0x7E, RequestTutorialClientEvent::new, ConnectionState.IN_GAME),
REQUEST_PETITION(0x7F, RequestPetition::new, ConnectionState.IN_GAME),
REQUEST_PETITION_CANCEL(0x80, RequestPetitionCancel::new, ConnectionState.IN_GAME),
REQUEST_GM_LIST(0x81, RequestGmList::new, ConnectionState.IN_GAME),
REQUEST_JOIN_ALLY(0x82, RequestJoinAlly::new, ConnectionState.IN_GAME),
REQUEST_ANSWER_JOIN_ALLY(0x83, RequestAnswerJoinAlly::new, ConnectionState.IN_GAME),
ALLY_LEAVE(0x84, AllyLeave::new, ConnectionState.IN_GAME),
ALLY_DISMISS(0x85, AllyDismiss::new, ConnectionState.IN_GAME),
REQUEST_DISMISS_ALLY(0x86, RequestDismissAlly::new, ConnectionState.IN_GAME),
REQUEST_SET_ALLY_CREST(0x87, RequestSetAllyCrest::new, ConnectionState.IN_GAME),
REQUEST_ALLY_CREST(0x88, RequestAllyCrest::new, ConnectionState.IN_GAME),
REQUEST_CHANGE_PET_NAME(0x89, RequestChangePetName::new, ConnectionState.IN_GAME),
REQUEST_PET_USE_ITEM(0x8A, RequestPetUseItem::new, ConnectionState.IN_GAME),
REQUEST_GIVE_ITEM_TO_PET(0x8B, RequestGiveItemToPet::new, ConnectionState.IN_GAME),
REQUEST_GET_ITEM_FROM_PET(0x8C, RequestGetItemFromPet::new, ConnectionState.IN_GAME),
REQUEST_ALLY_INFO(0x8E, RequestAllyInfo::new, ConnectionState.IN_GAME),
REQUEST_PET_GET_ITEM(0x8F, RequestPetGetItem::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_MANAGE_BUY(0x90, RequestPrivateStoreManageBuy::new, ConnectionState.IN_GAME),
SET_PRIVATE_STORE_LIST_BUY(0x91, SetPrivateStoreListBuy::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_QUIT_BUY(0x93, RequestPrivateStoreQuitBuy::new, ConnectionState.IN_GAME),
SET_PRIVATE_STORE_MSG_BUY(0x94, SetPrivateStoreMsgBuy::new, ConnectionState.IN_GAME),
REQUEST_PRIVATE_STORE_SELL(0x96, RequestPrivateStoreSell::new, ConnectionState.IN_GAME),
REQUEST_PACKAGE_SENDABLE_ITEM_LIST(0x9E, RequestPackageSendableItemList::new, ConnectionState.IN_GAME),
REQUEST_PACKAGE_SEND(0x9F, RequestPackageSend::new, ConnectionState.IN_GAME),
REQUEST_BLOCK(0xA0, RequestBlock::new, ConnectionState.IN_GAME),
REQUEST_SIEGE_ATTACKER_LIST(0xA2, RequestSiegeAttackerList::new, ConnectionState.IN_GAME),
REQUEST_SIEGE_DEFENDER_LIST(0xA3, RequestSiegeDefenderList::new, ConnectionState.IN_GAME),
REQUEST_JOIN_SIEGE(0xA4, RequestJoinSiege::new, ConnectionState.IN_GAME),
REQUEST_CONFIRM_SIEGE_WAITING_LIST(0xA5, RequestConfirmSiegeWaitingList::new, ConnectionState.IN_GAME),
MULTI_SELL_CHOOSE(0xA7, MultiSellChoose::new, ConnectionState.IN_GAME),
REQUEST_USER_COMMAND(0xAA, RequestUserCommand::new, ConnectionState.IN_GAME),
SNOOP_QUIT(0xAB, SnoopQuit::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_BOOK_OPEN(0xAC, RequestRecipeBookOpen::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_BOOK_DESTROY(0xAD, RequestRecipeBookDestroy::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_ITEM_MAKE_INFO(0xAE, RequestRecipeItemMakeInfo::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_ITEM_MAKE_SELF(0xAF, RequestRecipeItemMakeSelf::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_MESSAGE_SET(0xB1, RequestRecipeShopMessageSet::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_LIST_SET(0xB2, RequestRecipeShopListSet::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_MANAGE_QUIT(0xB3, RequestRecipeShopManageQuit::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_MAKE_INFO(0xB5, RequestRecipeShopMakeInfo::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_MAKE_ITEM(0xB6, RequestRecipeShopMakeItem::new, ConnectionState.IN_GAME),
REQUEST_RECIPE_SHOP_MANAGE_PREV(0xB7, RequestRecipeShopManagePrev::new, ConnectionState.IN_GAME),
OBSERVER_RETURN(0xB8, ObserverReturn::new, ConnectionState.IN_GAME),
REQUEST_EVALUATE(0xB9, RequestEvaluate::new, ConnectionState.IN_GAME),
REQUEST_HENNA_LIST(0xBA, RequestHennaList::new, ConnectionState.IN_GAME),
REQUEST_HENNA_ITEM_INFO(0xBB, RequestHennaItemInfo::new, ConnectionState.IN_GAME),
REQUEST_HENNA_EQUIP(0xBC, RequestHennaEquip::new, ConnectionState.IN_GAME),
REQUEST_HENNA_REMOVE_LIST(0xBD, RequestHennaRemoveList::new, ConnectionState.IN_GAME),
REQUEST_HENNA_ITEM_REMOVE_INFO(0xBE, RequestHennaItemRemoveInfo::new, ConnectionState.IN_GAME),
REQUEST_HENNA_REMOVE(0xBF, RequestHennaRemove::new, ConnectionState.IN_GAME),
REQUEST_PLEDGE_POWER(0xC0, RequestPledgePower::new, ConnectionState.IN_GAME),
REQUEST_MAKE_MACRO(0xC1, RequestMakeMacro::new, ConnectionState.IN_GAME),
REQUEST_DELETE_MACRO(0xC2, RequestDeleteMacro::new, ConnectionState.IN_GAME),
REQUEST_BUY_PROCURE(0xC3, RequestBuyProcure::new, ConnectionState.IN_GAME),
REQUEST_BUY_SEED(0xC4, RequestBuySeed::new, ConnectionState.IN_GAME),
DLG_ANSWER(0xC5, DlgAnswer::new, ConnectionState.IN_GAME),
REQUEST_WEAR_ITEM(0xC6, RequestWearItem::new, ConnectionState.IN_GAME),
REQUEST_S_S_Q_STATUS(0xC7, RequestSSQStatus::new, ConnectionState.IN_GAME),
GAME_GUARD_REPLY(0xCA, GameGuardReply::new, ConnectionState.IN_GAME),
REQUEST_SEND_FRIEND_MSG(0xCC, RequestSendFriendMsg::new, ConnectionState.IN_GAME),
REQUEST_SHOW_MINI_MAP(0xCD, RequestShowMiniMap::new, ConnectionState.IN_GAME),
REQUEST_RECORD_INFO(0xCF, RequestRecordInfo::new, ConnectionState.IN_GAME),
EX_PACKET(0xD0, ExPacket::new, ConnectionState.values()); // This packet has its own connection state checking so we allow all of them
public static final IncomingPackets[] PACKET_ARRAY;
static
{
final short maxPacketId = (short) Arrays.stream(values()).mapToInt(IIncomingPackets::getPacketId).max().orElse(0);
PACKET_ARRAY = new IncomingPackets[maxPacketId + 1];
for (IncomingPackets incomingPacket : values())
{
PACKET_ARRAY[incomingPacket.getPacketId()] = incomingPacket;
}
}
private short _packetId;
private Supplier<IIncomingPacket<GameClient>> _incomingPacketFactory;
private Set<IConnectionState> _connectionStates;
IncomingPackets(int packetId, Supplier<IIncomingPacket<GameClient>> incomingPacketFactory, IConnectionState... connectionStates)
{
// packetId is an unsigned byte
if (packetId > 0xFF)
{
throw new IllegalArgumentException("packetId must not be bigger than 0xFF");
}
_packetId = (short) packetId;
_incomingPacketFactory = incomingPacketFactory != null ? incomingPacketFactory : () -> null;
_connectionStates = new HashSet<>(Arrays.asList(connectionStates));
}
@Override
public int getPacketId()
{
return _packetId;
}
@Override
public IIncomingPacket<GameClient> newIncomingPacket()
{
return _incomingPacketFactory.get();
}
@Override
public Set<IConnectionState> getConnectionStates()
{
return _connectionStates;
}
}

View File

@@ -0,0 +1,331 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network;
import org.l2jmobius.commons.network.PacketWriter;
/**
* @author Mobius
*/
public enum OutgoingPackets
{
// Packets
KEY_PACKET(0x00),
CHAR_MOVE_TO_LOCATION(0x01),
CHAR_INFO(0x03),
USER_INFO(0x04),
ATTACK(0x05),
DIE(0x06),
REVIVE(0x07),
SPAWN_ITEM(0x0B),
DROP_ITEM(0x0C),
GET_ITEM(0x0D),
STATUS_UPDATE(0x0E),
NPC_HTML_MESSAGE(0x0F),
SELL_LIST(0x10),
BUY_LIST(0x11),
DELETE_OBJECT(0x12),
CHAR_SELECT_INFO(0x13),
AUTH_LOGIN_FAIL(0x14),
CHAR_SELECTED(0x15),
NPC_INFO(0x16),
CHAR_TEMPLATES(0x17),
CHAR_CREATE_OK(0x19),
CHAR_CREATE_FAIL(0x1A),
ITEM_LIST(0x1B),
SUN_RISE(0x1C),
SUN_SET(0x1D),
TRADE_START(0x1E),
TRADE_OWN_ADD(0x20),
TRADE_OTHER_ADD(0x21),
SEND_TRADE_DONE(0x22),
CHAR_DELETE_OK(0x23),
CHAR_DELETE_FAIL(0x24),
ACTION_FAILED(0x25),
SERVER_CLOSE(0x26),
INVENTORY_UPDATE(0x27),
TELEPORT_TO_LOCATION(0x28),
TARGET_SELECTED(0x29),
TARGET_UNSELECTED(0x2A),
AUTO_ATTACK_START(0x2B),
AUTO_ATTACK_STOP(0x2C),
SOCIAL_ACTION(0x2D),
CHANGE_MOVE_TYPE(0x2E),
CHANGE_WAIT_TYPE(0x2F),
MANAGE_PLEDGE_POWER(0x30),
ASK_JOIN_PLEDGE(0x32),
JOIN_PLEDGE(0x33),
ASK_JOIN_PARTY(0x39),
JOIN_PARTY(0x3A),
WARE_HOUSE_DEPOSIT_LIST(0x41),
WARE_HOUSE_WITHDRAWAL_LIST(0x42),
SHORT_CUT_REGISTER(0x44),
SHORT_CUT_INIT(0x45),
STOP_MOVE(0x47),
MAGIC_SKILL_USE(0x48),
MAGIC_SKILL_CANCELD(0x49),
CREATURE_SAY(0x4A),
EQUIP_UPDATE(0x4B),
DOOR_INFO(0x4C),
DOOR_STATUS_UPDATE(0x4D),
PARTY_SMALL_WINDOW_ALL(0x4E),
PARTY_SMALL_WINDOW_ADD(0x4F),
PARTY_SMALL_WINDOW_DELETE_ALL(0x50),
PARTY_SMALL_WINDOW_DELETE(0x51),
PARTY_SMALL_WINDOW_UPDATE(0x52),
PLEDGE_SHOW_MEMBER_LIST_ALL(0x53),
PLEDGE_SHOW_MEMBER_LIST_UPDATE(0x54),
PLEDGE_SHOW_MEMBER_LIST_ADD(0x55),
PLEDGE_SHOW_MEMBER_LIST_DELETE(0x56),
SKILL_LIST(0x58),
VEHICLE_INFO(0x59),
VEHICLE_DEPARTURE(0x5A),
ON_VEHICLE_CHECK_LOCATION(0x5B),
GET_ON_VEHICLE(0x5C),
GET_OFF_VEHICLE(0x5D),
SEND_TRADE_REQUEST(0x5E),
RESTART_RESPONSE(0x5F),
MOVE_TO_PAWN(0x60),
VALIDATE_LOCATION(0x61),
BEGIN_ROTATION(0x62),
STOP_ROTATION(0x63),
SYSTEM_MESSAGE(0x64),
START_PLEDGE_WAR(0x65),
STOP_PLEDGE_WAR(0x67),
SURRENDER_PLEDGE_WAR(0x69),
PLEDGE_CREST(0x6C),
SETUP_GAUGE(0x6D),
SHOW_BOARD(0x6E),
CHOOSE_INVENTORY_ITEM(0x6F),
MOVE_TO_LOCATION_IN_VEHICLE(0x71),
STOP_MOVE_IN_VEHICLE(0x72),
VALIDATE_LOCATION_IN_VEHICLE(0x73),
TRADE_UPDATE(0x74),
TRADE_PRESS_OWN_OK(0x75),
MAGIC_SKILL_LAUNCHED(0x76),
TRADE_PRESS_OTHER_OK(0x7C),
ASK_JOIN_FRIEND(0x7D),
LEAVE_WORLD(0x7E),
MAGIC_EFFECT_ICONS(0x7F),
QUEST_LIST(0x80),
ENCHANT_RESULT(0x81),
PLEDGE_SHOW_MEMBER_LIST_DELETE_ALL(0x82),
PLEDGE_INFO(0x83),
RIDE(0x86),
PLEDGE_SHOW_INFO_UPDATE(0x88),
AQUIRE_SKILL_LIST(0x8A),
AQUIRE_SKILL_INFO(0x8B),
GM_VIEW_CHARACTER_INFO(0x8F),
GM_VIEW_PLEDGE_INFO(0x90),
GM_VIEW_SKILL_INFO(0x91),
GM_VIEW_QUEST_LIST(0x93),
GM_VIEW_ITEM_LIST(0x94),
GM_VIEW_WAREHOUSE_WITHDRAW_LIST(0x95),
PARTY_MATCH_LIST(0x96),
PARTY_MATCH_DETAIL(0x97),
PLAY_SOUND(0x98),
STATIC_OBJECT(0x99),
PRIVATE_STORE_MANAGE_LIST_SELL(0x9A),
PRIVATE_STORE_LIST_SELL(0x9B),
PRIVATE_STORE_MSG_SELL(0x9C),
SHOW_MINI_MAP(0x9D),
TUTORIAL_SHOW_HTML(0xA0),
TUTORIAL_SHOW_QUESTION_MARK(0xA1),
TUTORIAL_ENABLE_CLIENT_EVENT(0xA2),
TUTORIAL_CLOSE_HTML(0xA3),
MY_TARGET_SELECTED(0xA6),
PARTY_MEMBER_POSITION(0xA7),
ASK_JOIN_ALLY(0xA8),
ALLY_CREST(0xAE),
PET_STATUS_SHOW(0xB0),
PET_INFO(0xB1),
PET_ITEM_LIST(0xB2),
PET_INVENTORY_UPDATE(0xB3),
PET_STATUS_UPDATE(0xB5),
PET_DELETE(0xB6),
PRIVATE_STORE_MANAGE_LIST_BUY(0xB7),
PRIVATE_STORE_LIST_BUY(0xB8),
PRIVATE_STORE_MSG_BUY(0xB9),
SKILL_COOL_TIME(0xC1),
PACKAGE_TO_LIST(0xC2),
PACKAGE_SENDABLE_LIST(0xC3),
EARTHQUAKE(0xC4),
SPECIAL_CAMERA(0xC7),
NORMAL_CAMERA(0xC8),
SIEGE_INFO(0xC9),
SIEGE_ATTACKER_LIST(0xCA),
SIEGE_DEFENDER_LIST(0xCB),
TITLE_UPDATE(0xCC),
PLEDGE_STATUS_CHANGED(0xCD),
RELATION_CHANGED(0xCE),
MULTI_SELL_LIST(0xD0),
SET_SUMMON_REMAIN_TIME(0xD1),
DICE(0xD4),
SNOOP(0xD5),
RECIPE_BOOK_ITEM_LIST(0xD6),
RECIPE_ITEM_MAKE_INFO(0xD7),
RECIPE_SHOP_MANAGE_LIST(0xD8),
RECIPE_SHOP_SELL_LIST(0xD9),
RECIPE_SHOP_ITEM_INFO(0xDA),
RECIPE_SHOP_MSG(0xDB),
SHOW_CALCULATOR(0xDC),
MON_RACE_INFO(0xDD),
SHOW_TOWN_MAP(0xDE),
OBSERVATION_MODE(0xDF),
OBSERVATION_RETURN(0xE0),
CHAIR_SIT(0xE1),
HENNA_EQUIP_LIST(0xE2),
HENNA_ITEM_INFO(0xE3),
HENNA_INFO(0xE4),
HENNA_REMOVE_LIST(0xE5),
HENNA_ITEM_REMOVE_INFO(0xE6),
SEND_MACRO_LIST(0xE7),
BUY_LIST_SEED(0xE8),
SELL_LIST_PROCURE(0xE9),
GM_VIEW_HENNA_INFO(0xEA),
RADAR_CONTROL(0xEB),
CLIENT_SET_TIME(0xEC),
CONFIRM_DLG(0xED),
PARTY_SPELLED(0xEE),
WEAR_LIST(0xEF),
CAMERA_MODE(0xF1),
SHOW_XMAS_SEAL(0xF2),
ETC_STATUS_UPDATE(0xF3),
SHORT_BUFF_STATUS_UPDATE(0xF4),
SSQ_STATUS(0xF5),
CLAN_HALL_DECORATION(0xF7),
SIGNS_SKY(0xF8),
GAME_GUARD_QUERY(0xF9),
FRIEND_LIST(0xFA),
FRIEND_RECV_MSG(0xFD),
// ExPackets
EX_COLOSSEUM_FENCE_INFO(0xFE, 0x09),
EX_PARTY_ROOM_MEMBER(0xFE, 0x0E),
EX_CLOSE_PARTY_ROOM(0xFE, 0x0F),
EX_MANAGE_PARTY_ROOM_MEMBER(0xFE, 0x10),
EX_AUTO_SOUL_SHOT(0xFE, 0x12),
EX_FISHING_START(0xFE, 0x13),
EX_FISHING_END(0xFE, 0x14),
EX_FISHING_START_COMBAT(0xFE, 0x15),
EX_FISHING_HP_REGEN(0xFE, 0x16),
EX_ENCHANT_SKILL_LIST(0xFE, 0x17),
EX_ENCHANT_SKILL_INFO(0xFE, 0x18),
EX_QUEST_INFO(0xFE, 0x19),
EX_SHOW_QUEST_MARK(0xFE, 0x1A),
EX_SEND_MANOR_LIST(0xFE, 0x1B),
EX_SHOW_SEED_INFO(0xFE, 0x1C),
EX_SHOW_CROP_INFO(0xFE, 0x1D),
EX_SHOW_MANOR_DEFAULT_INFO(0xFE, 0x1E),
EX_SHOW_SEED_SETTING(0xFE, 0x1F),
EX_SHOW_CROP_SETTING(0xFE, 0x20),
EX_SHOW_SELL_CROP_LIST(0xFE, 0x21),
EX_SHOW_PROCURE_CROP_DETAIL(0xFE, 0x22),
EX_HERO_LIST(0xFE, 0x23),
EX_SERVER_PRIMITIVE(0xFE, 0x24),
EX_OPEN_MPCC(0xFE, 0x25),
EX_CLOSE_MPCC(0xFE, 0x26),
EX_ASK_JOIN_MPCC(0xFE, 0x27),
EX_PLEDGE_CREST_LARGE(0xFE, 0x28),
EX_OLYMPIAD_USER_INFO(0xFE, 0x29),
EX_OLYMPIAD_SPELLED_INFO(0xFE, 0x2A),
EX_OLYMPIAD_MODE(0xFE, 0x2B),
EX_MAIL_ARRIVED(0xFE, 0x2D),
EX_STORAGE_MAX_COUNT(0xFE, 0x2E),
EX_MULTI_PARTY_COMMAND_CHANNEL_INFO(0xFE, 0x30),
EX_PC_CAFE_POINT_INFO(0xFE, 0x31),
EX_SET_COMPASS_ZONE_CODE(0xFE, 0x32),
EX_GET_BOSS_RECORD(0xFE, 0x33),
EX_ASK_JOIN_PARTY_ROOM(0xFE, 0x34),
EX_LIST_PARTY_MATCHING_WAITING_ROOM(0xFE, 0x35),
EX_SHOW_ADVENTURER_GUIDE_BOOK(0xFE, 0x37),
EX_SHOW_SCREEN_MESSAGE(0xFE, 0x38),
PLEDGE_SKILL_LIST(0xFE, 0x39),
PLEDGE_SKILL_LIST_ADD(0xFE, 0x3A),
PLEDGE_POWER_GRADE_LIST(0xFE, 0x3B),
PLEDGE_RECEIVE_POWER_INFO(0xFE, 0x3C),
PLEDGE_RECEIVE_MEMBER_INFO(0xFE, 0x3D),
PLEDGE_RECEIVE_WAR_LIST(0xFE, 0x3E),
PLEDGE_RECEIVE_SUB_PLEDGE_CREATED(0xFE, 0x3F),
EX_RED_SKY(0xFE, 0x40),
SHOW_PC_CAFE_COUPON_SHOW_UI(0xFE, 0x43),
EX_CAPTURE_ORC(0xFE, 0x44),
EX_CURSED_WEAPON_LIST(0xFE, 0x45),
EX_CURSED_WEAPON_LOCATION(0xFE, 0x46),
EX_RESTART_CLIENT(0xFE, 0x47),
EX_REQUEST_HACK_SHIELD(0xFE, 0x48),
EX_USE_SHARED_GROUP_ITEM(0xFE, 0x49),
EX_MPCC_SHOW_PARTY_MEMBER_INFO(0xFE, 0x4A),
EX_DUEL_ASK_START(0xFE, 0x4B),
EX_DUEL_READY(0xFE, 0x4C),
EX_DUEL_START(0xFE, 0x4D),
EX_DUEL_END(0xFE, 0x4E),
EX_DUEL_UPDATE_USER_INFO(0xFE, 0x4F),
EX_SHOW_VARIATION_MAKE_WINDOW(0xFE, 0x50),
EX_SHOW_VARIATION_CANCEL_WINDOW(0xFE, 0x51),
EX_CONFIRM_VARIATION_ITEM(0xFE, 0x52),
EX_CONFIRM_VARIATION_REFINER(0xFE, 0x53),
EX_CONFIRM_VARIATION_GEMSTONE(0xFE, 0x54),
EX_VARIATION_RESULT(0xFE, 0x55),
EX_CONFIRM_CANCEL_ITEM(0xFE, 0x56),
EX_VARIATION_CANCEL_RESULT(0xFE, 0x57),
EX_SHOW_SLIDESHOW_KAMAEL(0xFE, 0x5B);
private final int _id1;
private final int _id2;
OutgoingPackets(int id1)
{
this(id1, -1);
}
OutgoingPackets(int id1, int id2)
{
_id1 = id1;
_id2 = id2;
}
public int getId1()
{
return _id1;
}
public int getId2()
{
return _id2;
}
public void writeId(PacketWriter packet)
{
packet.writeC(_id1);
if (_id2 > 0)
{
packet.writeH(_id2);
}
}
public static OutgoingPackets getPacket(int id1, int id2)
{
for (OutgoingPackets packet : values())
{
if ((packet.getId1() == id1) && (packet.getId2() == id2))
{
return packet;
}
}
return null;
}
}

View File

@@ -18,38 +18,43 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
@SuppressWarnings("unused") public class Action implements IClientIncomingPacket
public class Action extends GameClientPacket
{ {
private static final Logger LOGGER = Logger.getLogger(Action.class.getName()); private static final Logger LOGGER = Logger.getLogger(Action.class.getName());
private int _objectId; private int _objectId;
@SuppressWarnings("unused")
private int _originX; private int _originX;
@SuppressWarnings("unused")
private int _originY; private int _originY;
@SuppressWarnings("unused")
private int _originZ; private int _originZ;
private int _actionId; private int _actionId;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_objectId = readD(); // Target object Identifier _objectId = packet.readD(); // Target object Identifier
_originX = readD(); _originX = packet.readD();
_originY = readD(); _originY = packet.readD();
_originZ = readD(); _originZ = packet.readD();
_actionId = readC(); // Action identifier : 0-Simple click, 1-Shift click _actionId = packet.readC(); // Action identifier : 0-Simple click, 1-Shift click
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
// Get the current PlayerInstance of the player // Get the current PlayerInstance of the player
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
@@ -76,21 +81,21 @@ public class Action extends GameClientPacket
// pressing e.g. pickup many times quickly would get you here // pressing e.g. pickup many times quickly would get you here
if (obj == null) if (obj == null)
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Players can't interact with objects in the other instances except from multiverse // Players can't interact with objects in the other instances except from multiverse
if ((obj.getInstanceId() != player.getInstanceId()) && (player.getInstanceId() != -1)) if ((obj.getInstanceId() != player.getInstanceId()) && (player.getInstanceId() != -1))
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Only GMs can directly interact with invisible characters // Only GMs can directly interact with invisible characters
if ((obj instanceof PlayerInstance) && (((PlayerInstance) obj).getAppearance().isInvisible()) && !player.isGM()) if ((obj instanceof PlayerInstance) && (((PlayerInstance) obj).getAppearance().isInvisible()) && !player.isGM())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
@@ -112,7 +117,7 @@ public class Action extends GameClientPacket
} }
else else
{ {
obj.onActionShift(getClient()); obj.onActionShift(client);
} }
break; break;
} }
@@ -120,14 +125,14 @@ public class Action extends GameClientPacket
{ {
// Invalid action detected (probably client cheating), LOGGER this // Invalid action detected (probably client cheating), LOGGER this
LOGGER.warning("Character: " + player.getName() + " requested invalid action: " + _actionId); LOGGER.warning("Character: " + player.getName() + " requested invalid action: " + _actionId);
getClient().sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
break; break;
} }
} }
} }
else else
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); // Actions prohibited when in trade client.sendPacket(ActionFailed.STATIC_PACKET); // Actions prohibited when in trade
} }
} }
} }

View File

@@ -18,16 +18,18 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.TradeList; import org.l2jmobius.gameserver.model.TradeList;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.TradeOtherAdd; import org.l2jmobius.gameserver.network.serverpackets.TradeOtherAdd;
import org.l2jmobius.gameserver.network.serverpackets.TradeOwnAdd; import org.l2jmobius.gameserver.network.serverpackets.TradeOwnAdd;
import org.l2jmobius.gameserver.network.serverpackets.TradeUpdate; import org.l2jmobius.gameserver.network.serverpackets.TradeUpdate;
public class AddTradeItem extends GameClientPacket public class AddTradeItem implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(AddTradeItem.class.getName()); private static final Logger LOGGER = Logger.getLogger(AddTradeItem.class.getName());
private int _tradeId; private int _tradeId;
@@ -35,17 +37,18 @@ public class AddTradeItem extends GameClientPacket
private int _count; private int _count;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_tradeId = readD(); _tradeId = packet.readD();
_objectId = readD(); _objectId = packet.readD();
_count = readD(); _count = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -17,31 +17,34 @@
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.data.sql.ClanTable; import org.l2jmobius.gameserver.data.sql.ClanTable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
public class AllyDismiss extends GameClientPacket public class AllyDismiss implements IClientIncomingPacket
{ {
private String _clanName; private String _clanName;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_clanName = readS(); _clanName = packet.readS();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if (_clanName == null) if (_clanName == null)
{ {
return; return;
} }
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -17,22 +17,25 @@
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
public class AllyLeave extends GameClientPacket public class AllyLeave implements IClientIncomingPacket
{ {
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,31 +16,34 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.partymatching.PartyMatchRoom; import org.l2jmobius.gameserver.model.partymatching.PartyMatchRoom;
import org.l2jmobius.gameserver.model.partymatching.PartyMatchRoomList; import org.l2jmobius.gameserver.model.partymatching.PartyMatchRoomList;
import org.l2jmobius.gameserver.model.partymatching.PartyMatchWaitingList; import org.l2jmobius.gameserver.model.partymatching.PartyMatchWaitingList;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ExManagePartyRoomMember; import org.l2jmobius.gameserver.network.serverpackets.ExManagePartyRoomMember;
import org.l2jmobius.gameserver.network.serverpackets.ExPartyRoomMember; import org.l2jmobius.gameserver.network.serverpackets.ExPartyRoomMember;
import org.l2jmobius.gameserver.network.serverpackets.PartyMatchDetail; import org.l2jmobius.gameserver.network.serverpackets.PartyMatchDetail;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
public class AnswerJoinPartyRoom extends GameClientPacket public class AnswerJoinPartyRoom implements IClientIncomingPacket
{ {
private int _answer; // 1 or 0 private int _answer; // 1 or 0
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_answer = readD(); _answer = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,27 +16,30 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.SendTradeDone; import org.l2jmobius.gameserver.network.serverpackets.SendTradeDone;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
public class AnswerTradeRequest extends GameClientPacket public class AnswerTradeRequest implements IClientIncomingPacket
{ {
private int _response; private int _response;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_response = readD(); _response = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,27 +16,30 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.UserInfo; import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
/** /**
* Appearing Packet Handler * Appearing Packet Handler
*/ */
public class Appearing extends GameClientPacket public class Appearing implements IClientIncomingPacket
{ {
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if ((player == null) || !player.isOnline()) if ((player == null) || !player.isOnline())
{ {
sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
@@ -45,6 +48,6 @@ public class Appearing extends GameClientPacket
player.onTeleported(); player.onTeleported();
} }
sendPacket(new UserInfo(player)); client.sendPacket(new UserInfo(player));
} }
} }

View File

@@ -16,6 +16,7 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.instancemanager.events.CTF; import org.l2jmobius.gameserver.instancemanager.events.CTF;
import org.l2jmobius.gameserver.instancemanager.events.DM; import org.l2jmobius.gameserver.instancemanager.events.DM;
@@ -24,10 +25,11 @@ import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.actor.instance.SummonInstance; import org.l2jmobius.gameserver.model.actor.instance.SummonInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class AttackRequest extends GameClientPacket public class AttackRequest implements IClientIncomingPacket
{ {
private int _objectId; private int _objectId;
private int _originX; private int _originX;
@@ -36,19 +38,20 @@ public class AttackRequest extends GameClientPacket
private int _attackId; private int _attackId;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_objectId = readD(); _objectId = packet.readD();
_originX = readD(); _originX = packet.readD();
_originY = readD(); _originY = packet.readD();
_originZ = readD(); _originZ = packet.readD();
_attackId = readC(); // 0 for simple click - 1 for shift-click _attackId = packet.readC(); // 0 for simple click - 1 for shift-click
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
@@ -157,7 +160,7 @@ public class AttackRequest extends GameClientPacket
} }
else else
{ {
sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
} }
} }
} }

View File

@@ -16,11 +16,12 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread;
import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.LoginServerThread.SessionKey;
import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.GameClient;
public class AuthLogin extends GameClientPacket public class AuthLogin implements IClientIncomingPacket
{ {
// loginName + keys must match what the loginserver used. // loginName + keys must match what the loginserver used.
private String _loginName; private String _loginName;
@@ -30,20 +31,20 @@ public class AuthLogin extends GameClientPacket
private int _loginKey2; private int _loginKey2;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_loginName = readS().toLowerCase(); _loginName = packet.readS().toLowerCase();
_playKey2 = readD(); _playKey2 = packet.readD();
_playKey1 = readD(); _playKey1 = packet.readD();
_loginKey1 = readD(); _loginKey1 = packet.readD();
_loginKey2 = readD(); _loginKey2 = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2); final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2);
final GameClient client = getClient();
// avoid potential exploits // avoid potential exploits
if (client.getAccountName() == null) if (client.getAccountName() == null)

View File

@@ -16,11 +16,13 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
public class CannotMoveAnymore extends GameClientPacket public class CannotMoveAnymore implements IClientIncomingPacket
{ {
private int _x; private int _x;
private int _y; private int _y;
@@ -28,18 +30,19 @@ public class CannotMoveAnymore extends GameClientPacket
private int _heading; private int _heading;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_x = readD(); _x = packet.readD();
_y = readD(); _y = packet.readD();
_z = readD(); _z = packet.readD();
_heading = readD(); _heading = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,14 +16,16 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.StopMoveInVehicle; import org.l2jmobius.gameserver.network.serverpackets.StopMoveInVehicle;
/** /**
* @author Maktakien * @author Maktakien
*/ */
public class CannotMoveAnymoreInVehicle extends GameClientPacket public class CannotMoveAnymoreInVehicle implements IClientIncomingPacket
{ {
private int _x; private int _x;
private int _y; private int _y;
@@ -32,19 +34,20 @@ public class CannotMoveAnymoreInVehicle extends GameClientPacket
private int _boatId; private int _boatId;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_boatId = readD(); _boatId = packet.readD();
_x = readD(); _x = packet.readD();
_y = readD(); _y = packet.readD();
_z = readD(); _z = packet.readD();
_heading = readD(); _heading = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,22 +16,25 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
public class ChangeMoveType2 extends GameClientPacket public class ChangeMoveType2 implements IClientIncomingPacket
{ {
private boolean _typeRun; private boolean _typeRun;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_typeRun = readD() == 1; _typeRun = packet.readD() == 1;
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -16,62 +16,62 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.actor.instance.StaticObjectInstance; import org.l2jmobius.gameserver.model.actor.instance.StaticObjectInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ChairSit; import org.l2jmobius.gameserver.network.serverpackets.ChairSit;
public class ChangeWaitType2 extends GameClientPacket public class ChangeWaitType2 implements IClientIncomingPacket
{ {
private boolean _typeStand; private boolean _typeStand;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_typeStand = readD() == 1; _typeStand = packet.readD() == 1;
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
} }
final WorldObject target = player.getTarget(); final WorldObject target = player.getTarget();
if (getClient() != null) if (player.isOutOfControl())
{ {
if (player.isOutOfControl()) player.sendPacket(ActionFailed.STATIC_PACKET);
{ return;
player.sendPacket(ActionFailed.STATIC_PACKET); }
return;
}
if (player.getMountType() != 0) if (player.getMountType() != 0)
{ {
return; return;
} }
if ((target != null) && !player.isSitting() && (target instanceof StaticObjectInstance) && (((StaticObjectInstance) target).getType() == 1) && (CastleManager.getInstance().getCastle(target) != null) && player.isInsideRadius2D(target, StaticObjectInstance.INTERACTION_DISTANCE)) if ((target != null) && !player.isSitting() && (target instanceof StaticObjectInstance) && (((StaticObjectInstance) target).getType() == 1) && (CastleManager.getInstance().getCastle(target) != null) && player.isInsideRadius2D(target, StaticObjectInstance.INTERACTION_DISTANCE))
{ {
final ChairSit cs = new ChairSit(player, ((StaticObjectInstance) target).getStaticObjectId()); final ChairSit cs = new ChairSit(player, ((StaticObjectInstance) target).getStaticObjectId());
player.sendPacket(cs); player.sendPacket(cs);
player.sitDown(); player.sitDown();
player.broadcastPacket(cs); player.broadcastPacket(cs);
} }
if (_typeStand) if (_typeStand)
{ {
player.standUp(); player.standUp();
} }
else else
{ {
player.sitDown(); player.sitDown();
}
} }
} }
} }

View File

@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.SkillTable; import org.l2jmobius.gameserver.data.SkillTable;
import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.data.sql.CharNameTable;
@@ -46,7 +47,7 @@ import org.l2jmobius.gameserver.network.serverpackets.CharCreateOk;
import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo; import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
public class CharacterCreate extends GameClientPacket public class CharacterCreate implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(CharacterCreate.class.getName()); private static final Logger LOGGER = Logger.getLogger(CharacterCreate.class.getName());
@@ -72,29 +73,30 @@ public class CharacterCreate extends GameClientPacket
private int _wit; private int _wit;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_name = readS(); _name = packet.readS();
_race = readD(); _race = packet.readD();
_sex = (byte) readD(); _sex = (byte) packet.readD();
_classId = readD(); _classId = packet.readD();
_int = readD(); _int = packet.readD();
_str = readD(); _str = packet.readD();
_con = readD(); _con = packet.readD();
_men = readD(); _men = packet.readD();
_dex = readD(); _dex = packet.readD();
_wit = readD(); _wit = packet.readD();
_hairStyle = (byte) readD(); _hairStyle = (byte) packet.readD();
_hairColor = (byte) readD(); _hairColor = (byte) packet.readD();
_face = (byte) readD(); _face = (byte) packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if ((_name.length() < 3) || (_name.length() > 16) || !Util.isAlphaNumeric(_name) || !isValidName(_name)) if ((_name.length() < 3) || (_name.length() > 16) || !Util.isAlphaNumeric(_name) || !isValidName(_name))
{ {
sendPacket(new CharCreateFail(CharCreateFail.REASON_16_ENG_CHARS)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_16_ENG_CHARS));
return; return;
} }
@@ -104,7 +106,7 @@ public class CharacterCreate extends GameClientPacket
{ {
if (_name.toLowerCase().contains(st.toLowerCase())) if (_name.toLowerCase().contains(st.toLowerCase()))
{ {
getClient().sendPacket(new CharCreateFail(CharCreateFail.REASON_INCORRECT_NAME)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_INCORRECT_NAME));
return; return;
} }
} }
@@ -116,26 +118,26 @@ public class CharacterCreate extends GameClientPacket
// Since checks for duplicate names are done using SQL, lock must be held until data is written to DB as well. // Since checks for duplicate names are done using SQL, lock must be held until data is written to DB as well.
synchronized (CharNameTable.getInstance()) synchronized (CharNameTable.getInstance())
{ {
if ((CharNameTable.getInstance().accountCharNumber(getClient().getAccountName()) >= Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT) && (Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT != 0)) if ((CharNameTable.getInstance().accountCharNumber(client.getAccountName()) >= Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT) && (Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT != 0))
{ {
sendPacket(new CharCreateFail(CharCreateFail.REASON_TOO_MANY_CHARACTERS)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_TOO_MANY_CHARACTERS));
return; return;
} }
else if (CharNameTable.getInstance().doesCharNameExist(_name)) else if (CharNameTable.getInstance().doesCharNameExist(_name))
{ {
sendPacket(new CharCreateFail(CharCreateFail.REASON_NAME_ALREADY_EXISTS)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_NAME_ALREADY_EXISTS));
return; return;
} }
template = PlayerTemplateData.getInstance().getTemplate(_classId); template = PlayerTemplateData.getInstance().getTemplate(_classId);
if ((template == null) || (template.getClassBaseLevel() > 1)) if ((template == null) || (template.getClassBaseLevel() > 1))
{ {
sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED));
return; return;
} }
final int objectId = IdManager.getInstance().getNextId(); final int objectId = IdManager.getInstance().getNextId();
newChar = PlayerInstance.create(objectId, template, getClient().getAccountName(), _name, _hairStyle, _hairColor, _face, _sex != 0); newChar = PlayerInstance.create(objectId, template, client.getAccountName(), _name, _hairStyle, _hairColor, _face, _sex != 0);
newChar.setCurrentHp(newChar.getMaxHp()); // L2Off like newChar.setCurrentHp(newChar.getMaxHp()); // L2Off like
// newChar.setCurrentCp(template.baseCpMax); // newChar.setCurrentCp(template.baseCpMax);
newChar.setCurrentCp(0); // L2Off like newChar.setCurrentCp(0); // L2Off like
@@ -143,8 +145,8 @@ public class CharacterCreate extends GameClientPacket
// newChar.setMaxLoad(template.baseLoad); // newChar.setMaxLoad(template.baseLoad);
// send acknowledgement // send acknowledgement
sendPacket(new CharCreateOk()); // Success client.sendPacket(new CharCreateOk()); // Success
initNewChar(getClient(), newChar); initNewChar(client, newChar);
} }
} }
@@ -160,7 +162,7 @@ public class CharacterCreate extends GameClientPacket
} }
catch (PatternSyntaxException e) // case of illegal pattern catch (PatternSyntaxException e) // case of illegal pattern
{ {
LOGGER.warning("ERROR " + getType() + ": Character name pattern of config is wrong!"); LOGGER.warning("Character name pattern of config is wrong!");
pattern = Pattern.compile(".*"); pattern = Pattern.compile(".*");
} }
@@ -297,7 +299,7 @@ public class CharacterCreate extends GameClientPacket
// Send char list // Send char list
final CharSelectInfo cl = new CharSelectInfo(client.getAccountName(), client.getSessionId().playOkID1); final CharSelectInfo cl = new CharSelectInfo(client.getAccountName(), client.getSessionId().playOkID1);
client.getConnection().sendPacket(cl); client.sendPacket(cl);
client.setCharSelection(cl.getCharInfo()); client.setCharSelection(cl.getCharInfo());
} }

View File

@@ -16,8 +16,11 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.CharDeleteFail; import org.l2jmobius.gameserver.network.serverpackets.CharDeleteFail;
import org.l2jmobius.gameserver.network.serverpackets.CharDeleteOk; import org.l2jmobius.gameserver.network.serverpackets.CharDeleteOk;
import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo; import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
@@ -25,28 +28,29 @@ import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
/** /**
* @author eX1steam * @author eX1steam
*/ */
public class CharacterDelete extends GameClientPacket public class CharacterDelete implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(CharacterDelete.class.getName()); private static final Logger LOGGER = Logger.getLogger(CharacterDelete.class.getName());
private int _charSlot; private int _charSlot;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_charSlot = readD(); _charSlot = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if (!getClient().getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterDelete")) if (!client.getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterDelete"))
{ {
return; return;
} }
try try
{ {
final byte answer = getClient().markToDeleteChar(_charSlot); final byte answer = client.markToDeleteChar(_charSlot);
switch (answer) switch (answer)
{ {
default: default:
@@ -56,28 +60,28 @@ public class CharacterDelete extends GameClientPacket
} }
case 0: // Success! case 0: // Success!
{ {
sendPacket(new CharDeleteOk()); client.sendPacket(new CharDeleteOk());
break; break;
} }
case 1: case 1:
{ {
sendPacket(new CharDeleteFail(CharDeleteFail.REASON_YOU_MAY_NOT_DELETE_CLAN_MEMBER)); client.sendPacket(new CharDeleteFail(CharDeleteFail.REASON_YOU_MAY_NOT_DELETE_CLAN_MEMBER));
break; break;
} }
case 2: case 2:
{ {
sendPacket(new CharDeleteFail(CharDeleteFail.REASON_CLAN_LEADERS_MAY_NOT_BE_DELETED)); client.sendPacket(new CharDeleteFail(CharDeleteFail.REASON_CLAN_LEADERS_MAY_NOT_BE_DELETED));
break; break;
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("ERROR " + getType() + ": " + e); LOGGER.log(Level.SEVERE, "Error:", e);
} }
final CharSelectInfo cl = new CharSelectInfo(getClient().getAccountName(), getClient().getSessionId().playOkID1, 0); final CharSelectInfo cl = new CharSelectInfo(client.getAccountName(), client.getSessionId().playOkID1, 0);
sendPacket(cl); client.sendPacket(cl);
getClient().setCharSelection(cl.getCharInfo()); client.setCharSelection(cl.getCharInfo());
} }
} }

View File

@@ -16,36 +16,39 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo; import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
public class CharacterRestore extends GameClientPacket public class CharacterRestore implements IClientIncomingPacket
{ {
private int _charSlot; private int _charSlot;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_charSlot = readD(); _charSlot = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if (!getClient().getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterRestore")) if (!client.getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterRestore"))
{ {
return; return;
} }
try try
{ {
getClient().markRestoredChar(_charSlot); client.markRestoredChar(_charSlot);
} }
catch (Exception e) catch (Exception e)
{ {
} }
final CharSelectInfo cl = new CharSelectInfo(getClient().getAccountName(), getClient().getSessionId().playOkID1, 0); final CharSelectInfo cl = new CharSelectInfo(client.getAccountName(), client.getSessionId().playOkID1, 0);
sendPacket(cl); client.sendPacket(cl);
getClient().setCharSelection(cl.getCharInfo()); client.setCharSelection(cl.getCharInfo());
} }
} }

View File

@@ -18,13 +18,15 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.ConnectionState;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.CharSelected; import org.l2jmobius.gameserver.network.serverpackets.CharSelected;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class CharacterSelected extends GameClientPacket public class CharacterSelected implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(CharacterSelected.class.getName()); private static final Logger LOGGER = Logger.getLogger(CharacterSelected.class.getName());
@@ -35,41 +37,42 @@ public class CharacterSelected extends GameClientPacket
private int _unk4; private int _unk4;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_charSlot = readD(); _charSlot = packet.readD();
_unk1 = readH(); _unk1 = packet.readH();
_unk2 = readD(); _unk2 = packet.readD();
_unk3 = readD(); _unk3 = packet.readD();
_unk4 = readD(); _unk4 = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
// if there is a playback.dat file in the current directory, it will be sent to the client instead of any regular packets // if there is a playback.dat file in the current directory, it will be sent to the client instead of any regular packets
// to make this work, the first packet in the playback.dat has to be a [S]0x21 packet // to make this work, the first packet in the playback.dat has to be a [S]0x21 packet
// after playback is done, the client will not work correct and need to exit // after playback is done, the client will not work correct and need to exit
// playLogFile(getConnection()); // try to play LOGGER file // playLogFile(getConnection()); // try to play LOGGER file
if (!getClient().getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterSelect")) if (!client.getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterSelect"))
{ {
return; return;
} }
// we should always be abble to acquire the lock but if we cant lock then nothing should be done (ie repeated packet) // we should always be abble to acquire the lock but if we cant lock then nothing should be done (ie repeated packet)
if (getClient().getPlayerLock().tryLock()) if (client.getPlayerLock().tryLock())
{ {
try try
{ {
// should always be null but if not then this is repeated packet and nothing should be done here // should always be null but if not then this is repeated packet and nothing should be done here
if (getClient().getPlayer() == null) if (client.getPlayer() == null)
{ {
// Load up character from disk // Load up character from disk
final PlayerInstance cha = getClient().loadCharFromDisk(_charSlot); final PlayerInstance cha = client.loadCharFromDisk(_charSlot);
if (cha == null) if (cha == null)
{ {
LOGGER.warning(getType() + ": Character could not be loaded (slot:" + _charSlot + ")"); LOGGER.warning("Character could not be loaded (slot:" + _charSlot + ")");
sendPacket(ActionFailed.STATIC_PACKET); client.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
@@ -79,10 +82,10 @@ public class CharacterSelected extends GameClientPacket
return; return;
} }
cha.setClient(getClient()); cha.setClient(client);
getClient().setPlayer(cha); client.setPlayer(cha);
getClient().setState(ConnectionState.ENTERING); client.setConnectionState(ConnectionState.ENTERING);
sendPacket(new CharSelected(cha, getClient().getSessionId().playOkID1)); client.sendPacket(new CharSelected(cha, client.getSessionId().playOkID1));
} }
} }
catch (Exception e) catch (Exception e)
@@ -91,7 +94,7 @@ public class CharacterSelected extends GameClientPacket
} }
finally finally
{ {
getClient().getPlayerLock().unlock(); client.getPlayerLock().unlock();
} }
} }
} }

View File

@@ -17,30 +17,33 @@
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
/** /**
* @author Dezmond_snz - Packet Format: cddd * @author Dezmond_snz - Packet Format: cddd
*/ */
public class DlgAnswer extends GameClientPacket public class DlgAnswer implements IClientIncomingPacket
{ {
private int _messageId; private int _messageId;
private int _answer; private int _answer;
// private int _requesterId; // private int _requesterId;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_messageId = readD(); _messageId = packet.readD();
_answer = readD(); _answer = packet.readD();
// _requesterId = readD(); // _requesterId = packet.readD();
return true;
} }
@Override @Override
public void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -26,6 +26,7 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.GameTimeController; import org.l2jmobius.gameserver.GameTimeController;
import org.l2jmobius.gameserver.communitybbs.Manager.MailBBSManager; import org.l2jmobius.gameserver.communitybbs.Manager.MailBBSManager;
@@ -67,6 +68,7 @@ import org.l2jmobius.gameserver.model.siege.FortSiege;
import org.l2jmobius.gameserver.model.siege.Siege; import org.l2jmobius.gameserver.model.siege.Siege;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.ConnectionState;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ClientSetTime; import org.l2jmobius.gameserver.network.serverpackets.ClientSetTime;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
@@ -96,7 +98,7 @@ import org.l2jmobius.gameserver.util.Util;
/** /**
* Enter World Packet Handler * Enter World Packet Handler
*/ */
public class EnterWorld extends GameClientPacket public class EnterWorld implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(EnterWorld.class.getName()); private static final Logger LOGGER = Logger.getLogger(EnterWorld.class.getName());
@@ -104,23 +106,23 @@ public class EnterWorld extends GameClientPacket
SimpleDateFormat df = new SimpleDateFormat("dd MM yyyy"); SimpleDateFormat df = new SimpleDateFormat("dd MM yyyy");
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
// this is just a trigger packet. it has no content return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
LOGGER.warning("EnterWorld failed! player is null..."); LOGGER.warning("EnterWorld failed! player is null...");
getClient().closeNow(); client.closeNow();
return; return;
} }
getClient().setState(ConnectionState.IN_GAME); client.setConnectionState(ConnectionState.IN_GAME);
// Set lock at login // Set lock at login
player.setLocked(true); player.setLocked(true);
@@ -130,7 +132,7 @@ public class EnterWorld extends GameClientPacket
if (!player.isGM() && !player.isDonator() && Config.CHECK_NAME_ON_LOGIN && ((player.getName().length() < 3) || (player.getName().length() > 16) || !Util.isAlphaNumeric(player.getName()) || !isValidName(player.getName()))) if (!player.isGM() && !player.isDonator() && Config.CHECK_NAME_ON_LOGIN && ((player.getName().length() < 3) || (player.getName().length() > 16) || !Util.isAlphaNumeric(player.getName()) || !isValidName(player.getName())))
{ {
LOGGER.warning("Charname: " + player.getName() + " is invalid. EnterWorld failed."); LOGGER.warning("Charname: " + player.getName() + " is invalid. EnterWorld failed.");
getClient().closeNow(); client.closeNow();
return; return;
} }
@@ -169,7 +171,7 @@ public class EnterWorld extends GameClientPacket
html.setFile("data/html/clan_notice.htm"); html.setFile("data/html/clan_notice.htm");
html.replace("%clan_name%", player.getClan().getName()); html.replace("%clan_name%", player.getClan().getName());
html.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>").replaceAll("action", "").replace("bypass", "")); html.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>").replaceAll("action", "").replace("bypass", ""));
sendPacket(html); player.sendPacket(html);
} }
} }
@@ -183,7 +185,7 @@ public class EnterWorld extends GameClientPacket
// player.sendPacket(new StopRotation(player, player.getHeading(), 10000000)); // player.sendPacket(new StopRotation(player, player.getHeading(), 10000000));
if (SevenSigns.getInstance().isSealValidationPeriod()) if (SevenSigns.getInstance().isSealValidationPeriod())
{ {
sendPacket(new SignsSky()); player.sendPacket(new SignsSky());
} }
// Buff and Status icons // Buff and Status icons
@@ -235,7 +237,7 @@ public class EnterWorld extends GameClientPacket
player.sendMessage("[Server]: You have over enchanted items you will be kicked from server!"); player.sendMessage("[Server]: You have over enchanted items you will be kicked from server!");
player.sendMessage("[Server]: Respect our server rules."); player.sendMessage("[Server]: Respect our server rules.");
// Message with screen // Message with screen
sendPacket(new ExShowScreenMessage(" You have an over enchanted item, you will be kicked from server! ", 6000)); player.sendPacket(new ExShowScreenMessage(" You have an over enchanted item, you will be kicked from server! ", 6000));
// Punishment e LOGGER in audit // Punishment e LOGGER in audit
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has Overenchanted item! Kicked! ", Config.DEFAULT_PUNISH); Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has Overenchanted item! Kicked! ", Config.DEFAULT_PUNISH);
// Logger in console // Logger in console
@@ -254,12 +256,12 @@ public class EnterWorld extends GameClientPacket
player.getMacroses().sendUpdate(); player.getMacroses().sendUpdate();
// Send packets info // Send packets info
sendPacket(new ClientSetTime()); // SetClientTime player.sendPacket(new ClientSetTime()); // SetClientTime
sendPacket(new UserInfo(player)); player.sendPacket(new UserInfo(player));
sendPacket(new HennaInfo(player)); player.sendPacket(new HennaInfo(player));
sendPacket(new FriendList(player)); player.sendPacket(new FriendList(player));
sendPacket(new ItemList(player, false)); player.sendPacket(new ItemList(player, false));
sendPacket(new ShortCutInit(player)); player.sendPacket(new ShortCutInit(player));
// Reload inventory to give SA skill // Reload inventory to give SA skill
player.getInventory().reloadEquippedItems(); player.getInventory().reloadEquippedItems();
@@ -292,13 +294,13 @@ public class EnterWorld extends GameClientPacket
// sendPacket(ui); // sendPacket(ui);
if ((player.getClanId() != 0) && (player.getClan() != null)) if ((player.getClanId() != 0) && (player.getClan() != null))
{ {
sendPacket(new PledgeShowMemberListAll(player.getClan(), player)); player.sendPacket(new PledgeShowMemberListAll(player.getClan(), player));
sendPacket(new PledgeStatusChanged(player.getClan())); player.sendPacket(new PledgeStatusChanged(player.getClan()));
} }
if (player.isAlikeDead()) if (player.isAlikeDead())
{ {
sendPacket(new Die(player)); // No broadcast needed since the player will already spawn dead to others player.sendPacket(new Die(player)); // No broadcast needed since the player will already spawn dead to others
} }
if (Config.ALLOW_WATER) if (Config.ALLOW_WATER)
@@ -466,13 +468,13 @@ public class EnterWorld extends GameClientPacket
{ {
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT);
sm.addSkillName(294); sm.addSkillName(294);
sendPacket(sm); player.sendPacket(sm);
} }
else else
{ {
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR);
sm.addSkillName(294); sm.addSkillName(294);
sendPacket(sm); player.sendPacket(sm);
} }
} }
} }
@@ -499,7 +501,7 @@ public class EnterWorld extends GameClientPacket
} }
catch (PatternSyntaxException e) // case of illegal pattern catch (PatternSyntaxException e) // case of illegal pattern
{ {
LOGGER.warning("ERROR " + getType() + ": Character name pattern of config is wrong!"); LOGGER.warning("Character name pattern of config is wrong!");
pattern = Pattern.compile(".*"); pattern = Pattern.compile(".*");
} }
@@ -604,7 +606,7 @@ public class EnterWorld extends GameClientPacket
final NpcHtmlMessage html = new NpcHtmlMessage(1); final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(Welcome_Path); html.setFile(Welcome_Path);
html.replace("%name%", player.getName()); html.replace("%name%", player.getName());
sendPacket(html); player.sendPacket(html);
} }
} }
@@ -706,11 +708,11 @@ public class EnterWorld extends GameClientPacket
player.updateNameTitleColor(); player.updateNameTitleColor();
sendPacket(new UserInfo(player)); player.sendPacket(new UserInfo(player));
sendPacket(new HennaInfo(player)); player.sendPacket(new HennaInfo(player));
sendPacket(new FriendList(player)); player.sendPacket(new FriendList(player));
sendPacket(new ItemList(player, false)); player.sendPacket(new ItemList(player, false));
sendPacket(new ShortCutInit(player)); player.sendPacket(new ShortCutInit(player));
player.broadcastUserInfo(); player.broadcastUserInfo();
} }

View File

@@ -0,0 +1,64 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.ExIncomingPackets;
import org.l2jmobius.gameserver.network.GameClient;
/**
* @author Nos
*/
public class ExPacket implements IClientIncomingPacket
{
// private static final Logger LOGGER = Logger.getLogger(ExPacket.class.getName());
private ExIncomingPackets _exIncomingPacket;
private IIncomingPacket<GameClient> _exPacket;
@Override
public boolean read(GameClient client, PacketReader packet)
{
final int exPacketId = packet.readH() & 0xFFFF;
if ((exPacketId < 0) || (exPacketId >= ExIncomingPackets.PACKET_ARRAY.length))
{
return false;
}
_exIncomingPacket = ExIncomingPackets.PACKET_ARRAY[exPacketId];
if (_exIncomingPacket == null)
{
// LOGGER.finer(getClass().getSimpleName() + ": Unknown packet: " + Integer.toHexString(exPacketId));
return false;
}
_exPacket = _exIncomingPacket.newIncomingPacket();
return (_exPacket != null) && _exPacket.read(client, packet);
}
@Override
public void run(GameClient client) throws Exception
{
if (!_exIncomingPacket.getConnectionStates().contains(client.getConnectionState()))
{
// LOGGER.finer(_exIncomingPacket + ": Connection at invalid state: " + client.getConnectionState() + " Required State: " + _exIncomingPacket.getConnectionStates());
return;
}
_exPacket.run(client);
}
}

View File

@@ -17,31 +17,32 @@
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.StopRotation; import org.l2jmobius.gameserver.network.serverpackets.StopRotation;
@SuppressWarnings("unused") public class FinishRotating implements IClientIncomingPacket
public class FinishRotating extends GameClientPacket
{ {
private int _degree; private int _degree;
private int _unknown;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_degree = readD(); _degree = packet.readD();
_unknown = readD(); packet.readD(); // Unknown.
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if (!Config.ENABLE_KEYBOARD_MOVEMENT) if (!Config.ENABLE_KEYBOARD_MOVEMENT)
{ {
return; return;
} }
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -1,92 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
import org.l2jmobius.commons.mmocore.ReceivablePacket;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket;
/**
* Packets received by the game server from clients
* @author KenM
*/
public abstract class GameClientPacket extends ReceivablePacket<GameClient>
{
protected static final Logger LOGGER = Logger.getLogger(GameClientPacket.class.getName());
@Override
protected boolean read()
{
try
{
readImpl();
return true;
}
catch (Exception e)
{
LOGGER.severe("Client: " + getClient() + " - Failed reading: " + getType() + " ; " + e.getMessage() + " " + e);
}
return false;
}
protected abstract void readImpl();
@Override
public void run()
{
try
{
runImpl();
if ((this instanceof MoveBackwardToLocation) || (this instanceof AttackRequest) || (this instanceof RequestMagicSkillUse))
{
if (getClient().getPlayer() != null)
{
getClient().getPlayer().onActionRequest(); // Removes onSpawn Protection
}
}
}
catch (Throwable t)
{
LOGGER.severe("Client: " + getClient() + " - Failed reading: " + getType() + " ; " + t.getMessage() + " " + t);
if (this instanceof EnterWorld)
{
getClient().closeNow();
}
}
}
protected abstract void runImpl();
/**
* Sends a game server packet to the client.
* @param gsp the game server packet
*/
protected final void sendPacket(GameServerPacket gsp)
{
getClient().sendPacket(gsp);
}
/**
* @return A String with this packet name for debuging purposes
*/
public String getType()
{
return "[C] " + getClass().getSimpleName();
}
}

View File

@@ -16,25 +16,29 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
/** /**
* @author zabbix Lets drink to code! Unknown Packet: ca 0000: 45 00 01 00 1e 37 a2 f5 00 00 00 00 00 00 00 00 E....7.......... * @author zabbix Lets drink to code! Unknown Packet: ca 0000: 45 00 01 00 1e 37 a2 f5 00 00 00 00 00 00 00 00 E....7..........
*/ */
public class GameGuardReply extends GameClientPacket public class GameGuardReply implements IClientIncomingPacket
{ {
private final int[] _reply = new int[4]; private final int[] _reply = new int[4];
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_reply[0] = readD(); _reply[0] = packet.readD();
_reply[1] = readD(); _reply[1] = packet.readD();
_reply[2] = readD(); _reply[2] = packet.readD();
_reply[3] = readD(); _reply[3] = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
getClient().setGameGuardOk(true); client.setGameGuardOk(true);
} }
} }

View File

@@ -16,18 +16,16 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
/** import java.util.logging.Logger;
* @author zabbix Lets drink to code!
*/
public class DummyPacket extends GameClientPacket
{
@Override
protected void readImpl()
{
}
@Override import org.l2jmobius.commons.network.IIncomingPacket;
public void runImpl() import org.l2jmobius.gameserver.network.GameClient;
{
} /**
* Packets received by the game serv@Override er from clients
* @author KenM
*/
public interface IClientIncomingPacket extends IIncomingPacket<GameClient>
{
Logger LOGGER = Logger.getLogger(IClientIncomingPacket.class.getName());
} }

View File

@@ -17,6 +17,7 @@
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.data.SkillTable; import org.l2jmobius.gameserver.data.SkillTable;
import org.l2jmobius.gameserver.model.Party; import org.l2jmobius.gameserver.model.Party;
@@ -25,23 +26,25 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.olympiad.Olympiad; import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival; import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager; import org.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
public class Logout extends GameClientPacket public class Logout implements IClientIncomingPacket
{ {
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
// Do not allow leaving if player is fighting // Do not allow leaving if player is fighting
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -19,10 +19,12 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.nio.BufferUnderflowException; import java.nio.BufferUnderflowException;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.xml.DoorData; import org.l2jmobius.gameserver.data.xml.DoorData;
import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.EnchantResult; import org.l2jmobius.gameserver.network.serverpackets.EnchantResult;
@@ -30,7 +32,7 @@ import org.l2jmobius.gameserver.network.serverpackets.StopMove;
import org.l2jmobius.gameserver.util.IllegalPlayerAction; import org.l2jmobius.gameserver.util.IllegalPlayerAction;
import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.gameserver.util.Util;
public class MoveBackwardToLocation extends GameClientPacket public class MoveBackwardToLocation implements IClientIncomingPacket
{ {
private int _targetX; private int _targetX;
private int _targetY; private int _targetY;
@@ -41,42 +43,44 @@ public class MoveBackwardToLocation extends GameClientPacket
private int _movementMode; private int _movementMode;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_targetX = readD(); _targetX = packet.readD();
_targetY = readD(); _targetY = packet.readD();
_targetZ = readD(); _targetZ = packet.readD();
_originX = readD(); _originX = packet.readD();
_originY = readD(); _originY = packet.readD();
_originZ = readD(); _originZ = packet.readD();
try try
{ {
_movementMode = readD(); // is 0 if cursor keys are used 1 if mouse is used _movementMode = packet.readD(); // is 0 if cursor keys are used 1 if mouse is used
} }
catch (BufferUnderflowException e) catch (BufferUnderflowException e)
{ {
// Ignore for now // Ignore for now
if (Config.L2WALKER_PROTECTION) if (Config.L2WALKER_PROTECTION)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
player.sendPacket(SystemMessageId.A_HACKING_TOOL_HAS_BEEN_DISCOVERED_PLEASE_TRY_PLAYING_AGAIN_AFTER_CLOSING_UNNECESSARY_PROGRAMS); player.sendPacket(SystemMessageId.A_HACKING_TOOL_HAS_BEEN_DISCOVERED_PLEASE_TRY_PLAYING_AGAIN_AFTER_CLOSING_UNNECESSARY_PROGRAMS);
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " trying to use L2Walker!", IllegalPlayerAction.PUNISH_KICK); Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " trying to use L2Walker!", IllegalPlayerAction.PUNISH_KICK);
} }
} }
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
} }
// Move flood protection // Move flood protection
if (!getClient().getFloodProtectors().getMoveAction().tryPerformAction("MoveBackwardToLocation")) if (!client.getFloodProtectors().getMoveAction().tryPerformAction("MoveBackwardToLocation"))
{ {
player.sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
@@ -85,7 +89,7 @@ public class MoveBackwardToLocation extends GameClientPacket
// Like L2OFF movements prohibited when char is sitting // Like L2OFF movements prohibited when char is sitting
if (player.isSitting()) if (player.isSitting())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }

View File

@@ -16,27 +16,26 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
/** /**
* Format: (c) ddd d: dx d: dy d: dz * Format: (c) ddd d: dx d: dy d: dz
* @author -Wooden- * @author -Wooden-
*/ */
@SuppressWarnings("unused") public class MoveWithDelta implements IClientIncomingPacket
public class MoveWithDelta extends GameClientPacket
{ {
private int _dx;
private int _dy;
private int _dz;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_dx = readD(); packet.readD(); // dx
_dy = readD(); packet.readD(); // dy
_dz = readD(); packet.readD(); // dz
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
} }
} }

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.MultisellData; import org.l2jmobius.gameserver.data.xml.MultisellData;
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
@@ -33,6 +34,7 @@ import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.multisell.MultiSellEntry; import org.l2jmobius.gameserver.model.multisell.MultiSellEntry;
import org.l2jmobius.gameserver.model.multisell.MultiSellIngredient; import org.l2jmobius.gameserver.model.multisell.MultiSellIngredient;
import org.l2jmobius.gameserver.model.multisell.MultiSellListContainer; import org.l2jmobius.gameserver.model.multisell.MultiSellListContainer;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.ItemList;
@@ -43,7 +45,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/** /**
* The Class MultiSellChoose. * The Class MultiSellChoose.
*/ */
public class MultiSellChoose extends GameClientPacket public class MultiSellChoose implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(MultiSellChoose.class.getName()); private static final Logger LOGGER = Logger.getLogger(MultiSellChoose.class.getName());
private int _listId; private int _listId;
@@ -53,27 +55,28 @@ public class MultiSellChoose extends GameClientPacket
private int _transactionTax; // local handling of taxation private int _transactionTax; // local handling of taxation
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_listId = readD(); _listId = packet.readD();
_entryId = readD(); _entryId = packet.readD();
_amount = readD(); _amount = packet.readD();
// _enchantment = readH(); // Commented this line because it did NOT work! // _enchantment = packet.readH(); // Commented this line because it did NOT work!
_enchantment = _entryId % 100000; _enchantment = _entryId % 100000;
_entryId = _entryId / 100000; _entryId = _entryId / 100000;
_transactionTax = 0; // Initialize tax amount to 0... _transactionTax = 0; // Initialize tax amount to 0...
return true;
} }
@Override @Override
public void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
} }
if (!getClient().getFloodProtectors().getMultiSell().tryPerformAction("multisell choose")) if (!client.getFloodProtectors().getMultiSell().tryPerformAction("multisell choose"))
{ {
player.setMultiSellId(-1); player.setMultiSellId(-1);
return; return;

View File

@@ -16,20 +16,23 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.xml.PlayerTemplateData; import org.l2jmobius.gameserver.data.xml.PlayerTemplateData;
import org.l2jmobius.gameserver.enums.ClassId; import org.l2jmobius.gameserver.enums.ClassId;
import org.l2jmobius.gameserver.model.actor.templates.PlayerTemplate; import org.l2jmobius.gameserver.model.actor.templates.PlayerTemplate;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.CharTemplates; import org.l2jmobius.gameserver.network.serverpackets.CharTemplates;
public class NewCharacter extends GameClientPacket public class NewCharacter implements IClientIncomingPacket
{ {
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final CharTemplates ct = new CharTemplates(); final CharTemplates ct = new CharTemplates();
PlayerTemplate template = PlayerTemplateData.getInstance().getTemplate(0); PlayerTemplate template = PlayerTemplateData.getInstance().getTemplate(0);
@@ -63,6 +66,6 @@ public class NewCharacter extends GameClientPacket
ct.addChar(template); ct.addChar(template);
// Finally // Finally
sendPacket(ct); client.sendPacket(ct);
} }
} }

View File

@@ -16,19 +16,22 @@
*/ */
package org.l2jmobius.gameserver.network.clientpackets; package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
public class ObserverReturn extends GameClientPacket public class ObserverReturn implements IClientIncomingPacket
{ {
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;

View File

@@ -19,37 +19,40 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.gameserver.network.serverpackets.GameServerPacket; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.KeyPacket; import org.l2jmobius.gameserver.network.serverpackets.KeyPacket;
public class ProtocolVersion extends GameClientPacket public class ProtocolVersion implements IClientIncomingPacket
{ {
static Logger LOGGER = Logger.getLogger(ProtocolVersion.class.getName()); static Logger LOGGER = Logger.getLogger(ProtocolVersion.class.getName());
private int _version; private int _version;
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_version = readD(); _version = packet.readD();
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
if ((_version == 65534) || (_version == -2)) // Ping if ((_version == 65534) || (_version == -2)) // Ping
{ {
getClient().close((GameServerPacket) null); // this is just a ping attempt from the new C2 client
client.closeNow();
} }
else if ((_version < Config.MIN_PROTOCOL_REVISION) || (_version > Config.MAX_PROTOCOL_REVISION)) else if ((_version < Config.MIN_PROTOCOL_REVISION) || (_version > Config.MAX_PROTOCOL_REVISION))
{ {
LOGGER.info("Client: " + getClient() + " -> Protocol Revision: " + _version + " is invalid. Minimum is " + Config.MIN_PROTOCOL_REVISION + " and Maximum is " + Config.MAX_PROTOCOL_REVISION + " are supported. Closing connection."); LOGGER.info("Client: " + client + " -> Protocol Revision: " + _version + " is invalid. Minimum is " + Config.MIN_PROTOCOL_REVISION + " and Maximum is " + Config.MAX_PROTOCOL_REVISION + " are supported. Closing connection.");
LOGGER.warning("Wrong Protocol Version " + _version); LOGGER.warning("Wrong Protocol Version " + _version);
getClient().close((GameServerPacket) null); client.close(new KeyPacket(client.enableCrypt(), 0));
} }
else else
{ {
getClient().setProtocolVersion(_version); client.sendPacket(new KeyPacket(client.enableCrypt(), 1));
getClient().sendPacket(new KeyPacket(getClient().enableCrypt())); client.setProtocolVersion(_version);
} }
} }
} }

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.GameTimeController; import org.l2jmobius.gameserver.GameTimeController;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.SkillTable; import org.l2jmobius.gameserver.data.SkillTable;
@@ -39,6 +40,7 @@ import org.l2jmobius.gameserver.model.actor.instance.StaticObjectInstance;
import org.l2jmobius.gameserver.model.actor.instance.SummonInstance; import org.l2jmobius.gameserver.model.actor.instance.SummonInstance;
import org.l2jmobius.gameserver.model.itemcontainer.Inventory; import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ChairSit; import org.l2jmobius.gameserver.network.serverpackets.ChairSit;
@@ -46,7 +48,7 @@ import org.l2jmobius.gameserver.network.serverpackets.RecipeShopManageList;
import org.l2jmobius.gameserver.network.serverpackets.Ride; import org.l2jmobius.gameserver.network.serverpackets.Ride;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
public class RequestActionUse extends GameClientPacket public class RequestActionUse implements IClientIncomingPacket
{ {
private static final Logger LOGGER = Logger.getLogger(RequestActionUse.class.getName()); private static final Logger LOGGER = Logger.getLogger(RequestActionUse.class.getName());
@@ -70,17 +72,18 @@ public class RequestActionUse extends GameClientPacket
} }
@Override @Override
protected void readImpl() public boolean read(GameClient client, PacketReader packet)
{ {
_actionId = readD(); _actionId = packet.readD();
_ctrlPressed = readD() == 1; _ctrlPressed = packet.readD() == 1;
_shiftPressed = readC() == 1; _shiftPressed = packet.readC() == 1;
return true;
} }
@Override @Override
protected void runImpl() public void run(GameClient client)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
@@ -89,14 +92,14 @@ public class RequestActionUse extends GameClientPacket
// dont do anything if player is dead // dont do anything if player is dead
if ((_actionId != 0) && player.isAlikeDead()) if ((_actionId != 0) && player.isAlikeDead())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// don't do anything if player is confused // don't do anything if player is confused
if (player.isOutOfControl()) if (player.isOutOfControl())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
@@ -107,7 +110,7 @@ public class RequestActionUse extends GameClientPacket
} }
else if (player.isCastingNow()) else if (player.isCastingNow())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
@@ -332,31 +335,31 @@ public class RequestActionUse extends GameClientPacket
} }
case 32: // Wild Hog Cannon - Mode Change case 32: // Wild Hog Cannon - Mode Change
{ {
useSkill(4230); useSkill(client, 4230);
break; break;
} }
case 36: // Soulless - Toxic Smoke case 36: // Soulless - Toxic Smoke
{ {
useSkill(4259); useSkill(client, 4259);
break; break;
} }
case 37: case 37:
{ {
if (player.isAlikeDead()) if (player.isAlikeDead())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Like L2OFF - You can't open Manufacture when you are in private store // Like L2OFF - You can't open Manufacture when you are in private store
if ((player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_BUY) || (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_SELL)) if ((player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_BUY) || (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_SELL))
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Like L2OFF - You can't open Manufacture when you are sitting // Like L2OFF - You can't open Manufacture when you are sitting
if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE)) if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE))
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE) if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE)
@@ -376,47 +379,47 @@ public class RequestActionUse extends GameClientPacket
} }
case 39: // Soulless - Parasite Burst case 39: // Soulless - Parasite Burst
{ {
useSkill(4138); useSkill(client, 4138);
break; break;
} }
case 41: // Wild Hog Cannon - Attack case 41: // Wild Hog Cannon - Attack
{ {
useSkill(4230); useSkill(client, 4230);
break; break;
} }
case 42: // Kai the Cat - Self Damage Shield case 42: // Kai the Cat - Self Damage Shield
{ {
useSkill(4378, player); useSkill(client, 4378, player);
break; break;
} }
case 43: // Unicorn Merrow - Hydro Screw case 43: // Unicorn Merrow - Hydro Screw
{ {
useSkill(4137); useSkill(client, 4137);
break; break;
} }
case 44: // Big Boom - Boom Attack case 44: // Big Boom - Boom Attack
{ {
useSkill(4139); useSkill(client, 4139);
break; break;
} }
case 45: // Unicorn Boxer - Master Recharge case 45: // Unicorn Boxer - Master Recharge
{ {
useSkill(4025, player); useSkill(client, 4025, player);
break; break;
} }
case 46: // Mew the Cat - Mega Storm Strike case 46: // Mew the Cat - Mega Storm Strike
{ {
useSkill(4261); useSkill(client, 4261);
break; break;
} }
case 47: // Silhouette - Steal Blood case 47: // Silhouette - Steal Blood
{ {
useSkill(4260); useSkill(client, 4260);
break; break;
} }
case 48: // Mechanic Golem - Mech. Cannon case 48: // Mechanic Golem - Mech. Cannon
{ {
useSkill(4068); useSkill(client, 4068);
break; break;
} }
case 51: case 51:
@@ -424,19 +427,19 @@ public class RequestActionUse extends GameClientPacket
// Player shouldn't be able to set stores if he/she is alike dead (dead or fake death) // Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
if (player.isAlikeDead()) if (player.isAlikeDead())
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Like L2OFF - You can't open Manufacture when you are in private store // Like L2OFF - You can't open Manufacture when you are in private store
if ((player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_BUY) || (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_SELL)) if ((player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_BUY) || (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_SELL))
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
// Like L2OFF - You can't open Manufacture when you are sitting // Like L2OFF - You can't open Manufacture when you are sitting
if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE)) if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE))
{ {
getClient().sendPacket(ActionFailed.STATIC_PACKET); player.sendPacket(ActionFailed.STATIC_PACKET);
return; return;
} }
if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE) if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE)
@@ -506,7 +509,7 @@ public class RequestActionUse extends GameClientPacket
{ {
if (target instanceof DoorInstance) if (target instanceof DoorInstance)
{ {
useSkill(4079); useSkill(client, 4079);
} }
break; break;
} }
@@ -516,124 +519,124 @@ public class RequestActionUse extends GameClientPacket
} }
case 1003: // Wind Hatchling/Strider - Wild Stun case 1003: // Wind Hatchling/Strider - Wild Stun
{ {
useSkill(4710); // TODO use correct skill level based on pet level useSkill(client, 4710); // TODO use correct skill level based on pet level
break; break;
} }
case 1004: // Wind Hatchling/Strider - Wild Defense case 1004: // Wind Hatchling/Strider - Wild Defense
{ {
useSkill(4711, player); // TODO use correct skill level based on pet level useSkill(client, 4711, player); // TODO use correct skill level based on pet level
break; break;
} }
case 1005: // Star Hatchling/Strider - Bright Burst case 1005: // Star Hatchling/Strider - Bright Burst
{ {
useSkill(4712); // TODO use correct skill level based on pet level useSkill(client, 4712); // TODO use correct skill level based on pet level
break; break;
} }
case 1006: // Star Hatchling/Strider - Bright Heal case 1006: // Star Hatchling/Strider - Bright Heal
{ {
useSkill(4713, player); // TODO use correct skill level based on pet level useSkill(client, 4713, player); // TODO use correct skill level based on pet level
break; break;
} }
case 1007: // Cat Queen - Blessing of Queen case 1007: // Cat Queen - Blessing of Queen
{ {
useSkill(4699, player); useSkill(client, 4699, player);
break; break;
} }
case 1008: // Cat Queen - Gift of Queen case 1008: // Cat Queen - Gift of Queen
{ {
useSkill(4700, player); useSkill(client, 4700, player);
break; break;
} }
case 1009: // Cat Queen - Cure of Queen case 1009: // Cat Queen - Cure of Queen
{ {
useSkill(4701); useSkill(client, 4701);
break; break;
} }
case 1010: // Unicorn Seraphim - Blessing of Seraphim case 1010: // Unicorn Seraphim - Blessing of Seraphim
{ {
useSkill(4702, player); useSkill(client, 4702, player);
break; break;
} }
case 1011: // Unicorn Seraphim - Gift of Seraphim case 1011: // Unicorn Seraphim - Gift of Seraphim
{ {
useSkill(4703, player); useSkill(client, 4703, player);
break; break;
} }
case 1012: // Unicorn Seraphim - Cure of Seraphim case 1012: // Unicorn Seraphim - Cure of Seraphim
{ {
useSkill(4704); useSkill(client, 4704);
break; break;
} }
case 1013: // Nightshade - Curse of Shade case 1013: // Nightshade - Curse of Shade
{ {
useSkill(4705); useSkill(client, 4705);
break; break;
} }
case 1014: // Nightshade - Mass Curse of Shade case 1014: // Nightshade - Mass Curse of Shade
{ {
useSkill(4706, player); useSkill(client, 4706, player);
break; break;
} }
case 1015: // Nightshade - Shade Sacrifice case 1015: // Nightshade - Shade Sacrifice
{ {
useSkill(4707); useSkill(client, 4707);
break; break;
} }
case 1016: // Cursed Man - Cursed Blow case 1016: // Cursed Man - Cursed Blow
{ {
useSkill(4709); useSkill(client, 4709);
break; break;
} }
case 1017: // Cursed Man - Cursed Strike/Stun case 1017: // Cursed Man - Cursed Strike/Stun
{ {
useSkill(4708); useSkill(client, 4708);
break; break;
} }
case 1031: // Feline King - Slash case 1031: // Feline King - Slash
{ {
useSkill(5135); useSkill(client, 5135);
break; break;
} }
case 1032: // Feline King - Spinning Slash case 1032: // Feline King - Spinning Slash
{ {
useSkill(5136); useSkill(client, 5136);
break; break;
} }
case 1033: // Feline King - Grip of the Cat case 1033: // Feline King - Grip of the Cat
{ {
useSkill(5137); useSkill(client, 5137);
break; break;
} }
case 1034: // Magnus the Unicorn - Whiplash case 1034: // Magnus the Unicorn - Whiplash
{ {
useSkill(5138); useSkill(client, 5138);
break; break;
} }
case 1035: // Magnus the Unicorn - Tridal Wave case 1035: // Magnus the Unicorn - Tridal Wave
{ {
useSkill(5139); useSkill(client, 5139);
break; break;
} }
case 1036: // Spectral Lord - Corpse Kaboom case 1036: // Spectral Lord - Corpse Kaboom
{ {
useSkill(5142); useSkill(client, 5142);
break; break;
} }
case 1037: // Spectral Lord - Dicing Death case 1037: // Spectral Lord - Dicing Death
{ {
useSkill(5141); useSkill(client, 5141);
break; break;
} }
case 1038: // Spectral Lord - Force Curse case 1038: // Spectral Lord - Force Curse
{ {
useSkill(5140); useSkill(client, 5140);
break; break;
} }
case 1039: // Swoop Cannon - Cannon Fodder case 1039: // Swoop Cannon - Cannon Fodder
{ {
if (!(target instanceof DoorInstance)) if (!(target instanceof DoorInstance))
{ {
useSkill(5110); useSkill(client, 5110);
} }
break; break;
} }
@@ -641,7 +644,7 @@ public class RequestActionUse extends GameClientPacket
{ {
if (!(target instanceof DoorInstance)) if (!(target instanceof DoorInstance))
{ {
useSkill(5111); useSkill(client, 5111);
} }
break; break;
} }
@@ -655,9 +658,9 @@ public class RequestActionUse extends GameClientPacket
/* /*
* Cast a skill for active pet/servitor. Target is specified as a parameter but can be overwrited or ignored depending on skill type. * Cast a skill for active pet/servitor. Target is specified as a parameter but can be overwrited or ignored depending on skill type.
*/ */
private void useSkill(int skillId, WorldObject target) private void useSkill(GameClient client, int skillId, WorldObject target)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
@@ -700,14 +703,14 @@ public class RequestActionUse extends GameClientPacket
/* /*
* Cast a skill for active pet/servitor. Target is retrieved from owner' target, then validated by overloaded method useSkill(int, Creature). * Cast a skill for active pet/servitor. Target is retrieved from owner' target, then validated by overloaded method useSkill(int, Creature).
*/ */
private void useSkill(int skillId) private void useSkill(GameClient client, int skillId)
{ {
final PlayerInstance player = getClient().getPlayer(); final PlayerInstance player = client.getPlayer();
if (player == null) if (player == null)
{ {
return; return;
} }
useSkill(skillId, player.getTarget()); useSkill(client, skillId, player.getTarget());
} }
} }

Some files were not shown because too many files have changed in this diff Show More