Implement discarding relics (the trash can button)

This commit is contained in:
Melledy 2024-02-06 23:31:28 -08:00
parent f67450203d
commit 83b6e975db
7 changed files with 480 additions and 24 deletions

View File

@ -0,0 +1,341 @@
// Code generated by protocol buffer compiler. Do not edit!
package emu.lunarcore.proto;
import java.io.IOException;
import us.hebi.quickbuf.FieldName;
import us.hebi.quickbuf.InvalidProtocolBufferException;
import us.hebi.quickbuf.JsonSink;
import us.hebi.quickbuf.JsonSource;
import us.hebi.quickbuf.MessageFactory;
import us.hebi.quickbuf.ProtoMessage;
import us.hebi.quickbuf.ProtoSink;
import us.hebi.quickbuf.ProtoSource;
public final class DiscardRelicCsReqOuterClass {
/**
* Protobuf type {@code DiscardRelicCsReq}
*/
public static final class DiscardRelicCsReq extends ProtoMessage<DiscardRelicCsReq> implements Cloneable {
private static final long serialVersionUID = 0L;
/**
* <code>optional uint32 relic_unique_id = 13;</code>
*/
private int relicUniqueId;
/**
* <code>optional bool is_discard = 1;</code>
*/
private boolean isDiscard;
private DiscardRelicCsReq() {
}
/**
* @return a new empty instance of {@code DiscardRelicCsReq}
*/
public static DiscardRelicCsReq newInstance() {
return new DiscardRelicCsReq();
}
/**
* <code>optional uint32 relic_unique_id = 13;</code>
* @return whether the relicUniqueId field is set
*/
public boolean hasRelicUniqueId() {
return (bitField0_ & 0x00000001) != 0;
}
/**
* <code>optional uint32 relic_unique_id = 13;</code>
* @return this
*/
public DiscardRelicCsReq clearRelicUniqueId() {
bitField0_ &= ~0x00000001;
relicUniqueId = 0;
return this;
}
/**
* <code>optional uint32 relic_unique_id = 13;</code>
* @return the relicUniqueId
*/
public int getRelicUniqueId() {
return relicUniqueId;
}
/**
* <code>optional uint32 relic_unique_id = 13;</code>
* @param value the relicUniqueId to set
* @return this
*/
public DiscardRelicCsReq setRelicUniqueId(final int value) {
bitField0_ |= 0x00000001;
relicUniqueId = value;
return this;
}
/**
* <code>optional bool is_discard = 1;</code>
* @return whether the isDiscard field is set
*/
public boolean hasIsDiscard() {
return (bitField0_ & 0x00000002) != 0;
}
/**
* <code>optional bool is_discard = 1;</code>
* @return this
*/
public DiscardRelicCsReq clearIsDiscard() {
bitField0_ &= ~0x00000002;
isDiscard = false;
return this;
}
/**
* <code>optional bool is_discard = 1;</code>
* @return the isDiscard
*/
public boolean getIsDiscard() {
return isDiscard;
}
/**
* <code>optional bool is_discard = 1;</code>
* @param value the isDiscard to set
* @return this
*/
public DiscardRelicCsReq setIsDiscard(final boolean value) {
bitField0_ |= 0x00000002;
isDiscard = value;
return this;
}
@Override
public DiscardRelicCsReq copyFrom(final DiscardRelicCsReq other) {
cachedSize = other.cachedSize;
if ((bitField0_ | other.bitField0_) != 0) {
bitField0_ = other.bitField0_;
relicUniqueId = other.relicUniqueId;
isDiscard = other.isDiscard;
}
return this;
}
@Override
public DiscardRelicCsReq mergeFrom(final DiscardRelicCsReq other) {
if (other.isEmpty()) {
return this;
}
cachedSize = -1;
if (other.hasRelicUniqueId()) {
setRelicUniqueId(other.relicUniqueId);
}
if (other.hasIsDiscard()) {
setIsDiscard(other.isDiscard);
}
return this;
}
@Override
public DiscardRelicCsReq clear() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
relicUniqueId = 0;
isDiscard = false;
return this;
}
@Override
public DiscardRelicCsReq clearQuick() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
return this;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof DiscardRelicCsReq)) {
return false;
}
DiscardRelicCsReq other = (DiscardRelicCsReq) o;
return bitField0_ == other.bitField0_
&& (!hasRelicUniqueId() || relicUniqueId == other.relicUniqueId)
&& (!hasIsDiscard() || isDiscard == other.isDiscard);
}
@Override
public void writeTo(final ProtoSink output) throws IOException {
if ((bitField0_ & 0x00000001) != 0) {
output.writeRawByte((byte) 104);
output.writeUInt32NoTag(relicUniqueId);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeRawByte((byte) 8);
output.writeBoolNoTag(isDiscard);
}
}
@Override
protected int computeSerializedSize() {
int size = 0;
if ((bitField0_ & 0x00000001) != 0) {
size += 1 + ProtoSink.computeUInt32SizeNoTag(relicUniqueId);
}
if ((bitField0_ & 0x00000002) != 0) {
size += 2;
}
return size;
}
@Override
@SuppressWarnings("fallthrough")
public DiscardRelicCsReq mergeFrom(final ProtoSource input) throws IOException {
// Enabled Fall-Through Optimization (QuickBuffers)
int tag = input.readTag();
while (true) {
switch (tag) {
case 104: {
// relicUniqueId
relicUniqueId = input.readUInt32();
bitField0_ |= 0x00000001;
tag = input.readTag();
if (tag != 8) {
break;
}
}
case 8: {
// isDiscard
isDiscard = input.readBool();
bitField0_ |= 0x00000002;
tag = input.readTag();
if (tag != 0) {
break;
}
}
case 0: {
return this;
}
default: {
if (!input.skipField(tag)) {
return this;
}
tag = input.readTag();
break;
}
}
}
}
@Override
public void writeTo(final JsonSink output) throws IOException {
output.beginObject();
if ((bitField0_ & 0x00000001) != 0) {
output.writeUInt32(FieldNames.relicUniqueId, relicUniqueId);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeBool(FieldNames.isDiscard, isDiscard);
}
output.endObject();
}
@Override
public DiscardRelicCsReq mergeFrom(final JsonSource input) throws IOException {
if (!input.beginObject()) {
return this;
}
while (!input.isAtEnd()) {
switch (input.readFieldHash()) {
case -1966200481:
case 49648253: {
if (input.isAtField(FieldNames.relicUniqueId)) {
if (!input.trySkipNullValue()) {
relicUniqueId = input.readUInt32();
bitField0_ |= 0x00000001;
}
} else {
input.skipUnknownField();
}
break;
}
case 1091588116:
case -1123290487: {
if (input.isAtField(FieldNames.isDiscard)) {
if (!input.trySkipNullValue()) {
isDiscard = input.readBool();
bitField0_ |= 0x00000002;
}
} else {
input.skipUnknownField();
}
break;
}
default: {
input.skipUnknownField();
break;
}
}
}
input.endObject();
return this;
}
@Override
public DiscardRelicCsReq clone() {
return new DiscardRelicCsReq().copyFrom(this);
}
@Override
public boolean isEmpty() {
return ((bitField0_) == 0);
}
public static DiscardRelicCsReq parseFrom(final byte[] data) throws
InvalidProtocolBufferException {
return ProtoMessage.mergeFrom(new DiscardRelicCsReq(), data).checkInitialized();
}
public static DiscardRelicCsReq parseFrom(final ProtoSource input) throws IOException {
return ProtoMessage.mergeFrom(new DiscardRelicCsReq(), input).checkInitialized();
}
public static DiscardRelicCsReq parseFrom(final JsonSource input) throws IOException {
return ProtoMessage.mergeFrom(new DiscardRelicCsReq(), input).checkInitialized();
}
/**
* @return factory for creating DiscardRelicCsReq messages
*/
public static MessageFactory<DiscardRelicCsReq> getFactory() {
return DiscardRelicCsReqFactory.INSTANCE;
}
private enum DiscardRelicCsReqFactory implements MessageFactory<DiscardRelicCsReq> {
INSTANCE;
@Override
public DiscardRelicCsReq create() {
return DiscardRelicCsReq.newInstance();
}
}
/**
* Contains name constants used for serializing JSON
*/
static class FieldNames {
static final FieldName relicUniqueId = FieldName.forField("relicUniqueId", "relic_unique_id");
static final FieldName isDiscard = FieldName.forField("isDiscard", "is_discard");
}
}
}

