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>
</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/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 kind="src" path="java"/>
<classpathentry kind="output" path="bin"/>

View File

@@ -130,6 +130,9 @@ ScheduledThreadPoolCount = 160
# Default: 120
InstantThreadPoolCount = 120
# Default: 40
UrgentPacketThreadCoreSize = 40
# ---------------------------------------------------------------------------
# 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.zone.type.BossZone;
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.SpecialCamera;
@@ -560,7 +560,7 @@ public class Antharas extends Quest
}
}
protected void broadcastPacket(GameServerPacket mov)
protected void broadcastPacket(IClientOutgoingPacket mov)
{
if (_zone != null)
{

Binary file not shown.

View File

@@ -106,11 +106,9 @@ public class Config
// others
private static final String BANNED_IP_FILE = "./config/others/banned_ip.cfg";
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();
@@ -1129,6 +1127,7 @@ public class Config
public static int MAX_PROTOCOL_REVISION;
public static int SCHEDULED_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 PET_NAME_TEMPLATE;
public static String CLAN_NAME_TEMPLATE;
@@ -1159,18 +1158,6 @@ public class Config
public static long SESSION_TTL;
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()
{
final PropertiesParser accessConfig = new PropertiesParser(ACCESS_CONFIG_FILE);
@@ -1229,6 +1216,7 @@ public class Config
}
SCHEDULED_THREAD_POOL_COUNT = serverConfig.getInt("ScheduledThreadPoolCount", 40);
INSTANT_THREAD_POOL_COUNT = serverConfig.getInt("InstantThreadPoolCount", 20);
IO_PACKET_THREAD_CORE_SIZE = serverConfig.getInt("UrgentPacketThreadCoreSize", 20);
CNAME_TEMPLATE = serverConfig.getString("CnameTemplate", ".*");
PET_NAME_TEMPLATE = serverConfig.getString("PetNameTemplate", ".*");
CLAN_NAME_TEMPLATE = serverConfig.getString("ClanNameTemplate", ".*");
@@ -2962,12 +2950,6 @@ public class Config
public static void loadBanFile()
{
File file = new File(BANNED_IP_FILE);
if (!file.exists())
{
// old file position
file = new File(LEGACY_BANNED_IP);
}
if (file.exists() && file.isFile())
{
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,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
* 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;
/**
* This class ...
* @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 byte[] _decrypt;
private int _off;
public ClientBasePacket(byte[] decrypt, LoginClient client)
public BaseRecievePacket(byte[] decrypt, LoginClient client)
{
_decrypt = decrypt;
_off = 1; // skip packet type id

View File

@@ -14,18 +14,17 @@
* 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.loginserver.network.gameserverpackets;
package org.l2jmobius.commons.network;
/**
* This class ...
* @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 int _off;
public GameServerBasePacket(byte[] decrypt)
public BaseSendablePacket(byte[] decrypt)
{
_decrypt = decrypt;
_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
* 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 -Wooden-
* @author Nos
*/
public class ExOrcMove extends GameServerPacket
public interface IConnectionState
{
@Override
protected void writeImpl()
{
writeC(0xfe);
writeH(0x44);
}
AttributeKey<IConnectionState> ATTRIBUTE_KEY = AttributeKey.valueOf(IConnectionState.class, "");
}

View File

@@ -14,14 +14,16 @@
* 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;
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
* 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>
*/
public interface IMMOExecutor<T extends MMOClient<?>>
public interface IIncomingPacket<T>
{
void execute(ReceivablePacket<T> packet);
}
/**
* 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
* 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>
*/
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()
{
return _client;
}
}
Set<IConnectionState> getConnectionStates();
}

View File

@@ -14,13 +14,16 @@
* 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;
package org.l2jmobius.commons.network;
/**
* @author KenM
* @param <T>
* @author Nos
*/
public interface IClientFactory<T extends MMOClient<?>>
public interface IOutgoingPacket
{
T create(MMOConnection<T> con);
}
/**
* @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,30 +14,28 @@
* 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.serverpackets;
package org.l2jmobius.commons.network.codecs;
import org.l2jmobius.gameserver.model.actor.Creature;
import java.util.List;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
/**
* format dd
* @version $Revision: 1.3.2.1.2.3 $ $Date: 2005/03/27 15:29:57 $
* @author Nos
*/
public class FinishRotation extends GameServerPacket
@Sharable
public class LengthFieldBasedFrameEncoder extends MessageToMessageEncoder<ByteBuf>
{
private final int _heading;
private final int _objectId;
public FinishRotation(Creature creature)
{
_objectId = creature.getObjectId();
_heading = creature.getHeading();
}
@Override
protected final void writeImpl()
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
{
writeC(0x63);
writeD(_objectId);
writeD(_heading);
final ByteBuf buf = ctx.alloc().buffer(2);
final short length = (short) (msg.readableBytes() + 2);
buf.writeShortLE(length);
out.add(buf);
out.add(msg.retain());
}
}

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

@@ -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

@@ -0,0 +1,218 @@
/*
* 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;
/**
* 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
{
private final BlowfishEngine _cipher;
/**
* @param blowfishKey
*/
public NewCrypt(byte[] blowfishKey)
{
_cipher = new BlowfishEngine();
_cipher.init(blowfishKey);
}
public NewCrypt(String key)
{
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)
{
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)
{
// check if size is multiple of 4 and if there is more then only the checksum
if (((size & 3) != 0) || (size <= 4))
{
return false;
}
long chksum = 0;
final int count = size - 4;
long check = -1;
int i;
for (i = offset; i < count; i += 4)
{
check = raw[i] & 0xff;
check |= (raw[i + 1] << 8) & 0xff00;
check |= (raw[i + 2] << 0x10) & 0xff0000;
check |= (raw[i + 3] << 0x18) & 0xff000000;
chksum ^= check;
}
check = raw[i] & 0xff;
check |= (raw[i + 1] << 8) & 0xff00;
check |= (raw[i + 2] << 0x10) & 0xff0000;
check |= (raw[i + 3] << 0x18) & 0xff000000;
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)
{
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)
{
long chksum = 0;
final int count = size - 4;
long ecx;
int i;
for (i = offset; i < count; i += 4)
{
ecx = raw[i] & 0xff;
ecx |= (raw[i + 1] << 8) & 0xff00;
ecx |= (raw[i + 2] << 0x10) & 0xff0000;
ecx |= (raw[i + 3] << 0x18) & 0xff000000;
chksum ^= ecx;
}
ecx = raw[i] & 0xff;
ecx |= (raw[i + 1] << 8) & 0xff00;
ecx |= (raw[i + 2] << 0x10) & 0xff0000;
ecx |= (raw[i + 3] << 0x18) & 0xff000000;
raw[i] = (byte) (chksum & 0xff);
raw[i + 1] = (byte) ((chksum >> 0x08) & 0xff);
raw[i + 2] = (byte) ((chksum >> 0x10) & 0xff);
raw[i + 3] = (byte) ((chksum >> 0x18) & 0xff);
}
/**
* 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 key The 4 bytes (int) XOR key
*/
public static void encXORPass(byte[] raw, int key)
{
encXORPass(raw, 0, raw.length, key);
}
/**
* 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 offset The beginning of the data to be encrypted
* @param size Length of the data to be encrypted
* @param key The 4 bytes (int) XOR key
*/
static void encXORPass(byte[] raw, int offset, int size, int key)
{
final int stop = size - 8;
int pos = 4 + offset;
int edx;
int ecx = key; // Initial xor key
while (pos < stop)
{
edx = raw[pos] & 0xFF;
edx |= (raw[pos + 1] & 0xFF) << 8;
edx |= (raw[pos + 2] & 0xFF) << 16;
edx |= (raw[pos + 3] & 0xFF) << 24;
ecx += edx;
edx ^= ecx;
raw[pos++] = (byte) (edx & 0xFF);
raw[pos++] = (byte) ((edx >> 8) & 0xFF);
raw[pos++] = (byte) ((edx >> 16) & 0xFF);
raw[pos++] = (byte) ((edx >> 24) & 0xFF);
}
raw[pos++] = (byte) (ecx & 0xFF);
raw[pos++] = (byte) ((ecx >> 8) & 0xFF);
raw[pos++] = (byte) ((ecx >> 16) & 0xFF);
raw[pos++] = (byte) ((ecx >> 24) & 0xFF);
}
/**
* 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)
{
for (int i = offset; i < (offset + size); i += 8)
{
_cipher.decryptBlock(raw, i);
}
}
/**
* 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)
{
for (int i = offset; i < (offset + size); i += 8)
{
_cipher.encryptBlock(raw, i);
}
}
}

View File

@@ -0,0 +1,88 @@
/*
* 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 java.math.BigInteger;
import java.security.Key;
import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey;
import java.util.logging.Logger;
public class ScrambledKeyPair
{
private static final Logger LOGGER = Logger.getLogger(ScrambledKeyPair.class.getName());
private final KeyPair _pair;
private final byte[] _scrambledModulus;
public ScrambledKeyPair(KeyPair pPair)
{
_pair = pPair;
_scrambledModulus = scrambleModulus(((RSAPublicKey) _pair.getPublic()).getModulus());
}
private byte[] scrambleModulus(BigInteger modulus)
{
byte[] scrambledMod = modulus.toByteArray();
if ((scrambledMod.length == 0x81) && (scrambledMod[0] == 0x00))
{
final byte[] temp = new byte[0x80];
System.arraycopy(scrambledMod, 1, temp, 0, 0x80);
scrambledMod = temp;
}
// step 1 : 0x4d-0x50 <-> 0x00-0x04
for (int i = 0; i < 4; i++)
{
final byte temp = scrambledMod[0x00 + i];
scrambledMod[0x00 + i] = scrambledMod[0x4d + i];
scrambledMod[0x4d + i] = temp;
}
// step 2 : xor first 0x40 bytes with last 0x40 bytes
for (int i = 0; i < 0x40; i++)
{
scrambledMod[i] = (byte) (scrambledMod[i] ^ scrambledMod[0x40 + i]);
}
// step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38
for (int i = 0; i < 4; i++)
{
scrambledMod[0x0d + i] = (byte) (scrambledMod[0x0d + i] ^ scrambledMod[0x34 + i]);
}
// step 4 : xor last 0x40 bytes with first 0x40 bytes
for (int i = 0; i < 0x40; i++)
{
scrambledMod[0x40 + i] = (byte) (scrambledMod[0x40 + i] ^ scrambledMod[i]);
}
LOGGER.finer("Modulus was scrambled");
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;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.logging.LogManager;
import java.util.logging.Logger;
@@ -31,8 +29,6 @@ import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
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.DeadlockDetector;
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.FortressOfResistance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.GamePacketHandler;
import org.l2jmobius.gameserver.network.ClientNetworkManager;
import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
import org.l2jmobius.gameserver.script.EventDroplist;
import org.l2jmobius.gameserver.script.faenor.FaenorScriptEngine;
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 SelectorThread<GameClient> _selectorThread;
private static LoginServerThread _loginThread;
private static GamePacketHandler _gamePacketHandler;
private static TelnetStatusThread _statusServer;
private static GameServer INSTANCE;
public static final Calendar dateTimeServerStarted = Calendar.getInstance();
public long getUsedMemoryMB()
{
return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576;
}
public GameServer() throws Exception
{
final long serverLoadStart = Chronos.currentTimeMillis();
@@ -476,17 +474,6 @@ public class GameServer
{
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
Util.printSection("Telnet");
if (Config.IS_TELNET_ENABLED)
@@ -500,47 +487,24 @@ public class GameServer
}
Util.printSection("Login");
_loginThread = LoginServerThread.getInstance();
_loginThread.start();
ClientNetworkManager.getInstance().start();
final SelectorConfig sc = new SelectorConfig();
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("*"))
if (Boolean.getBoolean("newLoginServer"))
{
try
{
bindAddress = InetAddress.getByName(Config.GAMESERVER_HOSTNAME);
}
catch (UnknownHostException e1)
{
LOGGER.warning("The GameServer bind address is invalid, using all avaliable IPs. Reason: " + e1);
}
LoginServerNetworkManager.getInstance().connect();
}
else
{
LoginServerThread.getInstance().start();
}
try
{
_selectorThread.openServerSocket(bindAddress, Config.PORT_GAME);
}
catch (IOException e)
{
LOGGER.severe("Failed to open server socket. Reason: " + e);
System.exit(1);
}
_selectorThread.start();
}
public static SelectorThread<GameClient> getSelectorThread()
{
return _selectorThread;
System.gc();
final long totalMem = Runtime.getRuntime().maxMemory() / 1048576;
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 + ".");
LOGGER.info(getClass().getSimpleName() + ": Server loaded in " + ((Chronos.currentTimeMillis() - serverLoadStart) / 1000) + " seconds.");
Toolkit.getDefaultToolkit().beep();
}
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.network.ConnectionState;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.gameserverpackets.AuthRequest;
import org.l2jmobius.gameserver.network.gameserverpackets.BlowFishKey;
import org.l2jmobius.gameserver.network.gameserverpackets.ChangeAccessLevel;
import org.l2jmobius.gameserver.network.gameserverpackets.GameServerBasePacket;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerAuthRequest;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerInGame;
import org.l2jmobius.gameserver.network.gameserverpackets.PlayerLogout;
import org.l2jmobius.gameserver.network.gameserverpackets.ServerStatus;
import org.l2jmobius.gameserver.network.loginserverpackets.AuthResponse;
import org.l2jmobius.gameserver.network.loginserverpackets.InitLS;
import org.l2jmobius.gameserver.network.loginserverpackets.KickPlayer;
import org.l2jmobius.gameserver.network.loginserverpackets.LoginServerFail;
import org.l2jmobius.gameserver.network.loginserverpackets.PlayerAuthResponse;
import org.l2jmobius.gameserver.network.loginserverpackets.game.AuthRequest;
import org.l2jmobius.gameserver.network.loginserverpackets.game.BlowFishKey;
import org.l2jmobius.gameserver.network.loginserverpackets.game.ChangeAccessLevel;
import org.l2jmobius.gameserver.network.loginserverpackets.game.GameServerBasePacket;
import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerAuthRequest;
import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerInGame;
import org.l2jmobius.gameserver.network.loginserverpackets.game.PlayerLogout;
import org.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
import org.l2jmobius.gameserver.network.loginserverpackets.login.AuthResponse;
import org.l2jmobius.gameserver.network.loginserverpackets.login.InitLS;
import org.l2jmobius.gameserver.network.loginserverpackets.login.KickPlayer;
import org.l2jmobius.gameserver.network.loginserverpackets.login.LoginServerFail;
import org.l2jmobius.gameserver.network.loginserverpackets.login.PlayerAuthResponse;
import org.l2jmobius.gameserver.network.serverpackets.AuthLoginFail;
import org.l2jmobius.gameserver.network.serverpackets.CharSelectInfo;
@@ -296,10 +296,10 @@ public class LoginServerThread extends Thread
{
final PlayerInGame pig = new PlayerInGame(par.getAccount());
sendPacket(pig);
wcToRemove.gameClient.setState(ConnectionState.AUTHENTICATED);
wcToRemove.gameClient.setConnectionState(ConnectionState.AUTHENTICATED);
wcToRemove.gameClient.setSessionId(wcToRemove.session);
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());
}
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.sevensigns.SevenSigns;
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.gameserverpackets.ServerStatus;
import org.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
import org.l2jmobius.gameserver.network.serverpackets.ServerClose;
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
{
// GameServer.getSelectorThread().setDaemon(true);
GameServer.getSelectorThread().shutdown();
ClientNetworkManager.getInstance().stop();
EventLoopGroupManager.getInstance().shutdown();
LOGGER.info("Game Server: Selector thread has been shut down.");
}
catch (Throwable t)
{
// ignore
}
// stop all threadpolls
@@ -530,7 +535,7 @@ public class Shutdown extends Thread
if (player.getClient() != null)
{
player.getClient().sendPacket(ServerClose.STATIC_PACKET);
player.getClient().close(0);
player.getClient().close(false);
player.getClient().setPlayer(null);
player.setClient(null);
}

View File

@@ -201,11 +201,11 @@ public class OfflineTradeTable
PlayerInstance player = null;
try
{
final GameClient client = new GameClient(null);
final GameClient client = new GameClient();
player = PlayerInstance.load(rs.getInt("charId"));
client.setPlayer(player);
client.setAccountName(player.getAccountName());
client.setState(ConnectionState.IN_GAME);
client.setConnectionState(ConnectionState.IN_GAME);
player.setClient(client);
player.setOfflineMode(true);
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.actor.instance.PlayerInstance;
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;
/**
@@ -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))
{

View File

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

View File

@@ -1195,12 +1195,12 @@ public class AdminEditChar implements IAdminCommandHandler
final Map<String, Integer> dualboxIPs = new HashMap<>();
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;
}
ip = player.getClient().getConnection().getInetAddress().getHostAddress();
ip = player.getClient().getConnectionAddress().getHostAddress();
if (ipMap.get(ip) == null)
{
ipMap.put(ip, new ArrayList<PlayerInstance>());
@@ -1260,12 +1260,12 @@ public class AdminEditChar implements IAdminCommandHandler
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;
}
ip = player.getClient().getConnection().getInetAddress().getHostAddress();
ip = player.getClient().getConnectionAddress().getHostAddress();
if (ip.equals(ipAdress))
{
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.serverpackets.Earthquake;
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.PlaySound;
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)
{
GameServerPacket packet = null;
IClientOutgoingPacket packet = null;
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.items.instance.ItemInstance;
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.UserInfo;
import org.l2jmobius.gameserver.util.BuilderUtil;
import org.l2jmobius.gameserver.util.IllegalPlayerAction;
import org.l2jmobius.gameserver.util.Util;
@@ -219,8 +217,7 @@ public class AdminEnchant implements IAdminCommandHandler
final InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(itemInstance);
player.sendPacket(iu);
player.broadcastPacket(new CharInfo(player));
player.sendPacket(new UserInfo(player));
player.broadcastUserInfo();
// informations
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.handler.IAdminCommandHandler;
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.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());
confirm.addString(activePlayer.getName());
confirm.addZoneName(activePlayer.getX(), activePlayer.getY(), activePlayer.getZ());
confirm.addTime(30000);
confirm.addTime(30000, targetPlayer);
confirm.addRequesterId(activePlayer.getObjectId());
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.network.SystemMessageId;
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.SystemMessage;
@@ -179,7 +179,7 @@ public class PetitionManager
return _type.toString().replace("_", " ");
}
public void sendPetitionerPacket(GameServerPacket responsePacket)
public void sendPetitionerPacket(IClientOutgoingPacket responsePacket)
{
if ((_petitioner == null) || !_petitioner.isOnline())
{
@@ -189,7 +189,7 @@ public class PetitionManager
_petitioner.sendPacket(responsePacket);
}
public void sendResponderPacket(GameServerPacket responsePacket)
public void sendResponderPacket(IClientOutgoingPacket responsePacket)
{
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.ExCloseMPCC;
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;
/**
@@ -147,7 +147,7 @@ public class CommandChannel
* Broadcast packet to every channel member
* @param gsp
*/
public void broadcastToChannelMembers(GameServerPacket gsp)
public void broadcastToChannelMembers(IClientOutgoingPacket gsp)
{
if ((_parties != null) && !_parties.isEmpty())
{

View File

@@ -176,7 +176,7 @@ public class MacroList
}
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);
}
}

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.ExCloseMPCC;
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.PartySmallWindowAdd;
import org.l2jmobius.gameserver.network.serverpackets.PartySmallWindowAll;
@@ -281,7 +281,7 @@ public class Party
* Broadcasts packet to every party member
* @param msg
*/
public void broadcastToPartyMembers(GameServerPacket msg)
public void broadcastToPartyMembers(IClientOutgoingPacket msg)
{
for (PlayerInstance member : _members)
{
@@ -327,7 +327,7 @@ public class Party
* @param player
* @param msg
*/
public void broadcastToPartyMembers(PlayerInstance player, GameServerPacket msg)
public void broadcastToPartyMembers(PlayerInstance player, IClientOutgoingPacket msg)
{
for (PlayerInstance member : _members)
{

View File

@@ -19,7 +19,7 @@ package org.l2jmobius.gameserver.model;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
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;
/**
@@ -34,7 +34,7 @@ public class Request
protected PlayerInstance _partner;
protected boolean _isRequestor;
protected boolean _isAnswerer;
protected GameClientPacket _requestPacket;
protected IClientIncomingPacket _requestPacket;
public Request(PlayerInstance player)
{
@@ -70,7 +70,7 @@ public class Request
* Set the packet incomed from requester.
* @param packet
*/
private synchronized void setRequestPacket(GameClientPacket packet)
private synchronized void setRequestPacket(IClientIncomingPacket packet)
{
_requestPacket = packet;
}
@@ -78,7 +78,7 @@ public class Request
/**
* @return the packet originally incomed from requester.
*/
public GameClientPacket getRequestPacket()
public IClientIncomingPacket getRequestPacket()
{
return _requestPacket;
}
@@ -89,7 +89,7 @@ public class Request
* @param packet
* @return
*/
public synchronized boolean setRequest(PlayerInstance partner, GameClientPacket packet)
public synchronized boolean setRequest(PlayerInstance partner, IClientIncomingPacket packet)
{
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.CharMoveToLocation;
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.MagicSkillCanceld;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
@@ -366,7 +366,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
getAttackByList().add(creature);
}
public void broadcastPacket(GameServerPacket mov)
public void broadcastPacket(IClientOutgoingPacket mov)
{
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())
{
@@ -507,7 +507,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder
* <li>PlayerInstance</li><br>
* @param mov the mov
*/
public void sendPacket(GameServerPacket mov)
public void sendPacket(IClientOutgoingPacket mov)
{
// default implementation
}

View File

@@ -526,7 +526,7 @@ public class DoorInstance extends Creature
// Send a Server->Client packet MyTargetSelected to the PlayerInstance player
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
player.sendPacket(new ValidateLocation(this));
@@ -577,7 +577,7 @@ public class DoorInstance extends Creature
player.sendPacket(new MyTargetSelected(getObjectId(), player.getLevel()));
if (isAutoAttackable(player))
{
player.sendPacket(new DoorStatusUpdate(this));
player.sendPacket(new DoorStatusUpdate(this, player));
}
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
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()));
if (isAutoAttackable(player))
{
player.sendPacket(new DoorStatusUpdate(this));
player.sendPacket(new DoorStatusUpdate(this, player));
}
final NpcHtmlMessage reply = new NpcHtmlMessage(5);
@@ -627,10 +627,9 @@ public class DoorInstance extends Creature
return;
}
final DoorStatusUpdate su = new DoorStatusUpdate(this);
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.ExPCCafePointInfo;
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.IClientOutgoingPacket;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.ItemList;
import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
@@ -644,7 +644,7 @@ public class PlayerInstance extends Playable
@Override
public void doAttack(Creature target)
{
if (Creature.isInsidePeaceZone(PlayerInstance.this, target))
if (isInsidePeaceZone(PlayerInstance.this, target))
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
@@ -2076,7 +2076,7 @@ public class PlayerInstance extends Playable
setOverloaded(false);
_curWeightPenalty = 0;
super.removeSkill(getKnownSkill(4270));
Broadcast.toKnownPlayers(this, new CharInfo(this));
Broadcast.toKnownPlayers(this, new CharInfo(this, isGM() && getAppearance().isInvisible()));
}
else
{
@@ -2120,7 +2120,7 @@ public class PlayerInstance extends Playable
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
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
public void broadcastPacket(GameServerPacket mov)
public void broadcastPacket(IClientOutgoingPacket mov)
{
final boolean isCharInfo = mov instanceof CharInfo;
if (!isCharInfo)
@@ -4916,7 +4945,7 @@ public class PlayerInstance extends Playable
}
@Override
public void broadcastPacket(GameServerPacket mov, int radius)
public void broadcastPacket(IClientOutgoingPacket mov, int radius)
{
final boolean isCharInfo = mov instanceof CharInfo;
if (!isCharInfo)
@@ -6211,8 +6240,8 @@ public class PlayerInstance extends Playable
// Anti FARM same IP
if (Config.ANTI_FARM_IP_ENABLED && (_client != null) && (targetPlayer.getClient() != null))
{
final String ip1 = _client.getConnection().getInetAddress().getHostAddress();
final String ip2 = targetPlayer.getClient().getConnection().getInetAddress().getHostAddress();
final String ip1 = _client.getConnectionAddress().getHostAddress();
final String ip2 = targetPlayer.getClient().getConnectionAddress().getHostAddress();
if (ip1.equals(ip2))
{
sendMessage("Farm is punishable with Ban! GM informed.");
@@ -6232,9 +6261,9 @@ public class PlayerInstance extends Playable
private void addItemReward(PlayerInstance targetPlayer)
{
// 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
{
@@ -11240,7 +11269,7 @@ public class PlayerInstance extends Playable
* Send a Server->Client packet StatusUpdate to the PlayerInstance.
*/
@Override
public void sendPacket(GameServerPacket packet)
public void sendPacket(IClientOutgoingPacket packet)
{
if (_client != null)
{
@@ -14886,12 +14915,12 @@ public class PlayerInstance extends Playable
boolean canMultiBox = true;
int boxCount = 1;
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())
{
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++;
activeBoxes.add(player.getName());
@@ -14923,12 +14952,12 @@ public class PlayerInstance extends Playable
*/
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())
{
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._activeBoxCharacters = _activeBoxCharacters;

View File

@@ -139,7 +139,7 @@ public class PlayerKnownList extends PlayableKnownList
{
activeChar.sendPacket(new DoorInfo((DoorInstance) object, false));
}
activeChar.sendPacket(new DoorStatusUpdate((DoorInstance) object));
activeChar.sendPacket(new DoorStatusUpdate((DoorInstance) object, activeChar));
}
else if (object.isBoat())
{
@@ -180,7 +180,7 @@ public class PlayerKnownList extends PlayableKnownList
if (otherPlayer.isInBoat())
{
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);
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
{
activeChar.sendPacket(new CharInfo(otherPlayer));
activeChar.sendPacket(new CharInfo(otherPlayer, activeChar.isGM() && otherPlayer.getAppearance().isInvisible()));
final int relation = otherPlayer.getRelation(activeChar);
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.network.SystemMessageId;
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.PledgeReceiveSubPledgeCreated;
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)
{
@@ -1141,7 +1141,7 @@ public class Clan
}
}
public void broadcastToOnlineMembers(GameServerPacket packet)
public void broadcastToOnlineMembers(IClientOutgoingPacket packet)
{
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())
{

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.zone.ZoneId;
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.SiegeInfo;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
@@ -784,7 +784,7 @@ public class FortSiege
*/
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)
{
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.actor.Creature;
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
@@ -331,7 +331,7 @@ public abstract class ZoneType
* Broadcasts packet to all players inside the zone
* @param packet
*/
public void broadcastPacket(GameServerPacket packet)
public void broadcastPacket(IClientOutgoingPacket packet)
{
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

@@ -14,48 +14,28 @@
* 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;
package org.l2jmobius.gameserver.network;
import java.nio.BufferOverflowException;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.NetworkManager;
/**
* @author Forsaiken
* @author Nos
*/
public class NioNetStringBuffer
public class ClientNetworkManager extends NetworkManager
{
private final char[] _buf;
private final int _size;
private int _len;
public NioNetStringBuffer(int size)
protected ClientNetworkManager()
{
_buf = new char[size];
_size = size;
_len = 0;
super(EventLoopGroupManager.getInstance().getBossGroup(), EventLoopGroupManager.getInstance().getWorkerGroup(), new ClientInitializer(), Config.GAMESERVER_HOSTNAME, Config.PORT_GAME);
}
public void clear()
public static ClientNetworkManager getInstance()
{
_len = 0;
return SingletonHolder.INSTANCE;
}
public void append(char c)
private static class SingletonHolder
{
if (_len < _size)
{
_buf[_len++] = c;
}
else
{
throw new BufferOverflowException();
}
protected static final ClientNetworkManager INSTANCE = new ClientNetworkManager();
}
@Override
public String toString()
{
return new String(_buf, 0, _len);
}
}
}

View File

@@ -16,13 +16,23 @@
*/
package org.l2jmobius.gameserver.network;
import org.l2jmobius.commons.network.IConnectionState;
/**
* @author KenM
*/
public enum ConnectionState
public enum ConnectionState implements IConnectionState
{
CONNECTED,
DISCONNECTED,
CLOSING,
AUTHENTICATED,
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;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.commons.mmocore.MMOClient;
import org.l2jmobius.commons.mmocore.MMOConnection;
import org.l2jmobius.commons.mmocore.ReceivablePacket;
import org.l2jmobius.commons.network.ChannelInboundHandler;
import org.l2jmobius.commons.network.ICrypt;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.LoginServerThread;
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.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId;
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.LeaveWorld;
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.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_ACCOUNTING = Logger.getLogger("accounting");
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 ReentrantLock _playerLock = new ReentrantLock();
private final List<Integer> _charSlotMapping = new ArrayList<>();
private final ReentrantLock _queueLock = new ReentrantLock();
private final ArrayBlockingQueue<ReceivablePacket<GameClient>> _packetQueue;
private final GameCrypt _crypt;
private ConnectionState _state;
private final Crypt _crypt;
private InetAddress _addr;
private Channel _channel;
private String _accountName;
private SessionKey _sessionId;
private ScheduledFuture<?> _cleanupTask = null;
private PlayerInstance _player;
private final List<Integer> _charSlotMapping = new ArrayList<>();
private volatile boolean _isDetached = false;
private boolean _isAuthedGG;
private int _protocolVersion;
protected PlayerInstance _player;
private ScheduledFuture<?> _cleanupTask = null;
public GameClient(MMOConnection<GameClient> con)
public GameClient()
{
super(con);
_state = ConnectionState.CONNECTED;
_crypt = new GameCrypt();
_packetQueue = new ArrayBlockingQueue<>(Config.CLIENT_PACKET_QUEUE_SIZE);
_crypt = new Crypt(this);
}
@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()
@@ -104,33 +192,13 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
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;
}
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;
return _addr;
}
public PlayerInstance getPlayer()
@@ -152,16 +220,16 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return _playerLock;
}
public boolean isAuthedGG()
{
return _isAuthedGG;
}
public void setGameGuardOk(boolean value)
{
_isAuthedGG = value;
}
public boolean isAuthedGG()
{
return _isAuthedGG;
}
public void setAccountName(String pAccountName)
{
_accountName = pAccountName;
@@ -182,18 +250,26 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return _sessionId;
}
public void sendPacket(GameServerPacket gsp)
public void sendPacket(IClientOutgoingPacket packet)
{
if (_isDetached)
if (_isDetached || (packet == null))
{
return;
}
if (getConnection() != null)
{
getConnection().sendPacket(gsp);
gsp.runImpl();
}
// Write into the channel.
_channel.writeAndFlush(packet);
// Run packet implementation.
packet.runImpl(_player);
}
/**
* @param smId
*/
public void sendPacket(SystemMessageId smId)
{
sendPacket(new SystemMessage(smId));
}
public boolean isDetached()
@@ -208,17 +284,17 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
/**
* Method to handle character deletion
* @param charslot
* @param characterSlot
* @return a byte:
* <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>1: character is member of a clan, but not clan leader
* <li>2: character is clan leader
*/
public byte markToDeleteChar(int charslot)
public byte markToDeleteChar(int characterSlot)
{
final int objid = getObjectIdForSlot(charslot);
if (objid < 0)
final int objectId = getObjectIdForSlot(characterSlot);
if (objectId < 0)
{
return -1;
}
@@ -228,7 +304,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
try (Connection con = DatabaseFactory.getConnection())
{
PreparedStatement statement = con.prepareStatement("SELECT clanId from characters WHERE charId=?");
statement.setInt(1, objid);
statement.setInt(1, objectId);
final ResultSet rs = statement.executeQuery();
rs.next();
@@ -241,7 +317,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{
answer = 0; // jeezes!
}
else if (clan.getLeaderId() == objid)
else if (clan.getLeaderId() == objectId)
{
answer = 2;
}
@@ -256,13 +332,13 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{
if (Config.DELETE_DAYS == 0)
{
deleteCharByObjId(objid);
deleteCharByObjId(objectId);
}
else
{
statement = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?");
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.close();
rs.close();
@@ -283,11 +359,11 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
return answer;
}
public void markRestoredChar(int charslot)
public void markRestoredChar(int characterSlot)
{
// have to make sure active character must be nulled
final int objid = getObjectIdForSlot(charslot);
if (objid < 0)
final int objectId = getObjectIdForSlot(characterSlot);
if (objectId < 0)
{
return;
}
@@ -295,7 +371,7 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
try (Connection con = DatabaseFactory.getConnection())
{
final PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?");
statement.setInt(1, objid);
statement.setInt(1, objectId);
statement.execute();
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;
}
try (Connection con = DatabaseFactory.getConnection())
{
PreparedStatement statement;
PreparedStatement ps;
statement = con.prepareStatement("DELETE FROM character_friends WHERE char_id=? OR friend_id=?");
statement.setInt(1, objid);
statement.setInt(2, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_friends WHERE char_id=? OR friend_id=?");
ps.setInt(1, objectId);
ps.setInt(2, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_macroses WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_macroses WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_quests WHERE char_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_quests WHERE char_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM character_subclasses WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM character_subclasses WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM heroes WHERE charId=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM seven_signs WHERE char_obj_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM seven_signs WHERE char_obj_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM items WHERE owner_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
statement = con.prepareStatement("DELETE FROM characters WHERE charId=?");
statement.setInt(1, objid);
statement.execute();
statement.close();
ps = con.prepareStatement("DELETE FROM characters WHERE charId=?");
ps.setInt(1, objectId);
ps.execute();
ps.close();
}
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);
if (objId < 0)
final int objectId = getObjectIdForSlot(characterSlot);
if (objectId < 0)
{
return null;
}
PlayerInstance character = World.getInstance().getPlayer(objId);
if (character != null)
PlayerInstance player = World.getInstance().getPlayer(objectId);
if (player != null)
{
// 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
{
character.deleteMe();
player.deleteMe();
try
{
character.store();
player.store();
}
catch (Exception e2)
{
@@ -436,8 +512,8 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
}
}
character = PlayerInstance.load(objId);
return character;
player = PlayerInstance.load(objectId);
return player;
}
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)
{
if ((charslot < 0) || (charslot >= _charSlotMapping.size()))
@@ -471,55 +539,9 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
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()
{
final InetAddress address = getConnection().getInetAddress();
final InetAddress address = _addr;
String ip;
if (address == null)
{
@@ -540,20 +562,22 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{
try
{
switch (_state)
final InetAddress address = _addr;
final ConnectionState state = (ConnectionState) getConnectionState();
switch (state)
{
case CONNECTED:
{
return "[IP: " + getIpAddress() + "]";
return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
}
case AUTHENTICATED:
{
return "[Account: " + _accountName + " - IP: " + getIpAddress() + "]";
return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
}
case ENTERING:
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:
{
@@ -777,72 +801,6 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
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)
{
_protocolVersion = version;
@@ -852,4 +810,9 @@ public class GameClient extends MMOClient<MMOConnection<GameClient>> implements
{
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 org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
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.serverpackets.ActionFailed;
@SuppressWarnings("unused")
public class Action extends GameClientPacket
public class Action implements IClientIncomingPacket
{
private static final Logger LOGGER = Logger.getLogger(Action.class.getName());
private int _objectId;
@SuppressWarnings("unused")
private int _originX;
@SuppressWarnings("unused")
private int _originY;
@SuppressWarnings("unused")
private int _originZ;
private int _actionId;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_objectId = readD(); // Target object Identifier
_originX = readD();
_originY = readD();
_originZ = readD();
_actionId = readC(); // Action identifier : 0-Simple click, 1-Shift click
_objectId = packet.readD(); // Target object Identifier
_originX = packet.readD();
_originY = packet.readD();
_originZ = packet.readD();
_actionId = packet.readC(); // Action identifier : 0-Simple click, 1-Shift click
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
// Get the current PlayerInstance of the player
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
@@ -76,21 +81,21 @@ public class Action extends GameClientPacket
// pressing e.g. pickup many times quickly would get you here
if (obj == null)
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
client.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Players can't interact with objects in the other instances except from multiverse
if ((obj.getInstanceId() != player.getInstanceId()) && (player.getInstanceId() != -1))
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
client.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Only GMs can directly interact with invisible characters
if ((obj instanceof PlayerInstance) && (((PlayerInstance) obj).getAppearance().isInvisible()) && !player.isGM())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
client.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
@@ -112,7 +117,7 @@ public class Action extends GameClientPacket
}
else
{
obj.onActionShift(getClient());
obj.onActionShift(client);
}
break;
}
@@ -120,14 +125,14 @@ public class Action extends GameClientPacket
{
// Invalid action detected (probably client cheating), LOGGER this
LOGGER.warning("Character: " + player.getName() + " requested invalid action: " + _actionId);
getClient().sendPacket(ActionFailed.STATIC_PACKET);
client.sendPacket(ActionFailed.STATIC_PACKET);
break;
}
}
}
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 org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.TradeList;
import org.l2jmobius.gameserver.model.World;
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.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.TradeOtherAdd;
import org.l2jmobius.gameserver.network.serverpackets.TradeOwnAdd;
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 int _tradeId;
@@ -35,17 +37,18 @@ public class AddTradeItem extends GameClientPacket
private int _count;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_tradeId = readD();
_objectId = readD();
_count = readD();
_tradeId = packet.readD();
_objectId = packet.readD();
_count = packet.readD();
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -16,22 +16,25 @@
*/
package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
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;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_typeRun = readD() == 1;
_typeRun = packet.readD() == 1;
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;

View File

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

View File

@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.SkillTable;
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.util.Util;
public class CharacterCreate extends GameClientPacket
public class CharacterCreate implements IClientIncomingPacket
{
private static final Logger LOGGER = Logger.getLogger(CharacterCreate.class.getName());
@@ -72,29 +73,30 @@ public class CharacterCreate extends GameClientPacket
private int _wit;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_name = readS();
_race = readD();
_sex = (byte) readD();
_classId = readD();
_int = readD();
_str = readD();
_con = readD();
_men = readD();
_dex = readD();
_wit = readD();
_hairStyle = (byte) readD();
_hairColor = (byte) readD();
_face = (byte) readD();
_name = packet.readS();
_race = packet.readD();
_sex = (byte) packet.readD();
_classId = packet.readD();
_int = packet.readD();
_str = packet.readD();
_con = packet.readD();
_men = packet.readD();
_dex = packet.readD();
_wit = packet.readD();
_hairStyle = (byte) packet.readD();
_hairColor = (byte) packet.readD();
_face = (byte) packet.readD();
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
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;
}
@@ -104,7 +106,7 @@ public class CharacterCreate extends GameClientPacket
{
if (_name.toLowerCase().contains(st.toLowerCase()))
{
getClient().sendPacket(new CharCreateFail(CharCreateFail.REASON_INCORRECT_NAME));
client.sendPacket(new CharCreateFail(CharCreateFail.REASON_INCORRECT_NAME));
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.
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;
}
else if (CharNameTable.getInstance().doesCharNameExist(_name))
{
sendPacket(new CharCreateFail(CharCreateFail.REASON_NAME_ALREADY_EXISTS));
client.sendPacket(new CharCreateFail(CharCreateFail.REASON_NAME_ALREADY_EXISTS));
return;
}
template = PlayerTemplateData.getInstance().getTemplate(_classId);
if ((template == null) || (template.getClassBaseLevel() > 1))
{
sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED));
client.sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED));
return;
}
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.setCurrentCp(template.baseCpMax);
newChar.setCurrentCp(0); // L2Off like
@@ -143,8 +145,8 @@ public class CharacterCreate extends GameClientPacket
// newChar.setMaxLoad(template.baseLoad);
// send acknowledgement
sendPacket(new CharCreateOk()); // Success
initNewChar(getClient(), newChar);
client.sendPacket(new CharCreateOk()); // Success
initNewChar(client, newChar);
}
}
@@ -160,7 +162,7 @@ public class CharacterCreate extends GameClientPacket
}
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(".*");
}
@@ -297,7 +299,7 @@ public class CharacterCreate extends GameClientPacket
// Send char list
final CharSelectInfo cl = new CharSelectInfo(client.getAccountName(), client.getSessionId().playOkID1);
client.getConnection().sendPacket(cl);
client.sendPacket(cl);
client.setCharSelection(cl.getCharInfo());
}

View File

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

View File

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

View File

@@ -18,13 +18,15 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
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.CharSelected;
@SuppressWarnings("unused")
public class CharacterSelected extends GameClientPacket
public class CharacterSelected implements IClientIncomingPacket
{
private static final Logger LOGGER = Logger.getLogger(CharacterSelected.class.getName());
@@ -35,41 +37,42 @@ public class CharacterSelected extends GameClientPacket
private int _unk4;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_charSlot = readD();
_unk1 = readH();
_unk2 = readD();
_unk3 = readD();
_unk4 = readD();
_charSlot = packet.readD();
_unk1 = packet.readH();
_unk2 = packet.readD();
_unk3 = packet.readD();
_unk4 = packet.readD();
return true;
}
@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
// 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
// playLogFile(getConnection()); // try to play LOGGER file
if (!getClient().getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterSelect"))
if (!client.getFloodProtectors().getCharacterSelect().tryPerformAction("CharacterSelect"))
{
return;
}
// 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
{
// 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
final PlayerInstance cha = getClient().loadCharFromDisk(_charSlot);
final PlayerInstance cha = client.loadCharFromDisk(_charSlot);
if (cha == null)
{
LOGGER.warning(getType() + ": Character could not be loaded (slot:" + _charSlot + ")");
sendPacket(ActionFailed.STATIC_PACKET);
LOGGER.warning("Character could not be loaded (slot:" + _charSlot + ")");
client.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
@@ -79,10 +82,10 @@ public class CharacterSelected extends GameClientPacket
return;
}
cha.setClient(getClient());
getClient().setPlayer(cha);
getClient().setState(ConnectionState.ENTERING);
sendPacket(new CharSelected(cha, getClient().getSessionId().playOkID1));
cha.setClient(client);
client.setPlayer(cha);
client.setConnectionState(ConnectionState.ENTERING);
client.sendPacket(new CharSelected(cha, client.getSessionId().playOkID1));
}
}
catch (Exception e)
@@ -91,7 +94,7 @@ public class CharacterSelected extends GameClientPacket
}
finally
{
getClient().getPlayerLock().unlock();
client.getPlayerLock().unlock();
}
}
}

View File

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

View File

@@ -26,6 +26,7 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.GameTimeController;
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.zone.ZoneId;
import org.l2jmobius.gameserver.network.ConnectionState;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ClientSetTime;
import org.l2jmobius.gameserver.network.serverpackets.CreatureSay;
@@ -96,7 +98,7 @@ import org.l2jmobius.gameserver.util.Util;
/**
* Enter World Packet Handler
*/
public class EnterWorld extends GameClientPacket
public class EnterWorld implements IClientIncomingPacket
{
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");
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
// this is just a trigger packet. it has no content
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
LOGGER.warning("EnterWorld failed! player is null...");
getClient().closeNow();
client.closeNow();
return;
}
getClient().setState(ConnectionState.IN_GAME);
client.setConnectionState(ConnectionState.IN_GAME);
// Set lock at login
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())))
{
LOGGER.warning("Charname: " + player.getName() + " is invalid. EnterWorld failed.");
getClient().closeNow();
client.closeNow();
return;
}
@@ -169,7 +171,7 @@ public class EnterWorld extends GameClientPacket
html.setFile("data/html/clan_notice.htm");
html.replace("%clan_name%", player.getClan().getName());
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));
if (SevenSigns.getInstance().isSealValidationPeriod())
{
sendPacket(new SignsSky());
player.sendPacket(new SignsSky());
}
// 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]: Respect our server rules.");
// 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
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has Overenchanted item! Kicked! ", Config.DEFAULT_PUNISH);
// Logger in console
@@ -254,12 +256,12 @@ public class EnterWorld extends GameClientPacket
player.getMacroses().sendUpdate();
// Send packets info
sendPacket(new ClientSetTime()); // SetClientTime
sendPacket(new UserInfo(player));
sendPacket(new HennaInfo(player));
sendPacket(new FriendList(player));
sendPacket(new ItemList(player, false));
sendPacket(new ShortCutInit(player));
player.sendPacket(new ClientSetTime()); // SetClientTime
player.sendPacket(new UserInfo(player));
player.sendPacket(new HennaInfo(player));
player.sendPacket(new FriendList(player));
player.sendPacket(new ItemList(player, false));
player.sendPacket(new ShortCutInit(player));
// Reload inventory to give SA skill
player.getInventory().reloadEquippedItems();
@@ -292,13 +294,13 @@ public class EnterWorld extends GameClientPacket
// sendPacket(ui);
if ((player.getClanId() != 0) && (player.getClan() != null))
{
sendPacket(new PledgeShowMemberListAll(player.getClan(), player));
sendPacket(new PledgeStatusChanged(player.getClan()));
player.sendPacket(new PledgeShowMemberListAll(player.getClan(), player));
player.sendPacket(new PledgeStatusChanged(player.getClan()));
}
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)
@@ -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);
sm.addSkillName(294);
sendPacket(sm);
player.sendPacket(sm);
}
else
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR);
sm.addSkillName(294);
sendPacket(sm);
player.sendPacket(sm);
}
}
}
@@ -499,7 +501,7 @@ public class EnterWorld extends GameClientPacket
}
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(".*");
}
@@ -604,7 +606,7 @@ public class EnterWorld extends GameClientPacket
final NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(Welcome_Path);
html.replace("%name%", player.getName());
sendPacket(html);
player.sendPacket(html);
}
}
@@ -706,11 +708,11 @@ public class EnterWorld extends GameClientPacket
player.updateNameTitleColor();
sendPacket(new UserInfo(player));
sendPacket(new HennaInfo(player));
sendPacket(new FriendList(player));
sendPacket(new ItemList(player, false));
sendPacket(new ShortCutInit(player));
player.sendPacket(new UserInfo(player));
player.sendPacket(new HennaInfo(player));
player.sendPacket(new FriendList(player));
player.sendPacket(new ItemList(player, false));
player.sendPacket(new ShortCutInit(player));
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;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.StopRotation;
@SuppressWarnings("unused")
public class FinishRotating extends GameClientPacket
public class FinishRotating implements IClientIncomingPacket
{
private int _degree;
private int _unknown;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_degree = readD();
_unknown = readD();
_degree = packet.readD();
packet.readD(); // Unknown.
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
if (!Config.ENABLE_KEYBOARD_MOVEMENT)
{
return;
}
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
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;
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..........
*/
public class GameGuardReply extends GameClientPacket
public class GameGuardReply implements IClientIncomingPacket
{
private final int[] _reply = new int[4];
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_reply[0] = readD();
_reply[1] = readD();
_reply[2] = readD();
_reply[3] = readD();
_reply[0] = packet.readD();
_reply[1] = packet.readD();
_reply[2] = packet.readD();
_reply[3] = packet.readD();
return true;
}
@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;
import java.util.logging.Logger;
import org.l2jmobius.commons.network.IIncomingPacket;
import org.l2jmobius.gameserver.network.GameClient;
/**
* @author zabbix Lets drink to code!
* Packets received by the game serv@Override er from clients
* @author KenM
*/
public class DummyPacket extends GameClientPacket
public interface IClientIncomingPacket extends IIncomingPacket<GameClient>
{
@Override
protected void readImpl()
{
}
@Override
public void runImpl()
{
}
}
Logger LOGGER = Logger.getLogger(IClientIncomingPacket.class.getName());
}

