Merge branch 'master' into fix-tools
# Conflicts: # pom.xml
This commit is contained in:
@@ -319,6 +319,7 @@ server:
|
||||
NAME_CHANGE_COOLDOWN: 2592000000 # (30*24*60*60*1000) Cooldown for name changes, default (GMS) is 30 days.
|
||||
WORLD_TRANSFER_COOLDOWN: 2592000000 # (30*24*60*60*1000) Cooldown for world tranfers, default is same as name change (30 days).
|
||||
INSTANT_NAME_CHANGE: false #Whether or not to wait for server restart to apply name changes. Does on reconnect otherwise (requires queries on every login).
|
||||
REBIRTH_NPC_ID: 9010021 #ID of the NPC that should be replaced with the rebirth mechanic, if enabled.
|
||||
|
||||
#Dangling Items/Locks Configuration
|
||||
ITEM_EXPIRE_TIME: 180000 # (3 * 60 * 1000) Time before items start disappearing. Recommended to be set up to 3 minutes.
|
||||
@@ -460,3 +461,7 @@ server:
|
||||
#Event End Timestamp
|
||||
EVENT_END_TIMESTAMP: 1428897600000
|
||||
|
||||
#Any NPC ids that should search for a js override script (useful if they already have wz entries since otherwise they're ignored).
|
||||
NPCS_SCRIPTABLE:
|
||||
#9200000: Talk to Cody # Cody
|
||||
9001105: Rescue Gaga! # Grandpa moon bunny
|
||||
|
||||
20
pom.xml
20
pom.xml
@@ -51,7 +51,11 @@
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<exclusions></exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>4.1.65.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
@@ -87,6 +91,20 @@
|
||||
<artifactId>js-scriptengine</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.7.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.7.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -21,48 +21,9 @@
|
||||
*/
|
||||
/* 9010021 - Wolf Spirit Ryko
|
||||
@author Ronan
|
||||
*/
|
||||
var status;
|
||||
|
||||
@author wejrox
|
||||
*/
|
||||
function start() {
|
||||
status = -1;
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_REBIRTH_SYSTEM) {
|
||||
cm.sendOk("... I came from distant planes to assist the fight against the #rBlack Magician#k. Right now I search my master, have you seen him?");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (status == 0) {
|
||||
cm.sendNext("Come to me when you want to be reborn again. You currently have a total of #r" + cm.getChar().getReborns() + " #krebirths.");
|
||||
} else if (status == 1) {
|
||||
cm.sendSimple("What do you want me to do today: \r\n \r\n #L0##bI want to be rebirthed#l \r\n #L1##bMaybe next time#k#l");
|
||||
} else if (status == 2) {
|
||||
if (selection == 0) {
|
||||
if (cm.getChar().getLevel() == 200) {
|
||||
cm.sendYesNo("Are you sure you want to be rebirthed?");
|
||||
} else {
|
||||
cm.sendOk("You are not level 200, please come back when you hit level 200.");
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Ok Bye")
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (status == 3 && type == 1) {
|
||||
cm.getChar().executeReborn();
|
||||
cm.sendOk("You have now been reborn. That's a total of #r" + cm.getChar().getReborns() + "#k rebirths");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
|
||||
cm.sendOk("... I came from distant planes to assist the fight against the #rBlack Magician#k. Right now I search my master, have you seen him?");
|
||||
cm.dispose();
|
||||
}
|
||||
67
scripts/npc/rebirth.js
Normal file
67
scripts/npc/rebirth.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Rebirth NPC
|
||||
@author Ronan
|
||||
@author wejrox
|
||||
*/
|
||||
var status;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_REBIRTH_SYSTEM) {
|
||||
cm.sendOk("Rebirths aren't enabled on this server, how did you get here?");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode === 1) {
|
||||
status++;
|
||||
} else {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (status === 0) {
|
||||
cm.sendNext("Come to me when you want to be reborn again. You currently have a total of #r" + cm.getChar().getReborns() + " #krebirths.");
|
||||
} else if (status === 1) {
|
||||
cm.sendSimple("What do you want me to do today: \r\n \r\n #L0##bI want to be reborn!#l \r\n #L1##bNothing for now...#k#l");
|
||||
} else if (status === 2) {
|
||||
if (selection === 0) {
|
||||
if (cm.getChar().getLevel() === 200) {
|
||||
cm.sendYesNo("Are you sure you want to be reborn?");
|
||||
} else {
|
||||
cm.sendOk("You are not level 200, please come back when you hit level 200.");
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection === 1) {
|
||||
cm.sendOk("See you soon!")
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (status === 3 && type === 1) {
|
||||
cm.getChar().executeReborn();
|
||||
cm.sendOk("You have now been reborn. That's a total of #r" + cm.getChar().getReborns() + "#k rebirths");
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package config;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ServerConfig {
|
||||
//Thread Tracker Configuration
|
||||
public boolean USE_THREAD_TRACKER;
|
||||
@@ -163,6 +165,7 @@ public class ServerConfig {
|
||||
public long NAME_CHANGE_COOLDOWN;
|
||||
public long WORLD_TRANSFER_COOLDOWN=NAME_CHANGE_COOLDOWN;//Cooldown for world tranfers, default is same as name change (30 days).
|
||||
public boolean INSTANT_NAME_CHANGE;
|
||||
public int REBIRTH_NPC_ID;
|
||||
|
||||
//Dangling Items/Locks Configuration
|
||||
public int ITEM_EXPIRE_TIME ;
|
||||
@@ -304,4 +307,6 @@ public class ServerConfig {
|
||||
//Event End Timestamp
|
||||
public long EVENT_END_TIMESTAMP;
|
||||
|
||||
//Custom NPC overrides. List of NPC IDs.
|
||||
public Map<String, String> NPCS_SCRIPTABLE = new HashMap<>();
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package constants.game;
|
||||
|
||||
/**
|
||||
* @brief ScriptableNPCConstants
|
||||
* @author GabrielSin <gabrielsin@playellin.net>
|
||||
* @date 16/09/2018
|
||||
*
|
||||
* Adaptations to use Pair and Set, in order to suit a one-packet marshall.
|
||||
* Adapted by Ronan
|
||||
*/
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import tools.Pair;
|
||||
|
||||
public class ScriptableNPCConstants {
|
||||
|
||||
public static final Set<Pair<Integer, String>> SCRIPTABLE_NPCS = new HashSet<Pair<Integer, String>>(){{
|
||||
//add(new Pair<>(9200000, "Cody"));
|
||||
add(new Pair<>(9001105, "Grandpa Moon Bunny"));
|
||||
}};
|
||||
|
||||
}
|
||||
|
||||
81
src/main/java/net/packet/ByteBufInPacket.java
Normal file
81
src/main/java/net/packet/ByteBufInPacket.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package net.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ByteBufInPacket implements InPacket {
|
||||
private final ByteBuf byteBuf;
|
||||
|
||||
public ByteBufInPacket(ByteBuf byteBuf) {
|
||||
this.byteBuf = byteBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
return ByteBufUtil.getBytes(byteBuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
return byteBuf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() {
|
||||
return byteBuf.readShortLE();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() {
|
||||
return byteBuf.readIntLE();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong() {
|
||||
return byteBuf.readLongLE();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point readPoint() {
|
||||
final short x = byteBuf.readShortLE();
|
||||
final short y = byteBuf.readShortLE();
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString() {
|
||||
short length = readShort();
|
||||
byte[] stringBytes = new byte[length];
|
||||
byteBuf.readBytes(stringBytes);
|
||||
return new String(stringBytes, STRING_CHARSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readBytes(int numberOfBytes) {
|
||||
byte[] bytes = new byte[numberOfBytes];
|
||||
byteBuf.readBytes(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip(int numberOfBytes) {
|
||||
byteBuf.skipBytes(numberOfBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return byteBuf.readableBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(int byteOffset) {
|
||||
byteBuf.readerIndex(byteOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return byteBuf.readerIndex();
|
||||
}
|
||||
}
|
||||
83
src/main/java/net/packet/ByteBufOutPacket.java
Normal file
83
src/main/java/net/packet/ByteBufOutPacket.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package net.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.jcip.annotations.NotThreadSafe;
|
||||
import net.opcodes.SendOpcode;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@NotThreadSafe
|
||||
public class ByteBufOutPacket implements OutPacket {
|
||||
private final ByteBuf byteBuf;
|
||||
|
||||
public ByteBufOutPacket(SendOpcode op) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeShortLE((short) op.getValue());
|
||||
this.byteBuf = byteBuf;
|
||||
}
|
||||
|
||||
public ByteBufOutPacket(SendOpcode op, int initialCapacity) {
|
||||
ByteBuf byteBuf = Unpooled.buffer(initialCapacity);
|
||||
byteBuf.writeShortLE((short) op.getValue());
|
||||
this.byteBuf = byteBuf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
return ByteBufUtil.getBytes(byteBuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(byte value) {
|
||||
byteBuf.writeByte(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int value) {
|
||||
writeByte((byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(byte[] value) {
|
||||
byteBuf.writeBytes(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int value) {
|
||||
byteBuf.writeShortLE(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int value) {
|
||||
byteBuf.writeIntLE(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long value) {
|
||||
byteBuf.writeLongLE(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean value) {
|
||||
byteBuf.writeByte(value ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
writeShort((short) value.length());
|
||||
writeBytes(value.getBytes(STRING_CHARSET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePoint(Point value) {
|
||||
writeShort((short) value.getX());
|
||||
writeShort((short) value.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip(int numberOfBytes) {
|
||||
writeBytes(new byte[numberOfBytes]);
|
||||
}
|
||||
}
|
||||
17
src/main/java/net/packet/InPacket.java
Normal file
17
src/main/java/net/packet/InPacket.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package net.packet;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface InPacket extends Packet {
|
||||
byte readByte();
|
||||
short readShort();
|
||||
int readInt();
|
||||
long readLong();
|
||||
Point readPoint();
|
||||
String readString();
|
||||
byte[] readBytes(int numberOfBytes);
|
||||
void skip(int numberOfBytes);
|
||||
int available();
|
||||
void seek(int byteOffset);
|
||||
int getPosition();
|
||||
}
|
||||
16
src/main/java/net/packet/OutPacket.java
Normal file
16
src/main/java/net/packet/OutPacket.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package net.packet;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface OutPacket extends Packet {
|
||||
void writeByte(byte value);
|
||||
void writeByte(int value);
|
||||
void writeBytes(byte[] value);
|
||||
void writeShort(int value);
|
||||
void writeInt(int value);
|
||||
void writeLong(long value);
|
||||
void writeBoolean(boolean value);
|
||||
void writeString(String value);
|
||||
void writePoint(Point value);
|
||||
void skip(int numberOfBytes);
|
||||
}
|
||||
10
src/main/java/net/packet/Packet.java
Normal file
10
src/main/java/net/packet/Packet.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package net.packet;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public interface Packet {
|
||||
Charset STRING_CHARSET = StandardCharsets.US_ASCII;
|
||||
|
||||
byte[] getBytes();
|
||||
}
|
||||
@@ -65,6 +65,8 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
|
||||
NPCScriptManager.getInstance().start(c, npc.getId(), "gachapon", null);
|
||||
} else if (npc.getName().endsWith("Maple TV")) {
|
||||
NPCScriptManager.getInstance().start(c, npc.getId(), "mapleTV", null);
|
||||
} else if (YamlConfig.config.server.USE_REBIRTH_SYSTEM && npc.getId() == YamlConfig.config.server.REBIRTH_NPC_ID) {
|
||||
NPCScriptManager.getInstance().start(c, npc.getId(), "rebirth", null);
|
||||
} else {
|
||||
boolean hasNpcScript = NPCScriptManager.getInstance().start(c, npc.getId(), oid, null);
|
||||
if (!hasNpcScript) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import client.inventory.*;
|
||||
import client.keybind.MapleKeyBinding;
|
||||
import config.YamlConfig;
|
||||
import constants.game.GameConstants;
|
||||
import constants.game.ScriptableNPCConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.PlayerBuffValueHolder;
|
||||
import net.server.Server;
|
||||
@@ -55,6 +54,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@@ -407,9 +407,23 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
eim.registerPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tell the client to use the custom scripts available for the NPCs provided, instead of the WZ entries.
|
||||
if (YamlConfig.config.server.USE_NPCS_SCRIPTABLE) {
|
||||
c.announce(MaplePacketCreator.setNPCScriptable(ScriptableNPCConstants.SCRIPTABLE_NPCS));
|
||||
|
||||
// Create a copy to prevent always adding entries to the server's list.
|
||||
Map<Integer, String> npcsIds = YamlConfig.config.server.NPCS_SCRIPTABLE
|
||||
.entrySet().stream().collect(Collectors.toMap(
|
||||
entry -> Integer.parseInt(entry.getKey()),
|
||||
Entry::getValue
|
||||
));
|
||||
|
||||
// Any npc be specified as the rebirth npc. Allow the npc to use custom scripts explicitly.
|
||||
if (YamlConfig.config.server.USE_REBIRTH_SYSTEM) {
|
||||
npcsIds.put(YamlConfig.config.server.REBIRTH_NPC_ID, "Rebirth");
|
||||
}
|
||||
|
||||
c.announce(MaplePacketCreator.setNPCScriptable(npcsIds));
|
||||
}
|
||||
|
||||
if(newcomer) player.setLoginTime(System.currentTimeMillis());
|
||||
|
||||
@@ -8327,17 +8327,25 @@ public class MaplePacketCreator {
|
||||
mplew.writeInt(transition);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static byte[] setNPCScriptable(Set<Pair<Integer, String>> scriptNpcDescriptions) { // thanks to GabrielSin
|
||||
|
||||
/**
|
||||
* Makes the NPCs provided set as scriptable, informing the client to search for js scripts for these NPCs even
|
||||
* if they already have entries within the wz files.
|
||||
*
|
||||
* @param scriptableNpcIds Ids of npcs to enable scripts for.
|
||||
* @return a packet which makes the npc's provided scriptable.
|
||||
*/
|
||||
public static byte[] setNPCScriptable(Map<Integer, String> scriptableNpcIds) { // thanks to GabrielSin
|
||||
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.SET_NPC_SCRIPTABLE.getValue());
|
||||
mplew.write(scriptNpcDescriptions.size());
|
||||
for (Pair<Integer, String> p : scriptNpcDescriptions) {
|
||||
mplew.writeInt(p.getLeft());
|
||||
mplew.writeMapleAsciiString(p.getRight());
|
||||
mplew.write(scriptableNpcIds.size());
|
||||
scriptableNpcIds.forEach((id, name) -> {
|
||||
mplew.writeInt(id);
|
||||
// The client needs a name for the npc conversation, which is displayed under etc when the npc has a quest available.
|
||||
mplew.writeMapleAsciiString(name);
|
||||
mplew.writeInt(0); // start time
|
||||
mplew.writeInt(Integer.MAX_VALUE); // end time
|
||||
}
|
||||
});
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
@@ -8383,17 +8391,17 @@ public class MaplePacketCreator {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.TOURNAMENT_SET_PRIZE.getValue());
|
||||
|
||||
//0 = "You have failed the set the prize. Please check the item number again."
|
||||
//1 = "You have successfully set the prize."
|
||||
mplew.write(bSetPrize);
|
||||
|
||||
mplew.write(bHasPrize);
|
||||
|
||||
if(bHasPrize != 0)
|
||||
{
|
||||
mplew.writeInt(nItemID1);
|
||||
mplew.writeInt(nItemID2);
|
||||
}
|
||||
//0 = "You have failed the set the prize. Please check the item number again."
|
||||
//1 = "You have successfully set the prize."
|
||||
mplew.write(bSetPrize);
|
||||
|
||||
mplew.write(bHasPrize);
|
||||
|
||||
if(bHasPrize != 0)
|
||||
{
|
||||
mplew.writeInt(nItemID1);
|
||||
mplew.writeInt(nItemID2);
|
||||
}
|
||||
|
||||
return mplew.getPacket();
|
||||
}
|
||||
@@ -8402,11 +8410,11 @@ public class MaplePacketCreator {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.TOURNAMENT_UEW.getValue());
|
||||
|
||||
//Is this a bitflag o.o ?
|
||||
//2 = "You have reached the finals by default."
|
||||
//4 = "You have reached the semifinals by default."
|
||||
//8 or 16 = "You have reached the round of %n by default." | Encodes nState as %n ?!
|
||||
mplew.write(nState);
|
||||
//Is this a bitflag o.o ?
|
||||
//2 = "You have reached the finals by default."
|
||||
//4 = "You have reached the semifinals by default."
|
||||
//8 or 16 = "You have reached the round of %n by default." | Encodes nState as %n ?!
|
||||
mplew.write(nState);
|
||||
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
192
src/test/java/net/packet/ByteBufInPacketTest.java
Normal file
192
src/test/java/net/packet/ByteBufInPacketTest.java
Normal file
@@ -0,0 +1,192 @@
|
||||
package net.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ByteBufInPacketTest {
|
||||
private ByteBuf byteBuf;
|
||||
private InPacket inPacket;
|
||||
|
||||
@BeforeEach
|
||||
void reset() {
|
||||
this.byteBuf = Unpooled.buffer();
|
||||
this.inPacket = new ByteBufInPacket(byteBuf);
|
||||
}
|
||||
|
||||
private void givenWrittenBytes(int... bytes) {
|
||||
for (int b : bytes) {
|
||||
byteBuf.writeByte(b);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void readByte() {
|
||||
final byte writtenByte = 123;
|
||||
byteBuf.writeByte(writtenByte);
|
||||
|
||||
byte readByte = inPacket.readByte();
|
||||
|
||||
assertEquals(writtenByte, readByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readShort() {
|
||||
final short writtenShort = 12_345;
|
||||
byteBuf.writeShortLE(writtenShort);
|
||||
|
||||
short readShort = inPacket.readShort();
|
||||
|
||||
assertEquals(writtenShort, readShort);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readInt() {
|
||||
final int writtenInt = 1_234_567_890;
|
||||
byteBuf.writeIntLE(writtenInt);
|
||||
|
||||
int readInt = inPacket.readInt();
|
||||
|
||||
assertEquals(writtenInt, readInt);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readLong() {
|
||||
final long writtenLong = 9_223_372_036_854_775_807L;
|
||||
byteBuf.writeLongLE(writtenLong);
|
||||
|
||||
long readLong = inPacket.readLong();
|
||||
|
||||
assertEquals(writtenLong, readLong);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readPoint() {
|
||||
final Point writtenPoint = new Point(111, 222);
|
||||
byteBuf.writeShortLE((short) writtenPoint.getX());
|
||||
byteBuf.writeShortLE((short) writtenPoint.getY());
|
||||
|
||||
Point readPoint = inPacket.readPoint();
|
||||
|
||||
assertEquals(writtenPoint, readPoint);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readString() {
|
||||
final String writtenString = "You have gained experience (+3200)";
|
||||
byteBuf.writeShortLE(writtenString.length());
|
||||
byte[] writtenStringBytes = writtenString.getBytes(Packet.STRING_CHARSET);
|
||||
byteBuf.writeBytes(writtenStringBytes);
|
||||
|
||||
String readString = inPacket.readString();
|
||||
|
||||
assertEquals(writtenString, readString);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readBytes() {
|
||||
givenWrittenBytes(10, 11, 12, 13, 14, 15);
|
||||
|
||||
byte[] byteBatch1 = inPacket.readBytes(1);
|
||||
assertEquals(1, byteBatch1.length);
|
||||
assertEquals(10, byteBatch1[0]);
|
||||
|
||||
byte[] byteBatch2 = inPacket.readBytes(2);
|
||||
assertEquals(2, byteBatch2.length);
|
||||
assertEquals(11, byteBatch2[0]);
|
||||
assertEquals(12, byteBatch2[1]);
|
||||
|
||||
byte[] byteBatch3 = inPacket.readBytes(3);
|
||||
assertEquals(3, byteBatch3.length);
|
||||
assertEquals(13, byteBatch3[0]);
|
||||
assertEquals(14, byteBatch3[1]);
|
||||
assertEquals(15, byteBatch3[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void skip() {
|
||||
givenWrittenBytes(20, 21, 22, 23, 24, 25);
|
||||
|
||||
byte firstByte = inPacket.readByte();
|
||||
assertEquals(20, firstByte);
|
||||
|
||||
inPacket.skip(3);
|
||||
|
||||
byte fifthByte = inPacket.readByte();
|
||||
assertEquals(24, fifthByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void available() {
|
||||
givenWrittenBytes(30, 31, 32, 33, 34, 35);
|
||||
|
||||
assertEquals(6, inPacket.available());
|
||||
|
||||
inPacket.readByte();
|
||||
assertEquals(5, inPacket.available());
|
||||
|
||||
inPacket.readInt();
|
||||
assertEquals(1, inPacket.available());
|
||||
}
|
||||
|
||||
@Test
|
||||
void seek() {
|
||||
givenWrittenBytes(40, 41, 42, 43, 44, 45);
|
||||
|
||||
inPacket.seek(2);
|
||||
assertEquals(4, inPacket.available());
|
||||
byte byteAtSeek = inPacket.readByte();
|
||||
assertEquals(42, byteAtSeek);
|
||||
|
||||
inPacket.seek(0);
|
||||
byte byteAtReset = inPacket.readByte();
|
||||
assertEquals(40, byteAtReset);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPosition() {
|
||||
givenWrittenBytes(50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60);
|
||||
|
||||
assertEquals(0, inPacket.getPosition());
|
||||
|
||||
inPacket.readByte();
|
||||
assertEquals(1, inPacket.getPosition());
|
||||
|
||||
inPacket.readShort();
|
||||
assertEquals(3, inPacket.getPosition());
|
||||
|
||||
inPacket.readInt();
|
||||
assertEquals(7, inPacket.getPosition());
|
||||
|
||||
inPacket.seek(5);
|
||||
assertEquals(5, inPacket.getPosition());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBytes() {
|
||||
givenWrittenBytes(20, 19, 21, 18, 22);
|
||||
|
||||
byte[] bytes = inPacket.getBytes();
|
||||
|
||||
assertArrayEquals(new byte[]{20, 19, 21, 18, 22}, bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenGetBytes_shouldBeRepeatable() {
|
||||
givenWrittenBytes(1, 2, 3, 4, 5);
|
||||
|
||||
byte[] bytes = inPacket.getBytes();
|
||||
assertEquals(5, bytes.length);
|
||||
|
||||
byte[] sameBytes = inPacket.getBytes();
|
||||
assertEquals(5, sameBytes.length);
|
||||
|
||||
assertArrayEquals(bytes, sameBytes);
|
||||
}
|
||||
}
|
||||
206
src/test/java/net/packet/ByteBufOutPacketTest.java
Normal file
206
src/test/java/net/packet/ByteBufOutPacketTest.java
Normal file
@@ -0,0 +1,206 @@
|
||||
package net.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.opcodes.SendOpcode;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ByteBufOutPacketTest {
|
||||
private ByteBufOutPacket outPacket;
|
||||
|
||||
@BeforeEach
|
||||
void reset() {
|
||||
outPacket = new ByteBufOutPacket(SendOpcode.ADMIN_SHOP); // Any opcode will do
|
||||
}
|
||||
|
||||
private static ByteBuf wrapExplicitlyWrittenBytes(OutPacket outPacket) {
|
||||
byte[] packetBytes = outPacket.getBytes();
|
||||
ByteBuf byteBuf = Unpooled.copiedBuffer(packetBytes);
|
||||
byteBuf.readShortLE(); // Skip over opcode
|
||||
return byteBuf;
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInstantiatingNew_shouldWriteOpcode() {
|
||||
byte[] packetBytes = new ByteBufOutPacket(SendOpcode.NPC_TALK).getBytes();
|
||||
assertEquals(2, packetBytes.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBytes() {
|
||||
ByteBufOutPacket outPacket = new ByteBufOutPacket(SendOpcode.PING); // This opcode has value 0x11 = 17 in decimal
|
||||
outPacket.writeByte(10);
|
||||
outPacket.writeByte(20);
|
||||
outPacket.writeByte(30);
|
||||
|
||||
byte[] bytes = outPacket.getBytes();
|
||||
|
||||
assertArrayEquals(new byte[]{(byte) 17, (byte) 0, (byte) 10, (byte) 20, (byte) 30}, bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeByte() {
|
||||
final byte writtenByte = 19;
|
||||
outPacket.writeByte(writtenByte);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
byte readByte = wrapped.readByte();
|
||||
|
||||
assertEquals(writtenByte, readByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeByteFromInt() {
|
||||
final int writtenInt = 123;
|
||||
outPacket.writeByte(writtenInt);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
byte readByte = wrapped.readByte();
|
||||
|
||||
assertEquals(writtenInt, readByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWritingByteFromInt_shouldOnlyWrite1Byte() {
|
||||
final int writtenInt = Integer.MAX_VALUE;
|
||||
outPacket.writeByte(writtenInt);
|
||||
|
||||
byte[] bytes = outPacket.getBytes();
|
||||
assertEquals(2 + 1, bytes.length); // 2 for opcode
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeBytes() {
|
||||
byte[] writtenBytes = {101, 102, 103};
|
||||
outPacket.writeBytes(writtenBytes);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
|
||||
assertEquals(101, wrapped.readByte());
|
||||
assertEquals(102, wrapped.readByte());
|
||||
assertEquals(103, wrapped.readByte());
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeShort() {
|
||||
final short writtenShort = 4312;
|
||||
outPacket.writeShort(writtenShort);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
short readShort = wrapped.readShortLE();
|
||||
|
||||
assertEquals(writtenShort, readShort);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWritingShortFromInt_shouldOnlyWrite2Bytes() {
|
||||
final int writtenInt = Integer.MAX_VALUE;
|
||||
outPacket.writeShort(writtenInt);
|
||||
|
||||
byte[] bytes = outPacket.getBytes();
|
||||
assertEquals(2 + 2, bytes.length); // 2 for opcode
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeShortFromInt() {
|
||||
final int writtenInt = 34_567;
|
||||
outPacket.writeShort(writtenInt);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
short readShort = wrapped.readShortLE();
|
||||
|
||||
assertEquals((short) writtenInt, readShort);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeInt() {
|
||||
final int writtenInt = 1_010_101_010;
|
||||
outPacket.writeInt(writtenInt);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
int readInt = wrapped.readIntLE();
|
||||
|
||||
assertEquals(writtenInt, readInt);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeLong() {
|
||||
final long writtenLong = 100_200_300_400_500_600L;
|
||||
outPacket.writeLong(writtenLong);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
long readLong = wrapped.readLongLE();
|
||||
|
||||
assertEquals(writtenLong, readLong);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeBoolean_true() {
|
||||
outPacket.writeBoolean(true);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
byte readByte = wrapped.readByte();
|
||||
|
||||
assertEquals(1, readByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeBoolean_false() {
|
||||
outPacket.writeBoolean(false);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
byte readByte = wrapped.readByte();
|
||||
|
||||
assertEquals(0, readByte);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeString() {
|
||||
final String writtenString = "You've been weakened, making you unable to jump.";
|
||||
outPacket.writeString(writtenString);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
int length = wrapped.readShortLE();
|
||||
byte[] stringBytes = new byte[length];
|
||||
wrapped.readBytes(stringBytes);
|
||||
String readString = new String(stringBytes, StandardCharsets.US_ASCII);
|
||||
|
||||
assertEquals(writtenString, readString);
|
||||
}
|
||||
|
||||
@Test
|
||||
void writePoint() {
|
||||
final Point writtenPoint = new Point(23, 42);
|
||||
outPacket.writePoint(writtenPoint);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
short readX = wrapped.readShortLE();
|
||||
short readY = wrapped.readShortLE();
|
||||
|
||||
assertEquals((short) writtenPoint.getX(), readX);
|
||||
assertEquals((short) writtenPoint.getY(), readY);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSkipping_shouldWriteZeroes() {
|
||||
final byte firstWrittenByte = 9;
|
||||
final byte secondWrittenByte = 11;
|
||||
outPacket.writeByte(firstWrittenByte);
|
||||
outPacket.skip(2);
|
||||
outPacket.writeByte(secondWrittenByte);
|
||||
|
||||
ByteBuf wrapped = wrapExplicitlyWrittenBytes(outPacket);
|
||||
|
||||
assertEquals(firstWrittenByte, wrapped.readByte());
|
||||
assertEquals(0, wrapped.readByte());
|
||||
assertEquals(0, wrapped.readByte());
|
||||
assertEquals(secondWrittenByte, wrapped.readByte());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user