View File

@ -49,6 +49,11 @@ public final class RelicOuterClass {
*/
private int mainAffixId;
/**
* <code>optional bool is_discarded = 4;</code>
*/
private boolean isDiscarded;
/**
* <code>optional bool is_protected = 11;</code>
*/
@ -291,12 +296,49 @@ public final class RelicOuterClass {
return this;
}
/**
* <code>optional bool is_discarded = 4;</code>
* @return whether the isDiscarded field is set
*/
public boolean hasIsDiscarded() {
return (bitField0_ & 0x00000040) != 0;
}
/**
* <code>optional bool is_discarded = 4;</code>
* @return this
*/
public Relic clearIsDiscarded() {
bitField0_ &= ~0x00000040;
isDiscarded = false;
return this;
}
/**
* <code>optional bool is_discarded = 4;</code>
* @return the isDiscarded
*/
public boolean getIsDiscarded() {
return isDiscarded;
}
/**
* <code>optional bool is_discarded = 4;</code>
* @param value the isDiscarded to set
* @return this
*/
public Relic setIsDiscarded(final boolean value) {
bitField0_ |= 0x00000040;
isDiscarded = value;
return this;
}
/**
* <code>optional bool is_protected = 11;</code>
* @return whether the isProtected field is set
*/
public boolean hasIsProtected() {
return (bitField0_ & 0x00000040) != 0;
return (bitField0_ & 0x00000080) != 0;
}
/**
@ -304,7 +346,7 @@ public final class RelicOuterClass {
* @return this
*/
public Relic clearIsProtected() {
bitField0_ &= ~0x00000040;
bitField0_ &= ~0x00000080;
isProtected = false;
return this;
}
@ -323,7 +365,7 @@ public final class RelicOuterClass {
* @return this
*/
public Relic setIsProtected(final boolean value) {
bitField0_ |= 0x00000040;
bitField0_ |= 0x00000080;
isProtected = value;
return this;
}
@ -333,7 +375,7 @@ public final class RelicOuterClass {
* @return whether the subAffixList field is set
*/
public boolean hasSubAffixList() {
return (bitField0_ & 0x00000080) != 0;
return (bitField0_ & 0x00000100) != 0;
}
/**
@ -341,7 +383,7 @@ public final class RelicOuterClass {
* @return this
*/
public Relic clearSubAffixList() {
bitField0_ &= ~0x00000080;
bitField0_ &= ~0x00000100;
subAffixList.clear();
return this;
}
@ -370,7 +412,7 @@ public final class RelicOuterClass {
* @return internal storage object for modifications
*/
public RepeatedMessage<RelicAffixOuterClass.RelicAffix> getMutableSubAffixList() {
bitField0_ |= 0x00000080;
bitField0_ |= 0x00000100;
return subAffixList;
}
@ -380,7 +422,7 @@ public final class RelicOuterClass {
* @return this
*/
public Relic addSubAffixList(final RelicAffixOuterClass.RelicAffix value) {
bitField0_ |= 0x00000080;
bitField0_ |= 0x00000100;
subAffixList.add(value);
return this;
}
@ -391,7 +433,7 @@ public final class RelicOuterClass {
* @return this
*/
public Relic addAllSubAffixList(final RelicAffixOuterClass.RelicAffix... values) {
bitField0_ |= 0x00000080;
bitField0_ |= 0x00000100;
subAffixList.addAll(values);
return this;
}
@ -407,6 +449,7 @@ public final class RelicOuterClass {
baseAvatarId = other.baseAvatarId;
exp = other.exp;
mainAffixId = other.mainAffixId;
isDiscarded = other.isDiscarded;
isProtected = other.isProtected;
subAffixList.copyFrom(other.subAffixList);
}
@ -437,6 +480,9 @@ public final class RelicOuterClass {
if (other.hasMainAffixId()) {
setMainAffixId(other.mainAffixId);
}
if (other.hasIsDiscarded()) {
setIsDiscarded(other.isDiscarded);
}
if (other.hasIsProtected()) {
setIsProtected(other.isProtected);
}
@ -459,6 +505,7 @@ public final class RelicOuterClass {
baseAvatarId = 0;
exp = 0;
mainAffixId = 0;
isDiscarded = false;
isProtected = false;
subAffixList.clear();
return this;
@ -491,6 +538,7 @@ public final class RelicOuterClass {
&& (!hasBaseAvatarId() || baseAvatarId == other.baseAvatarId)
&& (!hasExp() || exp == other.exp)
&& (!hasMainAffixId() || mainAffixId == other.mainAffixId)
&& (!hasIsDiscarded() || isDiscarded == other.isDiscarded)
&& (!hasIsProtected() || isProtected == other.isProtected)
&& (!hasSubAffixList() || subAffixList.equals(other.subAffixList));
}
@ -522,10 +570,14 @@ public final class RelicOuterClass {
output.writeUInt32NoTag(mainAffixId);
}
if ((bitField0_ & 0x00000040) != 0) {
output.writeRawByte((byte) 32);
output.writeBoolNoTag(isDiscarded);
}
if ((bitField0_ & 0x00000080) != 0) {
output.writeRawByte((byte) 88);
output.writeBoolNoTag(isProtected);
}
if ((bitField0_ & 0x00000080) != 0) {
if ((bitField0_ & 0x00000100) != 0) {
for (int i = 0; i < subAffixList.length(); i++) {
output.writeRawByte((byte) 66);
output.writeMessageNoTag(subAffixList.get(i));
@ -558,6 +610,9 @@ public final class RelicOuterClass {
size += 2;
}
if ((bitField0_ & 0x00000080) != 0) {
size += 2;
}
if ((bitField0_ & 0x00000100) != 0) {
size += (1 * subAffixList.length()) + ProtoSink.computeRepeatedMessageSizeNoTag(subAffixList);
}
return size;
@ -620,6 +675,15 @@ public final class RelicOuterClass {
mainAffixId = input.readUInt32();
bitField0_ |= 0x00000020;
tag = input.readTag();
if (tag != 32) {
break;
}
}
case 32: {
// isDiscarded
isDiscarded = input.readBool();
bitField0_ |= 0x00000040;
tag = input.readTag();
if (tag != 88) {
break;
}
@ -627,7 +691,7 @@ public final class RelicOuterClass {
case 88: {
// isProtected
isProtected = input.readBool();
bitField0_ |= 0x00000040;
bitField0_ |= 0x00000080;
tag = input.readTag();
if (tag != 66) {
break;
@ -636,7 +700,7 @@ public final class RelicOuterClass {
case 66: {
// subAffixList
tag = input.readRepeatedMessage(subAffixList, tag);
bitField0_ |= 0x00000080;
bitField0_ |= 0x00000100;
if (tag != 0) {
break;
}
@ -677,9 +741,12 @@ public final class RelicOuterClass {
output.writeUInt32(FieldNames.mainAffixId, mainAffixId);
}
if ((bitField0_ & 0x00000040) != 0) {
output.writeBool(FieldNames.isProtected, isProtected);
output.writeBool(FieldNames.isDiscarded, isDiscarded);
}
if ((bitField0_ & 0x00000080) != 0) {
output.writeBool(FieldNames.isProtected, isProtected);
}
if ((bitField0_ & 0x00000100) != 0) {
output.writeRepeatedMessage(FieldNames.subAffixList, subAffixList);
}
output.endObject();
@ -761,12 +828,24 @@ public final class RelicOuterClass {
}
break;
}
case 1044162483:
case -1445363480: {
if (input.isAtField(FieldNames.isDiscarded)) {
if (!input.trySkipNullValue()) {
isDiscarded = input.readBool();
bitField0_ |= 0x00000040;
}
} else {
input.skipUnknownField();
}
break;
}
case 569879972:
case -1919645991: {
if (input.isAtField(FieldNames.isProtected)) {
if (!input.trySkipNullValue()) {
isProtected = input.readBool();
bitField0_ |= 0x00000040;
bitField0_ |= 0x00000080;
}
} else {
input.skipUnknownField();
@ -778,7 +857,7 @@ public final class RelicOuterClass {
if (input.isAtField(FieldNames.subAffixList)) {
if (!input.trySkipNullValue()) {
input.readRepeatedMessage(subAffixList);
bitField0_ |= 0x00000080;
bitField0_ |= 0x00000100;
}
} else {
input.skipUnknownField();
@ -849,6 +928,8 @@ public final class RelicOuterClass {
static final FieldName mainAffixId = FieldName.forField("mainAffixId", "main_affix_id");
static final FieldName isDiscarded = FieldName.forField("isDiscarded", "is_discarded");
static final FieldName isProtected = FieldName.forField("isProtected", "is_protected");
static final FieldName subAffixList = FieldName.forField("subAffixList", "sub_affix_list");

View File

@ -48,6 +48,7 @@ public class GameItem {
@Setter private int promotion;
@Setter private int rank; // Superimpose
@Setter private boolean locked;
@Setter private boolean discarded;
@Setter private int mainAffix;
private List<GameItemSubAffix> subAffixes;
@ -277,6 +278,7 @@ public class GameItem {
.setLevel(this.getLevel())
.setExp(this.getExp())
.setIsProtected(this.isLocked())
.setIsDiscarded(this.isDiscarded())
.setBaseAvatarId(this.getEquipAvatar())
.setMainAffixId(this.mainAffix);

View File

@ -526,18 +526,30 @@ public class InventoryService extends BaseGameService {
// === Etc ===
public void lockEquip(Player player, int equipId, boolean locked) {
GameItem equip = player.getInventory().getItemByUid(equipId);
if (equip == null || !equip.getExcel().isEquippable()) {
public void lockItem(Player player, int equipId, boolean locked) {
GameItem item = player.getInventory().getItemByUid(equipId);
if (item == null || !item.getExcel().isEquippable()) {
return;
}
equip.setLocked(locked);
equip.save();
item.setLocked(locked);
item.save();
// Send packet
player.sendPacket(new PacketPlayerSyncScNotify(equip));
player.sendPacket(new PacketPlayerSyncScNotify(item));
}
public void discardRelic(Player player, int equipId, boolean discarded) {
GameItem relic = player.getInventory().getItemByUid(equipId);
if (relic == null || !relic.getExcel().isRelic()) {
return;
}
relic.setDiscarded(discarded);
relic.save();
// Send packet
player.sendPacket(new PacketPlayerSyncScNotify(relic));
}
public Int2IntMap sellItems(Player player, List<ItemParam> items) {

View File

@ -0,0 +1,20 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.DiscardRelicCsReqOuterClass.DiscardRelicCsReq;
import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler;
@Opcodes(CmdId.DiscardRelicCsReq)
public class HandlerDiscardRelicCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] data) throws Exception {
var req = DiscardRelicCsReq.parseFrom(data);
session.getServer().getInventoryService().discardRelic(session.getPlayer(), req.getRelicUniqueId(), req.getIsDiscard());
session.send(CmdId.DiscardRelicScRsp);
}
}

View File

@ -13,7 +13,7 @@ public class HandlerLockEquipmentCsReq extends PacketHandler {
public void handle(GameSession session, byte[] data) throws Exception {
var req = LockEquipmentCsReq.parseFrom(data);
session.getServer().getInventoryService().lockEquip(session.getPlayer(), req.getEquipmentUniqueId(), req.getIsProtected());
session.getServer().getInventoryService().lockItem(session.getPlayer(), req.getEquipmentUniqueId(), req.getIsProtected());
session.send(CmdId.LockEquipmentScRsp);
}

View File

@ -13,7 +13,7 @@ public class HandlerLockRelicCsReq extends PacketHandler {
public void handle(GameSession session, byte[] data) throws Exception {
var req = LockRelicCsReq.parseFrom(data);
session.getServer().getInventoryService().lockEquip(session.getPlayer(), req.getRelicUniqueId(), req.getIsProtected());
session.getServer().getInventoryService().lockItem(session.getPlayer(), req.getRelicUniqueId(), req.getIsProtected());
session.send(CmdId.LockRelicScRsp);
}