diff --git a/src/generated/main/emu/lunarcore/proto/FriendRecommendInfoOuterClass.java b/src/generated/main/emu/lunarcore/proto/FriendRecommendInfoOuterClass.java new file mode 100644 index 0000000..4afec1c --- /dev/null +++ b/src/generated/main/emu/lunarcore/proto/FriendRecommendInfoOuterClass.java @@ -0,0 +1,281 @@ +// 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 FriendRecommendInfoOuterClass { + /** + * Protobuf type {@code FriendRecommendInfo} + */ + public static final class FriendRecommendInfo extends ProtoMessage implements Cloneable { + private static final long serialVersionUID = 0L; + + /** + * optional .SimpleInfo simple_info = 11; + */ + private final SimpleInfoOuterClass.SimpleInfo simpleInfo = SimpleInfoOuterClass.SimpleInfo.newInstance(); + + private FriendRecommendInfo() { + } + + /** + * @return a new empty instance of {@code FriendRecommendInfo} + */ + public static FriendRecommendInfo newInstance() { + return new FriendRecommendInfo(); + } + + /** + * optional .SimpleInfo simple_info = 11; + * @return whether the simpleInfo field is set + */ + public boolean hasSimpleInfo() { + return (bitField0_ & 0x00000001) != 0; + } + + /** + * optional .SimpleInfo simple_info = 11; + * @return this + */ + public FriendRecommendInfo clearSimpleInfo() { + bitField0_ &= ~0x00000001; + simpleInfo.clear(); + return this; + } + + /** + * optional .SimpleInfo simple_info = 11; + * + * This method returns the internal storage object without modifying any has state. + * The returned object should not be modified and be treated as read-only. + * + * Use {@link #getMutableSimpleInfo()} if you want to modify it. + * + * @return internal storage object for reading + */ + public SimpleInfoOuterClass.SimpleInfo getSimpleInfo() { + return simpleInfo; + } + + /** + * optional .SimpleInfo simple_info = 11; + * + * This method returns the internal storage object and sets the corresponding + * has state. The returned object will become part of this message and its + * contents may be modified as long as the has state is not cleared. + * + * @return internal storage object for modifications + */ + public SimpleInfoOuterClass.SimpleInfo getMutableSimpleInfo() { + bitField0_ |= 0x00000001; + return simpleInfo; + } + + /** + * optional .SimpleInfo simple_info = 11; + * @param value the simpleInfo to set + * @return this + */ + public FriendRecommendInfo setSimpleInfo(final SimpleInfoOuterClass.SimpleInfo value) { + bitField0_ |= 0x00000001; + simpleInfo.copyFrom(value); + return this; + } + + @Override + public FriendRecommendInfo copyFrom(final FriendRecommendInfo other) { + cachedSize = other.cachedSize; + if ((bitField0_ | other.bitField0_) != 0) { + bitField0_ = other.bitField0_; + simpleInfo.copyFrom(other.simpleInfo); + } + return this; + } + + @Override + public FriendRecommendInfo mergeFrom(final FriendRecommendInfo other) { + if (other.isEmpty()) { + return this; + } + cachedSize = -1; + if (other.hasSimpleInfo()) { + getMutableSimpleInfo().mergeFrom(other.simpleInfo); + } + return this; + } + + @Override + public FriendRecommendInfo clear() { + if (isEmpty()) { + return this; + } + cachedSize = -1; + bitField0_ = 0; + simpleInfo.clear(); + return this; + } + + @Override + public FriendRecommendInfo clearQuick() { + if (isEmpty()) { + return this; + } + cachedSize = -1; + bitField0_ = 0; + simpleInfo.clearQuick(); + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof FriendRecommendInfo)) { + return false; + } + FriendRecommendInfo other = (FriendRecommendInfo) o; + return bitField0_ == other.bitField0_ + && (!hasSimpleInfo() || simpleInfo.equals(other.simpleInfo)); + } + + @Override + public void writeTo(final ProtoSink output) throws IOException { + if ((bitField0_ & 0x00000001) != 0) { + output.writeRawByte((byte) 90); + output.writeMessageNoTag(simpleInfo); + } + } + + @Override + protected int computeSerializedSize() { + int size = 0; + if ((bitField0_ & 0x00000001) != 0) { + size += 1 + ProtoSink.computeMessageSizeNoTag(simpleInfo); + } + return size; + } + + @Override + @SuppressWarnings("fallthrough") + public FriendRecommendInfo mergeFrom(final ProtoSource input) throws IOException { + // Enabled Fall-Through Optimization (QuickBuffers) + int tag = input.readTag(); + while (true) { + switch (tag) { + case 90: { + // simpleInfo + input.readMessage(simpleInfo); + bitField0_ |= 0x00000001; + 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.writeMessage(FieldNames.simpleInfo, simpleInfo); + } + output.endObject(); + } + + @Override + public FriendRecommendInfo mergeFrom(final JsonSource input) throws IOException { + if (!input.beginObject()) { + return this; + } + while (!input.isAtEnd()) { + switch (input.readFieldHash()) { + case -1431903872: + case -1419171045: { + if (input.isAtField(FieldNames.simpleInfo)) { + if (!input.trySkipNullValue()) { + input.readMessage(simpleInfo); + bitField0_ |= 0x00000001; + } + } else { + input.skipUnknownField(); + } + break; + } + default: { + input.skipUnknownField(); + break; + } + } + } + input.endObject(); + return this; + } + + @Override + public FriendRecommendInfo clone() { + return new FriendRecommendInfo().copyFrom(this); + } + + @Override + public boolean isEmpty() { + return ((bitField0_) == 0); + } + + public static FriendRecommendInfo parseFrom(final byte[] data) throws + InvalidProtocolBufferException { + return ProtoMessage.mergeFrom(new FriendRecommendInfo(), data).checkInitialized(); + } + + public static FriendRecommendInfo parseFrom(final ProtoSource input) throws IOException { + return ProtoMessage.mergeFrom(new FriendRecommendInfo(), input).checkInitialized(); + } + + public static FriendRecommendInfo parseFrom(final JsonSource input) throws IOException { + return ProtoMessage.mergeFrom(new FriendRecommendInfo(), input).checkInitialized(); + } + + /** + * @return factory for creating FriendRecommendInfo messages + */ + public static MessageFactory getFactory() { + return FriendRecommendInfoFactory.INSTANCE; + } + + private enum FriendRecommendInfoFactory implements MessageFactory { + INSTANCE; + + @Override + public FriendRecommendInfo create() { + return FriendRecommendInfo.newInstance(); + } + } + + /** + * Contains name constants used for serializing JSON + */ + static class FieldNames { + static final FieldName simpleInfo = FieldName.forField("simpleInfo", "simple_info"); + } + } +} diff --git a/src/generated/main/emu/lunarcore/proto/GetFriendRecommendListInfoScRspOuterClass.java b/src/generated/main/emu/lunarcore/proto/GetFriendRecommendListInfoScRspOuterClass.java new file mode 100644 index 0000000..51a27de --- /dev/null +++ b/src/generated/main/emu/lunarcore/proto/GetFriendRecommendListInfoScRspOuterClass.java @@ -0,0 +1,380 @@ +// 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; +import us.hebi.quickbuf.RepeatedMessage; + +public final class GetFriendRecommendListInfoScRspOuterClass { + /** + * Protobuf type {@code GetFriendRecommendListInfoScRsp} + */ + public static final class GetFriendRecommendListInfoScRsp extends ProtoMessage implements Cloneable { + private static final long serialVersionUID = 0L; + + /** + * optional uint32 retcode = 12; + */ + private int retcode; + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + */ + private final RepeatedMessage friendRecommendList = RepeatedMessage.newEmptyInstance(FriendRecommendInfoOuterClass.FriendRecommendInfo.getFactory()); + + private GetFriendRecommendListInfoScRsp() { + } + + /** + * @return a new empty instance of {@code GetFriendRecommendListInfoScRsp} + */ + public static GetFriendRecommendListInfoScRsp newInstance() { + return new GetFriendRecommendListInfoScRsp(); + } + + /** + * optional uint32 retcode = 12; + * @return whether the retcode field is set + */ + public boolean hasRetcode() { + return (bitField0_ & 0x00000001) != 0; + } + + /** + * optional uint32 retcode = 12; + * @return this + */ + public GetFriendRecommendListInfoScRsp clearRetcode() { + bitField0_ &= ~0x00000001; + retcode = 0; + return this; + } + + /** + * optional uint32 retcode = 12; + * @return the retcode + */ + public int getRetcode() { + return retcode; + } + + /** + * optional uint32 retcode = 12; + * @param value the retcode to set + * @return this + */ + public GetFriendRecommendListInfoScRsp setRetcode(final int value) { + bitField0_ |= 0x00000001; + retcode = value; + return this; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * @return whether the friendRecommendList field is set + */ + public boolean hasFriendRecommendList() { + return (bitField0_ & 0x00000002) != 0; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * @return this + */ + public GetFriendRecommendListInfoScRsp clearFriendRecommendList() { + bitField0_ &= ~0x00000002; + friendRecommendList.clear(); + return this; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * + * This method returns the internal storage object without modifying any has state. + * The returned object should not be modified and be treated as read-only. + * + * Use {@link #getMutableFriendRecommendList()} if you want to modify it. + * + * @return internal storage object for reading + */ + public RepeatedMessage getFriendRecommendList( + ) { + return friendRecommendList; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * + * This method returns the internal storage object and sets the corresponding + * has state. The returned object will become part of this message and its + * contents may be modified as long as the has state is not cleared. + * + * @return internal storage object for modifications + */ + public RepeatedMessage getMutableFriendRecommendList( + ) { + bitField0_ |= 0x00000002; + return friendRecommendList; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * @param value the friendRecommendList to add + * @return this + */ + public GetFriendRecommendListInfoScRsp addFriendRecommendList( + final FriendRecommendInfoOuterClass.FriendRecommendInfo value) { + bitField0_ |= 0x00000002; + friendRecommendList.add(value); + return this; + } + + /** + * repeated .FriendRecommendInfo friend_recommend_list = 5; + * @param values the friendRecommendList to add + * @return this + */ + public GetFriendRecommendListInfoScRsp addAllFriendRecommendList( + final FriendRecommendInfoOuterClass.FriendRecommendInfo... values) { + bitField0_ |= 0x00000002; + friendRecommendList.addAll(values); + return this; + } + + @Override + public GetFriendRecommendListInfoScRsp copyFrom(final GetFriendRecommendListInfoScRsp other) { + cachedSize = other.cachedSize; + if ((bitField0_ | other.bitField0_) != 0) { + bitField0_ = other.bitField0_; + retcode = other.retcode; + friendRecommendList.copyFrom(other.friendRecommendList); + } + return this; + } + + @Override + public GetFriendRecommendListInfoScRsp mergeFrom(final GetFriendRecommendListInfoScRsp other) { + if (other.isEmpty()) { + return this; + } + cachedSize = -1; + if (other.hasRetcode()) { + setRetcode(other.retcode); + } + if (other.hasFriendRecommendList()) { + getMutableFriendRecommendList().addAll(other.friendRecommendList); + } + return this; + } + + @Override + public GetFriendRecommendListInfoScRsp clear() { + if (isEmpty()) { + return this; + } + cachedSize = -1; + bitField0_ = 0; + retcode = 0; + friendRecommendList.clear(); + return this; + } + + @Override + public GetFriendRecommendListInfoScRsp clearQuick() { + if (isEmpty()) { + return this; + } + cachedSize = -1; + bitField0_ = 0; + friendRecommendList.clearQuick(); + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof GetFriendRecommendListInfoScRsp)) { + return false; + } + GetFriendRecommendListInfoScRsp other = (GetFriendRecommendListInfoScRsp) o; + return bitField0_ == other.bitField0_ + && (!hasRetcode() || retcode == other.retcode) + && (!hasFriendRecommendList() || friendRecommendList.equals(other.friendRecommendList)); + } + + @Override + public void writeTo(final ProtoSink output) throws IOException { + if ((bitField0_ & 0x00000001) != 0) { + output.writeRawByte((byte) 96); + output.writeUInt32NoTag(retcode); + } + if ((bitField0_ & 0x00000002) != 0) { + for (int i = 0; i < friendRecommendList.length(); i++) { + output.writeRawByte((byte) 42); + output.writeMessageNoTag(friendRecommendList.get(i)); + } + } + } + + @Override + protected int computeSerializedSize() { + int size = 0; + if ((bitField0_ & 0x00000001) != 0) { + size += 1 + ProtoSink.computeUInt32SizeNoTag(retcode); + } + if ((bitField0_ & 0x00000002) != 0) { + size += (1 * friendRecommendList.length()) + ProtoSink.computeRepeatedMessageSizeNoTag(friendRecommendList); + } + return size; + } + + @Override + @SuppressWarnings("fallthrough") + public GetFriendRecommendListInfoScRsp mergeFrom(final ProtoSource input) throws IOException { + // Enabled Fall-Through Optimization (QuickBuffers) + int tag = input.readTag(); + while (true) { + switch (tag) { + case 96: { + // retcode + retcode = input.readUInt32(); + bitField0_ |= 0x00000001; + tag = input.readTag(); + if (tag != 42) { + break; + } + } + case 42: { + // friendRecommendList + tag = input.readRepeatedMessage(friendRecommendList, tag); + bitField0_ |= 0x00000002; + 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.retcode, retcode); + } + if ((bitField0_ & 0x00000002) != 0) { + output.writeRepeatedMessage(FieldNames.friendRecommendList, friendRecommendList); + } + output.endObject(); + } + + @Override + public GetFriendRecommendListInfoScRsp mergeFrom(final JsonSource input) throws IOException { + if (!input.beginObject()) { + return this; + } + while (!input.isAtEnd()) { + switch (input.readFieldHash()) { + case 1097936398: { + if (input.isAtField(FieldNames.retcode)) { + if (!input.trySkipNullValue()) { + retcode = input.readUInt32(); + bitField0_ |= 0x00000001; + } + } else { + input.skipUnknownField(); + } + break; + } + case 1367821692: + case -194477566: { + if (input.isAtField(FieldNames.friendRecommendList)) { + if (!input.trySkipNullValue()) { + input.readRepeatedMessage(friendRecommendList); + bitField0_ |= 0x00000002; + } + } else { + input.skipUnknownField(); + } + break; + } + default: { + input.skipUnknownField(); + break; + } + } + } + input.endObject(); + return this; + } + + @Override + public GetFriendRecommendListInfoScRsp clone() { + return new GetFriendRecommendListInfoScRsp().copyFrom(this); + } + + @Override + public boolean isEmpty() { + return ((bitField0_) == 0); + } + + public static GetFriendRecommendListInfoScRsp parseFrom(final byte[] data) throws + InvalidProtocolBufferException { + return ProtoMessage.mergeFrom(new GetFriendRecommendListInfoScRsp(), data).checkInitialized(); + } + + public static GetFriendRecommendListInfoScRsp parseFrom(final ProtoSource input) throws + IOException { + return ProtoMessage.mergeFrom(new GetFriendRecommendListInfoScRsp(), input).checkInitialized(); + } + + public static GetFriendRecommendListInfoScRsp parseFrom(final JsonSource input) throws + IOException { + return ProtoMessage.mergeFrom(new GetFriendRecommendListInfoScRsp(), input).checkInitialized(); + } + + /** + * @return factory for creating GetFriendRecommendListInfoScRsp messages + */ + public static MessageFactory getFactory() { + return GetFriendRecommendListInfoScRspFactory.INSTANCE; + } + + private enum GetFriendRecommendListInfoScRspFactory implements MessageFactory { + INSTANCE; + + @Override + public GetFriendRecommendListInfoScRsp create() { + return GetFriendRecommendListInfoScRsp.newInstance(); + } + } + + /** + * Contains name constants used for serializing JSON + */ + static class FieldNames { + static final FieldName retcode = FieldName.forField("retcode"); + + static final FieldName friendRecommendList = FieldName.forField("friendRecommendList", "friend_recommend_list"); + } + } +} diff --git a/src/main/java/emu/lunarcore/server/game/GameServer.java b/src/main/java/emu/lunarcore/server/game/GameServer.java index f986005..c23fbbb 100644 --- a/src/main/java/emu/lunarcore/server/game/GameServer.java +++ b/src/main/java/emu/lunarcore/server/game/GameServer.java @@ -114,6 +114,24 @@ public class GameServer extends KcpServer { } } + public List getRandomOnlinePlayers(int amount, Player filter) { + List list = new ArrayList<>(); + + synchronized (this.players) { + var iterator = this.players.values().iterator(); + + while (iterator.hasNext() && list.size() < amount) { + Player player = iterator.next(); + + if (player != filter) { + list.add(player); + } + } + } + + return list; + } + public boolean deletePlayer(String accountUid) { // Check if player exists Player player = this.getOnlinePlayerByAccountId(accountUid); diff --git a/src/main/java/emu/lunarcore/server/packet/recv/HandlerGetFriendRecommendListInfoCsReq.java b/src/main/java/emu/lunarcore/server/packet/recv/HandlerGetFriendRecommendListInfoCsReq.java new file mode 100644 index 0000000..94e0655 --- /dev/null +++ b/src/main/java/emu/lunarcore/server/packet/recv/HandlerGetFriendRecommendListInfoCsReq.java @@ -0,0 +1,18 @@ +package emu.lunarcore.server.packet.recv; + +import emu.lunarcore.server.game.GameSession; +import emu.lunarcore.server.packet.CmdId; +import emu.lunarcore.server.packet.Opcodes; +import emu.lunarcore.server.packet.PacketHandler; +import emu.lunarcore.server.packet.send.PacketGetFriendRecommendListInfoScRsp; + +@Opcodes(CmdId.GetFriendRecommendListInfoCsReq) +public class HandlerGetFriendRecommendListInfoCsReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] data) throws Exception { + var list = session.getServer().getRandomOnlinePlayers(10, session.getPlayer()); + session.send(new PacketGetFriendRecommendListInfoScRsp(list)); + } + +} diff --git a/src/main/java/emu/lunarcore/server/packet/recv/HandlerSearchPlayerCsReq.java b/src/main/java/emu/lunarcore/server/packet/recv/HandlerSearchPlayerCsReq.java index d747494..ebfa3e7 100644 --- a/src/main/java/emu/lunarcore/server/packet/recv/HandlerSearchPlayerCsReq.java +++ b/src/main/java/emu/lunarcore/server/packet/recv/HandlerSearchPlayerCsReq.java @@ -18,8 +18,10 @@ public class HandlerSearchPlayerCsReq extends PacketHandler { public void handle(GameSession session, byte[] data) throws Exception { var req = SearchPlayerCsReq.parseFrom(data); + // Setup result list List results = new ArrayList<>(); + // Get searched player for (int uid : req.getSearchUidList()) { Player target = session.getServer().getPlayerByUid(uid, true); diff --git a/src/main/java/emu/lunarcore/server/packet/send/PacketGetFriendRecommendListInfoScRsp.java b/src/main/java/emu/lunarcore/server/packet/send/PacketGetFriendRecommendListInfoScRsp.java new file mode 100644 index 0000000..e7721d4 --- /dev/null +++ b/src/main/java/emu/lunarcore/server/packet/send/PacketGetFriendRecommendListInfoScRsp.java @@ -0,0 +1,27 @@ +package emu.lunarcore.server.packet.send; + +import java.util.Collection; + +import emu.lunarcore.game.player.Player; +import emu.lunarcore.proto.FriendRecommendInfoOuterClass.FriendRecommendInfo; +import emu.lunarcore.proto.GetFriendRecommendListInfoScRspOuterClass.GetFriendRecommendListInfoScRsp; +import emu.lunarcore.server.packet.BasePacket; +import emu.lunarcore.server.packet.CmdId; + +public class PacketGetFriendRecommendListInfoScRsp extends BasePacket { + + public PacketGetFriendRecommendListInfoScRsp(Collection list) { + super(CmdId.GetFriendRecommendListInfoScRsp); + + var data = GetFriendRecommendListInfoScRsp.newInstance(); + + for (Player player : list) { + var info = FriendRecommendInfo.newInstance() + .setSimpleInfo(player.toSimpleInfo()); + + data.addFriendRecommendList(info); + } + + this.setData(data); + } +}