Fix various bugs with lineups and optimize them by using fastutil

This commit is contained in:
Melledy
2023-12-03 20:19:06 -08:00
parent ddea361edc
commit a2e10640c4
6 changed files with 113 additions and 15 deletions

View File

@@ -56,7 +56,7 @@ public final class DatabaseManager {
// Add our custom fastutil codecs
var codecProvider = CodecRegistries.fromCodecs(
new IntSetCodec(), new Int2IntMapCodec()
new IntSetCodec(), new IntListCodec(), new Int2IntMapCodec()
);
// Set mapper options.

View File

@@ -0,0 +1,42 @@
package emu.lunarcore.database.codecs;
import org.bson.BsonReader;
import org.bson.BsonType;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
/**
* Custom mongodb codec for encoding/decoding fastutil int sets.
*/
public class IntListCodec implements Codec<IntList> {
@Override
public Class<IntList> getEncoderClass() {
return IntList.class;
}
@Override
public void encode(BsonWriter writer, IntList collection, EncoderContext encoderContext) {
writer.writeStartArray();
for (int value : collection) {
writer.writeInt32(value);
}
writer.writeEndArray();
}
@Override
public IntList decode(BsonReader reader, DecoderContext decoderContext) {
IntList collection = new IntArrayList();
reader.readStartArray();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
collection.add(reader.readInt32());
}
reader.readEndArray();
return collection;
}
}

View File

@@ -151,6 +151,11 @@ public class LineupManager {
// Lineup functions
/**
* Changes the player's current active avatar
* @param slot The slot of the avatar we are changing to
* @return true on success
*/
public boolean changeLeader(int slot) {
PlayerLineup lineup = this.getCurrentLineup();
@@ -162,6 +167,13 @@ public class LineupManager {
return false;
}
/**
* Adds an avatar to a lineup
* @param index Index of the lineup we are adding the avatar to
* @param slot The slot that we want to put the avatar at
* @param avatarId Id of the avatar we are adding
* @return true on success
*/
public boolean joinLineup(int index, int slot, int avatarId) {
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index);
@@ -174,7 +186,7 @@ public class LineupManager {
if (avatar == null) return false;
// Join lineup
if (slot >= 0 && slot < lineup.size()) {
if (lineup.isActiveSlot(slot)) {
// Replace avatar
lineup.getAvatars().set(slot, avatarId);
} else if (lineup.size() < GameConstants.MAX_AVATARS_IN_TEAM) {
@@ -199,6 +211,13 @@ public class LineupManager {
return true;
}
/**
* Removes an avatar from a lineup
* @param index Index of the lineup we are removing the avatar from
* @param slot The slot that we want to remove the avatar from
* @param avatarId Id of the avatar we are removing
* @return true on success
*/
public boolean quitLineup(int index, int avatarId) {
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index);
@@ -211,7 +230,7 @@ public class LineupManager {
return false;
}
//
// Remove avatar from lineup
int i = lineup.getAvatars().indexOf(avatarId);
if (i != -1) {
lineup.getAvatars().remove(i);
@@ -238,6 +257,11 @@ public class LineupManager {
return true;
}
/**
* Changes the player's active lineup
* @param index Index of the lineup we are changing to
* @return true on success
*/
public boolean switchLineup(int index) {
// Sanity + Prevent lineups from being changed when the player is using an extra lineup
if (index == this.getCurrentIndex() || this.currentExtraIndex > 0) {
@@ -247,7 +271,7 @@ public class LineupManager {
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index);
// Make sure lineup exists and has size
// Make sure our next lineup exists and has avatars in it
if (lineup == null || lineup.size() == 0) {
return false;
}
@@ -265,6 +289,13 @@ public class LineupManager {
return true;
}
/**
* Sets the avatars of a lineup
* @param index Index of the lineup we are replacing the avatars on
* @param extraLineupType
* @param lineupList New avatar list
* @return true on success
*/
public boolean replaceLineup(int index, int extraLineupType, List<Integer> lineupList) {
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index, extraLineupType);
@@ -305,17 +336,23 @@ public class LineupManager {
return true;
}
/**
* Swaps the positions of 2 avatars on a lineup
* @param index Index of the lineup we are swapping avatars on
* @param src 1st avatar slot
* @param dest 2nd avatar slot
* @return true on success
*/
public boolean swapLineup(int index, int src, int dest) {
// Sanity
if (src == dest) return false;
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index);
// Validate slots
if ((lineup == null) || (src < 0 && src >= lineup.size())) {
return false;
}
if (dest < 0 && dest >= lineup.size()) {
if (lineup == null) return false;
// Validate slots to make sure avatars are in them
if (!lineup.isActiveSlot(src) || !lineup.isActiveSlot(dest)) {
return false;
}
@@ -335,6 +372,12 @@ public class LineupManager {
return true;
}
/**
* Changes a lineup's name
* @param index
* @param name
* @return
*/
public boolean changeLineupName(int index, String name) {
// Get lineup
PlayerLineup lineup = this.getLineupByIndex(index);
@@ -347,6 +390,8 @@ public class LineupManager {
return true;
}
// Database
public void loadFromDatabase() {
// Load lineups from database
var list = LunarCore.getGameDatabase()

View File

@@ -1,6 +1,5 @@
package emu.lunarcore.game.player.lineup;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@@ -15,6 +14,8 @@ import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.LineupInfoOuterClass.LineupInfo;
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import lombok.Setter;
@@ -26,7 +27,7 @@ public class PlayerLineup {
private transient Player owner;
protected int index;
protected List<Integer> avatars;
protected IntList avatars;
@Setter private int leader;
@Setter private String name;
@@ -38,7 +39,7 @@ public class PlayerLineup {
this.owner = player;
this.ownerUid = player.getUid();
this.index = index;
this.avatars = new ArrayList<>(GameConstants.MAX_AVATARS_IN_TEAM);
this.avatars = new IntArrayList(GameConstants.MAX_AVATARS_IN_TEAM);
// Set team name if not an extra lineup
if (!this.isExtraLineup()) {
@@ -65,7 +66,7 @@ public class PlayerLineup {
public synchronized List<Integer> getAvatars() {
return avatars;
}
public int size() {
return getAvatars().size();
}
@@ -127,6 +128,15 @@ public class PlayerLineup {
}
}
/**
* Checks if the slot contains an avatar
* @param slot The slot we are checking for
* @return true if the slot contains an avatar
*/
public synchronized boolean isActiveSlot(int slot) {
return slot >= 0 && slot < this.size();
}
// Database
public void save() {

View File

@@ -15,7 +15,7 @@ public class HandlerSetLineupNameCsReq extends PacketHandler {
var req = SetLineupNameCsReq.parseFrom(data);
var success = session.getPlayer().getLineupManager().changeLineupName(req.getIndex(), req.getName());
session.send(new PacketSetLineupNameScRsp(success ? req.getName() : null));
session.send(new PacketSetLineupNameScRsp(req.getIndex(), success ? req.getName() : null));
}
}

View File

@@ -6,12 +6,13 @@ import emu.lunarcore.server.packet.CmdId;
public class PacketSetLineupNameScRsp extends BasePacket {
public PacketSetLineupNameScRsp(String name) {
public PacketSetLineupNameScRsp(int index, String name) {
super(CmdId.SetLineupNameScRsp);
var data = SetLineupNameScRsp.newInstance();
if (name != null) {
data.setIndex(index);
data.setName(name);
} else {
data.setRetcode(1);