diff --git a/src/generated/main/java/emu/grasscutter/net/proto/FriendBriefOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/FriendBriefOuterClass.java
index 7dde37122..0e1e0e2f3 100644
--- a/src/generated/main/java/emu/grasscutter/net/proto/FriendBriefOuterClass.java
+++ b/src/generated/main/java/emu/grasscutter/net/proto/FriendBriefOuterClass.java
@@ -217,16 +217,16 @@ public final class FriendBriefOuterClass {
emu.grasscutter.net.proto.PlatformTypeOuterClass.PlatformType getPlatformType();
/**
- * bool IEAHDCLDOEJ = 28;
- * @return The iEAHDCLDOEJ.
+ * bool is_in_duel = 28;
+ * @return The isInDuel.
*/
- boolean getIEAHDCLDOEJ();
+ boolean getIsInDuel();
/**
- * bool BJFJJMGENCH = 29;
- * @return The bJFJJMGENCH.
+ * bool is_duel_observable = 29;
+ * @return The isDuelObservable.
*/
- boolean getBJFJJMGENCH();
+ boolean getIsDuelObservable();
}
/**
*
@@ -417,12 +417,12 @@ public final class FriendBriefOuterClass {
}
case 224: {
- iEAHDCLDOEJ_ = input.readBool();
+ isInDuel_ = input.readBool();
break;
}
case 232: {
- bJFJJMGENCH_ = input.readBool();
+ isDuelObservable_ = input.readBool();
break;
}
default: {
@@ -878,26 +878,26 @@ public final class FriendBriefOuterClass {
return result == null ? emu.grasscutter.net.proto.PlatformTypeOuterClass.PlatformType.UNRECOGNIZED : result;
}
- public static final int IEAHDCLDOEJ_FIELD_NUMBER = 28;
- private boolean iEAHDCLDOEJ_;
+ public static final int IS_IN_DUEL_FIELD_NUMBER = 28;
+ private boolean isInDuel_;
/**
- * bool IEAHDCLDOEJ = 28;
- * @return The iEAHDCLDOEJ.
+ * bool is_in_duel = 28;
+ * @return The isInDuel.
*/
@java.lang.Override
- public boolean getIEAHDCLDOEJ() {
- return iEAHDCLDOEJ_;
+ public boolean getIsInDuel() {
+ return isInDuel_;
}
- public static final int BJFJJMGENCH_FIELD_NUMBER = 29;
- private boolean bJFJJMGENCH_;
+ public static final int IS_DUEL_OBSERVABLE_FIELD_NUMBER = 29;
+ private boolean isDuelObservable_;
/**
- * bool BJFJJMGENCH = 29;
- * @return The bJFJJMGENCH.
+ * bool is_duel_observable = 29;
+ * @return The isDuelObservable.
*/
@java.lang.Override
- public boolean getBJFJJMGENCH() {
- return bJFJJMGENCH_;
+ public boolean getIsDuelObservable() {
+ return isDuelObservable_;
}
private byte memoizedIsInitialized = -1;
@@ -980,11 +980,11 @@ public final class FriendBriefOuterClass {
if (platformType_ != emu.grasscutter.net.proto.PlatformTypeOuterClass.PlatformType.PLATFORM_TYPE_EDITOR.getNumber()) {
output.writeEnum(27, platformType_);
}
- if (iEAHDCLDOEJ_ != false) {
- output.writeBool(28, iEAHDCLDOEJ_);
+ if (isInDuel_ != false) {
+ output.writeBool(28, isInDuel_);
}
- if (bJFJJMGENCH_ != false) {
- output.writeBool(29, bJFJJMGENCH_);
+ if (isDuelObservable_ != false) {
+ output.writeBool(29, isDuelObservable_);
}
unknownFields.writeTo(output);
}
@@ -1079,13 +1079,13 @@ public final class FriendBriefOuterClass {
size += com.google.protobuf.CodedOutputStream
.computeEnumSize(27, platformType_);
}
- if (iEAHDCLDOEJ_ != false) {
+ if (isInDuel_ != false) {
size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(28, iEAHDCLDOEJ_);
+ .computeBoolSize(28, isInDuel_);
}
- if (bJFJJMGENCH_ != false) {
+ if (isDuelObservable_ != false) {
size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(29, bJFJJMGENCH_);
+ .computeBoolSize(29, isDuelObservable_);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
@@ -1146,10 +1146,10 @@ public final class FriendBriefOuterClass {
if (getIsPsnSource()
!= other.getIsPsnSource()) return false;
if (platformType_ != other.platformType_) return false;
- if (getIEAHDCLDOEJ()
- != other.getIEAHDCLDOEJ()) return false;
- if (getBJFJJMGENCH()
- != other.getBJFJJMGENCH()) return false;
+ if (getIsInDuel()
+ != other.getIsInDuel()) return false;
+ if (getIsDuelObservable()
+ != other.getIsDuelObservable()) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@@ -1213,12 +1213,12 @@ public final class FriendBriefOuterClass {
getIsPsnSource());
hash = (37 * hash) + PLATFORM_TYPE_FIELD_NUMBER;
hash = (53 * hash) + platformType_;
- hash = (37 * hash) + IEAHDCLDOEJ_FIELD_NUMBER;
+ hash = (37 * hash) + IS_IN_DUEL_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
- getIEAHDCLDOEJ());
- hash = (37 * hash) + BJFJJMGENCH_FIELD_NUMBER;
+ getIsInDuel());
+ hash = (37 * hash) + IS_DUEL_OBSERVABLE_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
- getBJFJJMGENCH());
+ getIsDuelObservable());
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
@@ -1409,9 +1409,9 @@ public final class FriendBriefOuterClass {
platformType_ = 0;
- iEAHDCLDOEJ_ = false;
+ isInDuel_ = false;
- bJFJJMGENCH_ = false;
+ isDuelObservable_ = false;
return this;
}
@@ -1474,8 +1474,8 @@ public final class FriendBriefOuterClass {
result.isGameSource_ = isGameSource_;
result.isPsnSource_ = isPsnSource_;
result.platformType_ = platformType_;
- result.iEAHDCLDOEJ_ = iEAHDCLDOEJ_;
- result.bJFJJMGENCH_ = bJFJJMGENCH_;
+ result.isInDuel_ = isInDuel_;
+ result.isDuelObservable_ = isDuelObservable_;
onBuilt();
return result;
}
@@ -1617,11 +1617,11 @@ public final class FriendBriefOuterClass {
if (other.platformType_ != 0) {
setPlatformTypeValue(other.getPlatformTypeValue());
}
- if (other.getIEAHDCLDOEJ() != false) {
- setIEAHDCLDOEJ(other.getIEAHDCLDOEJ());
+ if (other.getIsInDuel() != false) {
+ setIsInDuel(other.getIsInDuel());
}
- if (other.getBJFJJMGENCH() != false) {
- setBJFJJMGENCH(other.getBJFJJMGENCH());
+ if (other.getIsDuelObservable() != false) {
+ setIsDuelObservable(other.getIsDuelObservable());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
@@ -2881,64 +2881,64 @@ public final class FriendBriefOuterClass {
return this;
}
- private boolean iEAHDCLDOEJ_ ;
+ private boolean isInDuel_ ;
/**
- * bool IEAHDCLDOEJ = 28;
- * @return The iEAHDCLDOEJ.
+ * bool is_in_duel = 28;
+ * @return The isInDuel.
*/
@java.lang.Override
- public boolean getIEAHDCLDOEJ() {
- return iEAHDCLDOEJ_;
+ public boolean getIsInDuel() {
+ return isInDuel_;
}
/**
- * bool IEAHDCLDOEJ = 28;
- * @param value The iEAHDCLDOEJ to set.
+ * bool is_in_duel = 28;
+ * @param value The isInDuel to set.
* @return This builder for chaining.
*/
- public Builder setIEAHDCLDOEJ(boolean value) {
+ public Builder setIsInDuel(boolean value) {
- iEAHDCLDOEJ_ = value;
+ isInDuel_ = value;
onChanged();
return this;
}
/**
- * bool IEAHDCLDOEJ = 28;
+ * bool is_in_duel = 28;
* @return This builder for chaining.
*/
- public Builder clearIEAHDCLDOEJ() {
+ public Builder clearIsInDuel() {
- iEAHDCLDOEJ_ = false;
+ isInDuel_ = false;
onChanged();
return this;
}
- private boolean bJFJJMGENCH_ ;
+ private boolean isDuelObservable_ ;
/**
- * bool BJFJJMGENCH = 29;
- * @return The bJFJJMGENCH.
+ * bool is_duel_observable = 29;
+ * @return The isDuelObservable.
*/
@java.lang.Override
- public boolean getBJFJJMGENCH() {
- return bJFJJMGENCH_;
+ public boolean getIsDuelObservable() {
+ return isDuelObservable_;
}
/**
- * bool BJFJJMGENCH = 29;
- * @param value The bJFJJMGENCH to set.
+ * bool is_duel_observable = 29;
+ * @param value The isDuelObservable to set.
* @return This builder for chaining.
*/
- public Builder setBJFJJMGENCH(boolean value) {
+ public Builder setIsDuelObservable(boolean value) {
- bJFJJMGENCH_ = value;
+ isDuelObservable_ = value;
onChanged();
return this;
}
/**
- * bool BJFJJMGENCH = 29;
+ * bool is_duel_observable = 29;
* @return This builder for chaining.
*/
- public Builder clearBJFJJMGENCH() {
+ public Builder clearIsDuelObservable() {
- bJFJJMGENCH_ = false;
+ isDuelObservable_ = false;
onChanged();
return this;
}
@@ -3012,7 +3012,7 @@ public final class FriendBriefOuterClass {
"\n\021FriendBrief.proto\032\027FriendOnlineState.p" +
"roto\032\032SocialShowAvatarInfo.proto\032\033Friend" +
"EnterHomeOption.proto\032\024ProfilePicture.pr" +
- "oto\032\022PlatformType.proto\"\210\005\n\013FriendBrief\022" +
+ "oto\032\022PlatformType.proto\"\216\005\n\013FriendBrief\022" +
"\013\n\003uid\030\001 \001(\r\022\020\n\010nickname\030\002 \001(\t\022\r\n\005level\030" +
"\003 \001(\r\022\021\n\tavatar_id\030\004 \001(\r\022\023\n\013world_level\030" +
"\005 \001(\r\022\021\n\tsignature\030\006 \001(\t\022(\n\014online_state" +
@@ -3027,9 +3027,9 @@ public final class FriendBriefOuterClass {
"\0162\026.FriendEnterHomeOption\022(\n\017profile_pic" +
"ture\030\030 \001(\0132\017.ProfilePicture\022\026\n\016is_game_s" +
"ource\030\031 \001(\010\022\025\n\ris_psn_source\030\032 \001(\010\022$\n\rpl" +
- "atform_type\030\033 \001(\0162\r.PlatformType\022\023\n\013IEAH" +
- "DCLDOEJ\030\034 \001(\010\022\023\n\013BJFJJMGENCH\030\035 \001(\010B\033\n\031em" +
- "u.grasscutter.net.protob\006proto3"
+ "atform_type\030\033 \001(\0162\r.PlatformType\022\022\n\nis_i" +
+ "n_duel\030\034 \001(\010\022\032\n\022is_duel_observable\030\035 \001(\010" +
+ "B\033\n\031emu.grasscutter.net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
@@ -3045,7 +3045,7 @@ public final class FriendBriefOuterClass {
internal_static_FriendBrief_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_FriendBrief_descriptor,
- new java.lang.String[] { "Uid", "Nickname", "Level", "AvatarId", "WorldLevel", "Signature", "OnlineState", "Param", "IsMpModeAvailable", "OnlineId", "LastActiveTime", "NameCardId", "MpPlayerNum", "IsChatNoDisturb", "ChatSequence", "RemarkName", "ShowAvatarInfoList", "FriendEnterHomeOption", "ProfilePicture", "IsGameSource", "IsPsnSource", "PlatformType", "IEAHDCLDOEJ", "BJFJJMGENCH", });
+ new java.lang.String[] { "Uid", "Nickname", "Level", "AvatarId", "WorldLevel", "Signature", "OnlineState", "Param", "IsMpModeAvailable", "OnlineId", "LastActiveTime", "NameCardId", "MpPlayerNum", "IsChatNoDisturb", "ChatSequence", "RemarkName", "ShowAvatarInfoList", "FriendEnterHomeOption", "ProfilePicture", "IsGameSource", "IsPsnSource", "PlatformType", "IsInDuel", "IsDuelObservable", });
emu.grasscutter.net.proto.FriendOnlineStateOuterClass.getDescriptor();
emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass.getDescriptor();
emu.grasscutter.net.proto.FriendEnterHomeOptionOuterClass.getDescriptor();
diff --git a/src/main/java/emu/grasscutter/game/friends/Friendship.java b/src/main/java/emu/grasscutter/game/friends/Friendship.java
index 3e28e9aa6..2282b7857 100644
--- a/src/main/java/emu/grasscutter/game/friends/Friendship.java
+++ b/src/main/java/emu/grasscutter/game/friends/Friendship.java
@@ -14,19 +14,24 @@ import org.bson.types.ObjectId;
@Entity(value = "friendships", useDiscriminator = false)
public class Friendship {
- @Id private ObjectId id;
+ @Id
+ private ObjectId id;
- @Transient private Player owner;
+ @Transient
+ private Player owner;
- @Indexed private int ownerId;
- @Indexed private int friendId;
+ @Indexed
+ private int ownerId;
+ @Indexed
+ private int friendId;
private boolean isFriend;
private int askerId;
private PlayerProfile profile;
@Deprecated // Morphia use only
- public Friendship() {}
+ public Friendship() {
+ }
public Friendship(Player owner, Player friend, Player asker) {
this.setOwner(owner);
@@ -90,28 +95,28 @@ public class Friendship {
}
public FriendBrief toProto() {
- FriendBrief proto =
- FriendBrief.newBuilder()
- .setUid(getFriendProfile().getUid())
- .setNickname(getFriendProfile().getName())
- .setLevel(getFriendProfile().getPlayerLevel())
- .setProfilePicture(
- ProfilePicture.newBuilder().setAvatarId(getFriendProfile().getAvatarId()))
- .setWorldLevel(getFriendProfile().getWorldLevel())
- .setSignature(getFriendProfile().getSignature())
- .setOnlineState(
- getFriendProfile().isOnline()
- ? FriendOnlineState.FRIEND_ONLINE_STATE_ONLINE
- : FriendOnlineState.FRIEND_ONLINE_STATE_DISCONNECT)
- .setIsMpModeAvailable(true)
- .setLastActiveTime(getFriendProfile().getLastActiveTime())
- .setNameCardId(getFriendProfile().getNameCard())
- .setParam(getFriendProfile().getDaysSinceLogin())
- .setIsGameSource(true)
- .setPlatformType(PlatformTypeOuterClass.PlatformType.PLATFORM_TYPE_PC)
- .setFriendEnterHomeOptionValue(getFriendProfile().getEnterHomeOption())
- .build();
+ var player = this.getFriendProfile().getPlayer(); // get latest player and sync.
- return proto;
+ return FriendBrief.newBuilder()
+ .setUid(getFriendProfile().getUid())
+ .setNickname(getFriendProfile().getName())
+ .setLevel(getFriendProfile().getPlayerLevel())
+ .setProfilePicture(
+ ProfilePicture.newBuilder().setAvatarId(getFriendProfile().getAvatarId()))
+ .setWorldLevel(getFriendProfile().getWorldLevel())
+ .setSignature(getFriendProfile().getSignature())
+ .setOnlineState(
+ player != null && player.isOnline()
+ ? FriendOnlineState.FRIEND_ONLINE_STATE_ONLINE
+ : FriendOnlineState.FRIEND_ONLINE_STATE_DISCONNECT)
+ .setIsMpModeAvailable(true)
+ .setLastActiveTime(getFriendProfile().getLastActiveTime())
+ .setNameCardId(getFriendProfile().getNameCard())
+ .setParam(getFriendProfile().getDaysSinceLogin())
+ .setIsGameSource(true)
+ .setPlatformType(PlatformTypeOuterClass.PlatformType.PLATFORM_TYPE_PC)
+ .setIsInDuel(getFriendProfile().isInDuel())
+ .setIsDuelObservable(getFriendProfile().isDuelObservable())
+ .build();
}
}
diff --git a/src/main/java/emu/grasscutter/game/friends/PlayerProfile.java b/src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
index b6676e9d7..d8106a7f8 100644
--- a/src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
+++ b/src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
@@ -2,17 +2,21 @@ package emu.grasscutter.game.friends;
import dev.morphia.annotations.AlsoLoad;
import dev.morphia.annotations.Entity;
+
+import emu.grasscutter.Grasscutter;
+
import dev.morphia.annotations.Transient;
import emu.grasscutter.game.home.GameHome;
+
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.FriendEnterHomeOptionOuterClass;
import emu.grasscutter.utils.Utils;
import lombok.Getter;
+import org.jetbrains.annotations.Nullable;
@Entity
+@Getter
public class PlayerProfile {
- @Transient private Player player;
-
@AlsoLoad("id")
private int uid;
@@ -24,9 +28,14 @@ public class PlayerProfile {
private int playerLevel;
private int worldLevel;
private int lastActiveTime;
+
+ private boolean isInDuel = false; // TODO: Implement duels. (TCG)
+ private boolean isDuelObservable = false; // TODO: Implement duels. (TCG)
+
@Getter
private int enterHomeOption;
+
@Deprecated // Morphia only
public PlayerProfile() {}
@@ -35,46 +44,13 @@ public class PlayerProfile {
this.syncWithCharacter(player);
}
- public int getUid() {
- return uid;
- }
-
+ @Nullable
public Player getPlayer() {
+ var player = Grasscutter.getGameServer().getPlayerByUid(this.getUid(), true);
+ this.syncWithCharacter(player);
return player;
}
- public synchronized void setPlayer(Player player) {
- this.player = player;
- }
-
- public String getName() {
- return name;
- }
-
- public int getNameCard() {
- return nameCard;
- }
-
- public int getAvatarId() {
- return avatarId;
- }
-
- public String getSignature() {
- return signature;
- }
-
- public int getPlayerLevel() {
- return playerLevel;
- }
-
- public int getWorldLevel() {
- return worldLevel;
- }
-
- public int getLastActiveTime() {
- return lastActiveTime;
- }
-
public void updateLastActiveTime() {
this.lastActiveTime = Utils.getCurrentSeconds();
}
@@ -83,10 +59,6 @@ public class PlayerProfile {
return (int) Math.floor((Utils.getCurrentSeconds() - getLastActiveTime()) / 86400.0);
}
- public boolean isOnline() {
- return this.getPlayer() != null;
- }
-
public void syncWithCharacter(Player player) {
if (player == null) {
return;
diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java
index e84e433f4..c067739b2 100644
--- a/src/main/java/emu/grasscutter/game/player/Player.java
+++ b/src/main/java/emu/grasscutter/game/player/Player.java
@@ -1488,7 +1488,6 @@ public class Player implements PlayerHook, FieldFetch {
// register
getServer().registerPlayer(this);
- getProfile().setPlayer(this); // Set online
}
public void onLogout() {
@@ -1509,7 +1508,6 @@ public class Player implements PlayerHook, FieldFetch {
// Status stuff
this.getProfile().syncWithCharacter(this);
- this.getProfile().setPlayer(null); // Set offline
this.getCoopRequests().clear();
this.getEnterHomeRequests().values().forEach(req -> this.expireEnterHomeRequest(req, true));