View File

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

View File

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

View File

@@ -16,27 +16,26 @@
*/
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
* @author -Wooden-
*/
@SuppressWarnings("unused")
public class MoveWithDelta extends GameClientPacket
public class MoveWithDelta implements IClientIncomingPacket
{
private int _dx;
private int _dy;
private int _dz;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_dx = readD();
_dy = readD();
_dz = readD();
packet.readD(); // dx
packet.readD(); // dy
packet.readD(); // dz
return true;
}
@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 org.l2jmobius.Config;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.MultisellData;
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.MultiSellIngredient;
import org.l2jmobius.gameserver.model.multisell.MultiSellListContainer;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.ItemList;
@@ -43,7 +45,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* The Class MultiSellChoose.
*/
public class MultiSellChoose extends GameClientPacket
public class MultiSellChoose implements IClientIncomingPacket
{
private static final Logger LOGGER = Logger.getLogger(MultiSellChoose.class.getName());
private int _listId;
@@ -53,27 +55,28 @@ public class MultiSellChoose extends GameClientPacket
private int _transactionTax; // local handling of taxation
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_listId = readD();
_entryId = readD();
_amount = readD();
// _enchantment = readH(); // Commented this line because it did NOT work!
_listId = packet.readD();
_entryId = packet.readD();
_amount = packet.readD();
// _enchantment = packet.readH(); // Commented this line because it did NOT work!
_enchantment = _entryId % 100000;
_entryId = _entryId / 100000;
_transactionTax = 0; // Initialize tax amount to 0...
return true;
}
@Override
public void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
if (!getClient().getFloodProtectors().getMultiSell().tryPerformAction("multisell choose"))
if (!client.getFloodProtectors().getMultiSell().tryPerformAction("multisell choose"))
{
player.setMultiSellId(-1);
return;

View File

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

View File

@@ -16,19 +16,22 @@
*/
package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
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
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;

View File

@@ -19,37 +19,40 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
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;
public class ProtocolVersion extends GameClientPacket
public class ProtocolVersion implements IClientIncomingPacket
{
static Logger LOGGER = Logger.getLogger(ProtocolVersion.class.getName());
private int _version;
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_version = readD();
_version = packet.readD();
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
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))
{
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);
getClient().close((GameServerPacket) null);
client.close(new KeyPacket(client.enableCrypt(), 0));
}
else
{
getClient().setProtocolVersion(_version);
getClient().sendPacket(new KeyPacket(getClient().enableCrypt()));
client.sendPacket(new KeyPacket(client.enableCrypt(), 1));
client.setProtocolVersion(_version);
}
}
}

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.GameTimeController;
import org.l2jmobius.gameserver.ai.CtrlIntention;
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.itemcontainer.Inventory;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
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.SystemMessage;
public class RequestActionUse extends GameClientPacket
public class RequestActionUse implements IClientIncomingPacket
{
private static final Logger LOGGER = Logger.getLogger(RequestActionUse.class.getName());
@@ -70,17 +72,18 @@ public class RequestActionUse extends GameClientPacket
}
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_actionId = readD();
_ctrlPressed = readD() == 1;
_shiftPressed = readC() == 1;
_actionId = packet.readD();
_ctrlPressed = packet.readD() == 1;
_shiftPressed = packet.readC() == 1;
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
final PlayerInstance player = getClient().getPlayer();
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
@@ -89,14 +92,14 @@ public class RequestActionUse extends GameClientPacket
// dont do anything if player is dead
if ((_actionId != 0) && player.isAlikeDead())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// don't do anything if player is confused
if (player.isOutOfControl())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
@@ -107,7 +110,7 @@ public class RequestActionUse extends GameClientPacket
}
else if (player.isCastingNow())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
@@ -332,31 +335,31 @@ public class RequestActionUse extends GameClientPacket
}
case 32: // Wild Hog Cannon - Mode Change
{
useSkill(4230);
useSkill(client, 4230);
break;
}
case 36: // Soulless - Toxic Smoke
{
useSkill(4259);
useSkill(client, 4259);
break;
}
case 37:
{
if (player.isAlikeDead())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// 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))
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Like L2OFF - You can't open Manufacture when you are sitting
if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE))
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE)
@@ -376,47 +379,47 @@ public class RequestActionUse extends GameClientPacket
}
case 39: // Soulless - Parasite Burst
{
useSkill(4138);
useSkill(client, 4138);
break;
}
case 41: // Wild Hog Cannon - Attack
{
useSkill(4230);
useSkill(client, 4230);
break;
}
case 42: // Kai the Cat - Self Damage Shield
{
useSkill(4378, player);
useSkill(client, 4378, player);
break;
}
case 43: // Unicorn Merrow - Hydro Screw
{
useSkill(4137);
useSkill(client, 4137);
break;
}
case 44: // Big Boom - Boom Attack
{
useSkill(4139);
useSkill(client, 4139);
break;
}
case 45: // Unicorn Boxer - Master Recharge
{
useSkill(4025, player);
useSkill(client, 4025, player);
break;
}
case 46: // Mew the Cat - Mega Storm Strike
{
useSkill(4261);
useSkill(client, 4261);
break;
}
case 47: // Silhouette - Steal Blood
{
useSkill(4260);
useSkill(client, 4260);
break;
}
case 48: // Mechanic Golem - Mech. Cannon
{
useSkill(4068);
useSkill(client, 4068);
break;
}
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)
if (player.isAlikeDead())
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// 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))
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Like L2OFF - You can't open Manufacture when you are sitting
if (player.isSitting() && (player.getPrivateStoreType() != PlayerInstance.STORE_PRIVATE_MANUFACTURE))
{
getClient().sendPacket(ActionFailed.STATIC_PACKET);
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if (player.getPrivateStoreType() == PlayerInstance.STORE_PRIVATE_MANUFACTURE)
@@ -506,7 +509,7 @@ public class RequestActionUse extends GameClientPacket
{
if (target instanceof DoorInstance)
{
useSkill(4079);
useSkill(client, 4079);
}
break;
}
@@ -516,124 +519,124 @@ public class RequestActionUse extends GameClientPacket
}
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;
}
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;
}
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;
}
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;
}
case 1007: // Cat Queen - Blessing of Queen
{
useSkill(4699, player);
useSkill(client, 4699, player);
break;
}
case 1008: // Cat Queen - Gift of Queen
{
useSkill(4700, player);
useSkill(client, 4700, player);
break;
}
case 1009: // Cat Queen - Cure of Queen
{
useSkill(4701);
useSkill(client, 4701);
break;
}
case 1010: // Unicorn Seraphim - Blessing of Seraphim
{
useSkill(4702, player);
useSkill(client, 4702, player);
break;
}
case 1011: // Unicorn Seraphim - Gift of Seraphim
{
useSkill(4703, player);
useSkill(client, 4703, player);
break;
}
case 1012: // Unicorn Seraphim - Cure of Seraphim
{
useSkill(4704);
useSkill(client, 4704);
break;
}
case 1013: // Nightshade - Curse of Shade
{
useSkill(4705);
useSkill(client, 4705);
break;
}
case 1014: // Nightshade - Mass Curse of Shade
{
useSkill(4706, player);
useSkill(client, 4706, player);
break;
}
case 1015: // Nightshade - Shade Sacrifice
{
useSkill(4707);
useSkill(client, 4707);
break;
}
case 1016: // Cursed Man - Cursed Blow
{
useSkill(4709);
useSkill(client, 4709);
break;
}
case 1017: // Cursed Man - Cursed Strike/Stun
{
useSkill(4708);
useSkill(client, 4708);
break;
}
case 1031: // Feline King - Slash
{
useSkill(5135);
useSkill(client, 5135);
break;
}
case 1032: // Feline King - Spinning Slash
{
useSkill(5136);
useSkill(client, 5136);
break;
}
case 1033: // Feline King - Grip of the Cat
{
useSkill(5137);
useSkill(client, 5137);
break;
}
case 1034: // Magnus the Unicorn - Whiplash
{
useSkill(5138);
useSkill(client, 5138);
break;
}
case 1035: // Magnus the Unicorn - Tridal Wave
{
useSkill(5139);
useSkill(client, 5139);
break;
}
case 1036: // Spectral Lord - Corpse Kaboom
{
useSkill(5142);
useSkill(client, 5142);
break;
}
case 1037: // Spectral Lord - Dicing Death
{
useSkill(5141);
useSkill(client, 5141);
break;
}
case 1038: // Spectral Lord - Force Curse
{
useSkill(5140);
useSkill(client, 5140);
break;
}
case 1039: // Swoop Cannon - Cannon Fodder
{
if (!(target instanceof DoorInstance))
{
useSkill(5110);
useSkill(client, 5110);
}
break;
}
@@ -641,7 +644,7 @@ public class RequestActionUse extends GameClientPacket
{
if (!(target instanceof DoorInstance))
{
useSkill(5111);
useSkill(client, 5111);
}
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.
*/
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)
{
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).
*/
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)
{
return;
}
useSkill(skillId, player.getTarget());
useSkill(client, skillId, player.getTarget());
}
}

View File

@@ -16,9 +16,11 @@
*/
package org.l2jmobius.gameserver.network.clientpackets;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.serverpackets.AllyCrest;
public class RequestAllyCrest extends GameClientPacket
public class RequestAllyCrest implements IClientIncomingPacket
{
private int _crestId;
@@ -26,14 +28,15 @@ public class RequestAllyCrest extends GameClientPacket
* packet type id 0x88 format: cd
*/
@Override
protected void readImpl()
public boolean read(GameClient client, PacketReader packet)
{
_crestId = readD();
_crestId = packet.readD();
return true;
}
@Override
protected void runImpl()
public void run(GameClient client)
{
sendPacket(new AllyCrest(_crestId));
client.sendPacket(new AllyCrest(_crestId));
}
}

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