Fix player location updates in co-op

This commit is contained in:
Melledy 2022-04-20 18:44:02 -07:00
parent b9876fc056
commit 7f2de4fab8
4 changed files with 34 additions and 6 deletions

View File

@ -31,6 +31,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason; import emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason;
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo; import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify; import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify;
@ -49,9 +50,11 @@ import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify; import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify; import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify;
import emu.grasscutter.server.packet.send.PacketPrivateChatNotify; import emu.grasscutter.server.packet.send.PacketPrivateChatNotify;
import emu.grasscutter.server.packet.send.PacketScenePlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketSetNameCardRsp; import emu.grasscutter.server.packet.send.PacketSetNameCardRsp;
import emu.grasscutter.server.packet.send.PacketStoreWeightLimitNotify; import emu.grasscutter.server.packet.send.PacketStoreWeightLimitNotify;
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify; import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify; import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
@ -101,6 +104,7 @@ public class GenshinPlayer {
@Transient private int enterSceneToken; @Transient private int enterSceneToken;
@Transient private SceneLoadState sceneState; @Transient private SceneLoadState sceneState;
@Transient private boolean hasSentAvatarDataNotify; @Transient private boolean hasSentAvatarDataNotify;
@Transient private long nextSendPlayerLocTime = 0;
@Transient private final Int2ObjectMap<CoopRequest> coopRequests; @Transient private final Int2ObjectMap<CoopRequest> coopRequests;
@Transient private final InvokeHandler<CombatInvokeEntry> combatInvokeHandler; @Transient private final InvokeHandler<CombatInvokeEntry> combatInvokeHandler;
@ -654,6 +658,13 @@ public class GenshinPlayer {
return social; return social;
} }
public WorldPlayerLocationInfo getWorldPlayerLocationInfo() {
return WorldPlayerLocationInfo.newBuilder()
.setSceneId(this.getSceneId())
.setPlayerLoc(this.getPlayerLocationInfo())
.build();
}
public PlayerLocationInfo getPlayerLocationInfo() { public PlayerLocationInfo getPlayerLocationInfo() {
return PlayerLocationInfo.newBuilder() return PlayerLocationInfo.newBuilder()
.setUid(this.getUid()) .setUid(this.getUid())
@ -679,9 +690,22 @@ public class GenshinPlayer {
} }
// Ping // Ping
if (this.getWorld() != null) { if (this.getWorld() != null) {
this.sendPacket(new PacketWorldPlayerRTTNotify(this.getWorld())); // Player ping // RTT notify - very important to send this often
this.sendPacket(new PacketWorldPlayerRTTNotify(this.getWorld()));
// Update player locations if in multiplayer every 5 seconds
long time = System.currentTimeMillis();
if (this.getWorld().isMultiplayer() && this.getScene() != null && time > nextSendPlayerLocTime) {
this.sendPacket(new PacketWorldPlayerLocationNotify(this.getWorld()));
this.sendPacket(new PacketScenePlayerLocationNotify(this.getScene()));
this.resetSendPlayerLocTime();
}
} }
} }
public void resetSendPlayerLocTime() {
this.nextSendPlayerLocTime = System.currentTimeMillis() + 5000;
}
@PostLoad @PostLoad
private void onLoad() { private void onLoad() {

View File

@ -31,8 +31,11 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
// Locations // Locations
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
session.send(new PacketScenePlayerLocationNotify(session.getPlayer())); session.send(new PacketScenePlayerLocationNotify(session.getPlayer().getScene()));
session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld()));
// Reset timer for sending player locations
session.getPlayer().resetSendPlayerLocTime();
} }
} }

View File

@ -1,19 +1,20 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ScenePlayerLocationNotifyOuterClass.ScenePlayerLocationNotify; import emu.grasscutter.net.proto.ScenePlayerLocationNotifyOuterClass.ScenePlayerLocationNotify;
public class PacketScenePlayerLocationNotify extends GenshinPacket { public class PacketScenePlayerLocationNotify extends GenshinPacket {
public PacketScenePlayerLocationNotify(GenshinPlayer player) { public PacketScenePlayerLocationNotify(GenshinScene scene) {
super(PacketOpcodes.ScenePlayerLocationNotify); super(PacketOpcodes.ScenePlayerLocationNotify);
ScenePlayerLocationNotify.Builder proto = ScenePlayerLocationNotify.newBuilder() ScenePlayerLocationNotify.Builder proto = ScenePlayerLocationNotify.newBuilder()
.setSceneId(player.getSceneId()); .setSceneId(scene.getId());
for (GenshinPlayer p : player.getWorld().getPlayers()) { for (GenshinPlayer p : scene.getPlayers()) {
proto.addPlayerLocList(p.getPlayerLocationInfo()); proto.addPlayerLocList(p.getPlayerLocationInfo());
} }

View File

@ -14,7 +14,7 @@ public class PacketWorldPlayerLocationNotify extends GenshinPacket {
WorldPlayerLocationNotify.Builder proto = WorldPlayerLocationNotify.newBuilder(); WorldPlayerLocationNotify.Builder proto = WorldPlayerLocationNotify.newBuilder();
for (GenshinPlayer p : world.getPlayers()) { for (GenshinPlayer p : world.getPlayers()) {
proto.addPlayerLocList(p.getPlayerLocationInfo()); proto.addPlayerLocList(p.getWorldPlayerLocationInfo());
} }
this.setData(proto); this.setData(proto);