Commit 058d3222 authored by Benjamin Elsdon's avatar Benjamin Elsdon
Browse files

Merge remote-tracking branch 'upstream/main'

parents dfc956a1 2572d55c
package emu.grasscutter.game.entity;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World;
public abstract class EntityGadget extends GenshinEntity {
public EntityGadget(World world) {
super(world);
public EntityGadget(GenshinScene scene) {
super(scene);
}
public abstract int getGadgetId();
......
......@@ -2,6 +2,7 @@ package emu.grasscutter.game.entity;
import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.EntityIdType;
......@@ -30,12 +31,12 @@ public class EntityItem extends EntityGadget {
private final GenshinItem item;
private final long guid;
public EntityItem(World world, GenshinPlayer player, ItemData itemData, Position pos, int count) {
super(world);
this.id = world.getNextEntityId(EntityIdType.GADGET);
public EntityItem(GenshinScene scene, GenshinPlayer player, ItemData itemData, Position pos, int count) {
super(scene);
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
this.pos = new Position(pos);
this.rot = new Position();
this.guid = player.getNextGuid();
this.guid = player.getNextGenshinGuid();
this.item = new GenshinItem(itemData, count);
}
......
......@@ -4,6 +4,7 @@ import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.common.PropGrowCurve;
import emu.grasscutter.data.def.MonsterCurveData;
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.FightProperty;
......@@ -36,9 +37,9 @@ public class EntityMonster extends GenshinEntity {
private final int level;
private int weaponEntityId;
public EntityMonster(World world, MonsterData monsterData, Position pos, int level) {
super(world);
this.id = world.getNextEntityId(EntityIdType.MONSTER);
public EntityMonster(GenshinScene scene, MonsterData monsterData, Position pos, int level) {
super(scene);
this.id = getWorld().getNextEntityId(EntityIdType.MONSTER);
this.monsterData = monsterData;
this.fightProp = new Int2FloatOpenHashMap();
this.pos = new Position(pos);
......@@ -48,7 +49,7 @@ public class EntityMonster extends GenshinEntity {
// Monster weapon
if (getMonsterWeaponId() > 0) {
this.weaponEntityId = world.getNextEntityId(EntityIdType.WEAPON);
this.weaponEntityId = getWorld().getNextEntityId(EntityIdType.WEAPON);
}
this.recalcStats();
......
package emu.grasscutter.game.entity;
import emu.grasscutter.game.GenshinScene;
import emu.grasscutter.game.World;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
......@@ -12,23 +13,27 @@ import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public abstract class GenshinEntity {
protected int id;
private final World world;
private final GenshinScene scene;
private MotionState moveState;
private int lastMoveSceneTimeMs;
private int lastMoveReliableSeq;
public GenshinEntity(World world) {
this.world = world;
public GenshinEntity(GenshinScene scene) {
this.scene = scene;
this.moveState = MotionState.MotionNone;
}
public int getId() {
return this.id;
}
public World getWorld() {
return world;
return this.getScene().getWorld();
}
public GenshinScene getScene() {
return this.scene;
}
public boolean isAlive() {
......
......@@ -79,11 +79,11 @@ public class FriendsList {
}
// Make sure asker cant do anything
if (myFriendship.getAskerId() == this.getPlayer().getId()) {
if (myFriendship.getAskerId() == this.getPlayer().getUid()) {
return;
}
GenshinPlayer target = getPlayer().getSession().getServer().forceGetPlayerById(targetUid);
GenshinPlayer target = getPlayer().getSession().getServer().getPlayerByUid(targetUid, true);
if (target == null) {
return; // Should never happen
}
......@@ -91,7 +91,7 @@ public class FriendsList {
// Get target's friendship
Friendship theirFriendship = null;
if (target.isOnline()) {
theirFriendship = target.getFriendsList().getPendingFriendById(this.getPlayer().getId());
theirFriendship = target.getFriendsList().getPendingFriendById(this.getPlayer().getUid());
} else {
theirFriendship = DatabaseHelper.getReverseFriendship(myFriendship);
}
......@@ -112,7 +112,7 @@ public class FriendsList {
this.addFriend(myFriendship);
if (target.isOnline()) {
target.getFriendsList().getPendingFriends().remove(this.getPlayer().getId());
target.getFriendsList().getPendingFriends().remove(this.getPlayer().getUid());
target.getFriendsList().addFriend(theirFriendship);
}
......@@ -124,7 +124,7 @@ public class FriendsList {
myFriendship.delete();
// Delete from target uid
if (target.isOnline()) {
theirFriendship = target.getFriendsList().getPendingFriendById(this.getPlayer().getId());
theirFriendship = target.getFriendsList().getPendingFriendById(this.getPlayer().getUid());
}
theirFriendship.delete();
}
......@@ -146,7 +146,7 @@ public class FriendsList {
GenshinPlayer friend = myFriendship.getFriendProfile().getPlayer();
if (friend != null) {
// Friend online
theirFriendship = friend.getFriendsList().getFriendById(this.getPlayer().getId());
theirFriendship = friend.getFriendsList().getFriendById(this.getPlayer().getUid());
if (theirFriendship != null) {
friend.getFriendsList().getFriends().remove(theirFriendship.getFriendId());
theirFriendship.delete();
......@@ -165,7 +165,7 @@ public class FriendsList {
}
public synchronized void sendFriendRequest(int targetUid) {
GenshinPlayer target = getPlayer().getSession().getServer().forceGetPlayerById(targetUid);
GenshinPlayer target = getPlayer().getSession().getServer().getPlayerByUid(targetUid, true);
if (target == null || target == this.getPlayer()) {
return;
......@@ -220,14 +220,14 @@ public class FriendsList {
friendship.setOwner(getPlayer());
// Check if friend is online
GenshinPlayer friend = getPlayer().getSession().getServer().getPlayerById(friendship.getFriendProfile().getId());
GenshinPlayer friend = getPlayer().getSession().getServer().getPlayerByUid(friendship.getFriendProfile().getId());
if (friend != null) {
// Set friend to online mode
friendship.setFriendProfile(friend);
// Update our status on friend's client if theyre online
if (friend.getFriendsList().hasLoaded()) {
Friendship theirFriendship = friend.getFriendsList().getFriendshipById(getPlayer().getId());
Friendship theirFriendship = friend.getFriendsList().getFriendshipById(getPlayer().getUid());
if (theirFriendship != null) {
// Update friend profile
theirFriendship.setFriendProfile(getPlayer());
......
......@@ -27,10 +27,10 @@ public class Friendship {
public Friendship(GenshinPlayer owner, GenshinPlayer friend, GenshinPlayer asker) {
this.setOwner(owner);
this.ownerId = owner.getId();
this.friendId = friend.getId();
this.ownerId = owner.getUid();
this.friendId = friend.getUid();
this.profile = friend.getProfile();
this.askerId = asker.getId();
this.askerId = asker.getUid();
}
public GenshinPlayer getOwner() {
......@@ -70,7 +70,7 @@ public class Friendship {
}
public void setFriendProfile(GenshinPlayer character) {
if (character == null || this.friendId != character.getId()) return;
if (character == null || this.friendId != character.getUid()) return;
this.profile = character.getProfile();
}
......
......@@ -22,7 +22,7 @@ public class PlayerProfile {
public PlayerProfile() { }
public PlayerProfile(GenshinPlayer player) {
this.id = player.getId();
this.id = player.getUid();
this.syncWithCharacter(player);
}
......
......@@ -125,8 +125,8 @@ public class GenshinItem {
}
public void setOwner(GenshinPlayer player) {
this.ownerId = player.getId();
this.guid = player.getNextGuid();
this.ownerId = player.getUid();
this.guid = player.getNextGenshinGuid();
}
public int getItemId() {
return itemId;
......
......@@ -6,6 +6,7 @@ import java.util.LinkedList;
import java.util.List;
import emu.grasscutter.GenshinConstants;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.AvatarCostumeData;
import emu.grasscutter.data.def.AvatarData;
......@@ -36,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> {
this.store = new Long2ObjectOpenHashMap<>();
this.inventoryTypes = new Int2ObjectOpenHashMap<>();
this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(GenshinConstants.LIMIT_WEAPON));
this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(GenshinConstants.LIMIT_RELIC));
this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(GenshinConstants.LIMIT_MATERIAL));
this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(GenshinConstants.LIMIT_FURNITURE));
this.createInventoryTab(ItemType.ITEM_WEAPON, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitWeapon));
this.createInventoryTab(ItemType.ITEM_RELIQUARY, new EquipInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitRelic));
this.createInventoryTab(ItemType.ITEM_MATERIAL, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitMaterial));
this.createInventoryTab(ItemType.ITEM_FURNITURE, new MaterialInventoryTab(Grasscutter.getConfig().getServerOptions().InventoryLimitFurniture));
}
public GenshinPlayer getPlayer() {
......
......@@ -36,14 +36,14 @@ public class ChatManager {
}
// Get target
GenshinPlayer target = getServer().getPlayerById(targetUid);
GenshinPlayer target = getServer().getPlayerByUid(targetUid);
if (target == null) {
return;
}
// Create chat packet
GenshinPacket packet = new PacketPrivateChatNotify(player.getId(), target.getId(), message);
GenshinPacket packet = new PacketPrivateChatNotify(player.getUid(), target.getUid(), message);
player.sendPacket(packet);
target.sendPacket(packet);
......@@ -51,14 +51,14 @@ public class ChatManager {
public void sendPrivateMessage(GenshinPlayer player, int targetUid, int emote) {
// Get target
GenshinPlayer target = getServer().getPlayerById(targetUid);
GenshinPlayer target = getServer().getPlayerByUid(targetUid);
if (target == null) {
return;
}
// Create chat packet
GenshinPacket packet = new PacketPrivateChatNotify(player.getId(), target.getId(), emote);
GenshinPacket packet = new PacketPrivateChatNotify(player.getUid(), target.getUid(), emote);
player.sendPacket(packet);
target.sendPacket(packet);
......
......@@ -438,8 +438,14 @@ public class InventoryManager {
return;
}
if (weapon.getItemType() != ItemType.ITEM_WEAPON || weapon.getItemId() != feed.getItemId()) {
return;
if (weapon.getItemData().getAwakenMaterial() == 0) {
if (weapon.getItemType() != ItemType.ITEM_WEAPON || weapon.getItemId() != feed.getItemId()) {
return;
}
} else {
if (weapon.getItemType() != ItemType.ITEM_WEAPON || weapon.getItemData().getAwakenMaterial() != feed.getItemId()) {
return;
}
}
if (weapon.getRefinement() >= 4 || weapon.getAffixes() == null || weapon.getAffixes().size() == 0) {
......
......@@ -24,7 +24,7 @@ public class MultiplayerManager {
}
public void applyEnterMp(GenshinPlayer player, int targetUid) {
GenshinPlayer target = getServer().getPlayerById(targetUid);
GenshinPlayer target = getServer().getPlayerByUid(targetUid);
if (target == null) {
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.PlayerCannotEnterMp));
return;
......@@ -35,13 +35,15 @@ public class MultiplayerManager {
return;
}
/*
if (target.getWorld().isDungeon()) {
player.sendPacket(new PacketPlayerApplyEnterMpResultNotify(targetUid, "", false, PlayerApplyEnterMpReason.SceneCannotEnter));
return;
}
*/
// Get request
CoopRequest request = target.getCoopRequests().get(player.getId());
CoopRequest request = target.getCoopRequests().get(player.getUid());
if (request != null && !request.isExpired()) {
// Join request already exists
......@@ -50,31 +52,31 @@ public class MultiplayerManager {
// Put request in
request = new CoopRequest(player);
target.getCoopRequests().put(player.getId(), request);
target.getCoopRequests().put(player.getUid(), request);
// Packet
target.sendPacket(new PacketPlayerApplyEnterMpNotify(player));
}
public void applyEnterMpReply(GenshinPlayer player, int applyUid, boolean isAgreed) {
public void applyEnterMpReply(GenshinPlayer hostPlayer, int applyUid, boolean isAgreed) {
// Checks
CoopRequest request = player.getCoopRequests().get(applyUid);
CoopRequest request = hostPlayer.getCoopRequests().get(applyUid);
if (request == null || request.isExpired()) {
return;
}
// Remove now that we are handling it
GenshinPlayer requester = request.getRequester();
player.getCoopRequests().remove(applyUid);
hostPlayer.getCoopRequests().remove(applyUid);
// Sanity checks - Dont let player join if already in multiplayer
// Sanity checks - Dont let the requesting player join if they are already in multiplayer
if (requester.getWorld().isMultiplayer()) {
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(player, false, PlayerApplyEnterMpReason.PlayerCannotEnterMp));
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, false, PlayerApplyEnterMpReason.PlayerCannotEnterMp));
return;
}
// Response packet
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(player, isAgreed, PlayerApplyEnterMpReason.PlayerJudge));
request.getRequester().sendPacket(new PacketPlayerApplyEnterMpResultNotify(hostPlayer, isAgreed, PlayerApplyEnterMpReason.PlayerJudge));
// Declined
if (!isAgreed) {
......@@ -82,24 +84,27 @@ public class MultiplayerManager {
}
// Success
if (!player.getWorld().isMultiplayer()) {
if (!hostPlayer.getWorld().isMultiplayer()) {
// Player not in multiplayer, create multiplayer world
World world = new World(player, true);
World world = new World(hostPlayer, true);
// Add
world.addPlayer(player);
world.addPlayer(hostPlayer);
// Rejoin packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, player, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, player.getWorld().getSceneId(), player.getPos()));
hostPlayer.sendPacket(new PacketPlayerEnterSceneNotify(hostPlayer, hostPlayer, EnterType.EnterSelf, EnterReason.HostFromSingleToMp, hostPlayer.getScene().getId(), hostPlayer.getPos()));
}
// Make requester join
player.getWorld().addPlayer(requester);
// Set scene pos and id of requester to the host player's
requester.getPos().set(hostPlayer.getPos());
requester.getRotation().set(hostPlayer.getRotation());
requester.setSceneId(hostPlayer.getSceneId());
// Make requester join
hostPlayer.getWorld().addPlayer(requester);
// Packet
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, player, EnterType.EnterOther, EnterReason.TeamJoin, player.getWorld().getSceneId(), player.getPos()));
requester.getPos().set(player.getPos());
requester.getRotation().set(player.getRotation());
requester.sendPacket(new PacketPlayerEnterSceneNotify(requester, hostPlayer, EnterType.EnterOther, EnterReason.TeamJoin, hostPlayer.getScene().getId(), hostPlayer.getPos()));
}
public boolean leaveCoop(GenshinPlayer player) {
......@@ -120,7 +125,7 @@ public class MultiplayerManager {
world.addPlayer(player);
// Packet
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getWorld().getSceneId(), player.getPos()));
player.sendPacket(new PacketPlayerEnterSceneNotify(player, EnterType.EnterSelf, EnterReason.TeamBack, player.getScene().getId(), player.getPos()));
return true;
}
......@@ -132,7 +137,7 @@ public class MultiplayerManager {
}
// Get victim and sanity checks
GenshinPlayer victim = player.getServer().getPlayerById(targetUid);
GenshinPlayer victim = player.getServer().getPlayerByUid(targetUid);
if (victim == null || victim == player) {
return false;
......@@ -147,7 +152,7 @@ public class MultiplayerManager {
World world = new World(victim);
world.addPlayer(victim);
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getWorld().getSceneId(), victim.getPos()));
victim.sendPacket(new PacketPlayerEnterSceneNotify(victim, EnterType.EnterSelf, EnterReason.TeamKick, victim.getScene().getId(), victim.getPos()));
return true;
}
}
package emu.grasscutter.game.props;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public enum SceneType {
SCENE_NONE (0),
SCENE_WORLD (1),
SCENE_DUNGEON (2),
SCENE_ROOM (3),
SCENE_HOME_WORLD (4),
SCENE_HOME_ROOM (5),
SCENE_ACTIVITY (6);
private final int value;
private static final Int2ObjectMap<SceneType> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, SceneType> stringMap = new HashMap<>();
static {
Stream.of(values()).forEach(e -> {
map.put(e.getValue(), e);
stringMap.put(e.name(), e);
});
}
private SceneType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static SceneType getTypeByValue(int value) {
return map.getOrDefault(value, SCENE_NONE);
}
public static SceneType getTypeByName(String name) {
return stringMap.getOrDefault(name, SCENE_NONE);
}
}
......@@ -958,6 +958,7 @@ public class PacketOpcodes {
public static final int SceneTimeNotify = 229;
public static final int SceneTransToPointReq = 256;
public static final int SceneTransToPointRsp = 283;
public static final int SceneUnlockInfoNotify = 3386;
public static final int SceneWeatherForcastReq = 3167;
public static final int SceneWeatherForcastRsp = 3023;
public static final int SeaLampCoinNotify = 2028;
......
......@@ -104,21 +104,25 @@ public final class GameServer extends MihoyoKcpServer {
}
public void registerPlayer(GenshinPlayer player) {
getPlayers().put(player.getId(), player);
getPlayers().put(player.getUid(), player);
}
public GenshinPlayer getPlayerById(int id) {
return this.getPlayers().get(id);
public GenshinPlayer getPlayerByUid(int id) {
return this.getPlayerByUid(id, false);
}
public GenshinPlayer forceGetPlayerById(int id) {
public GenshinPlayer getPlayerByUid(int id, boolean allowOfflinePlayers) {
// Console check
if (id == GenshinConstants.SERVER_CONSOLE_UID) {
return null;
}
// Get from online players
GenshinPlayer player = this.getPlayerById(id);
GenshinPlayer player = this.getPlayers().get(id);
if (!allowOfflinePlayers) {
return player;
}
// Check database if character isnt here
if (player == null) {
......@@ -128,9 +132,9 @@ public final class GameServer extends MihoyoKcpServer {
return player;
}
public SocialDetail.Builder getSocialDetailById(int id) {
public SocialDetail.Builder getSocialDetailByUid(int id) {
// Get from online players
GenshinPlayer player = this.forceGetPlayerById(id);
GenshinPlayer player = this.getPlayerByUid(id, true);
if (player == null) {
return null;
......
......@@ -123,7 +123,7 @@ public class GameSession extends MihoyoKcpChannel {
// Save
getPlayer().onLogout();
// Remove from gameserver
getServer().getPlayers().remove(getPlayer().getId());
getServer().getPlayers().remove(getPlayer().getUid());
}
}
......
......@@ -14,8 +14,8 @@ public class HandlerChangeGameTimeReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload);
session.getPlayer().getWorld().changeTime(req.getGameTime());
session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer().getWorld()));
session.getPlayer().getScene().changeTime(req.getGameTime());
session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer()));
}
}
......@@ -22,12 +22,12 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
case CombatEvtBeingHit:
// Handle damage
EvtBeingHitInfo hitInfo = EvtBeingHitInfo.parseFrom(entry.getCombatData());
session.getPlayer().getWorld().handleAttack(hitInfo.getAttackResult());
session.getPlayer().getScene().handleAttack(hitInfo.getAttackResult());
break;
case EntityMove:
// Handle movement
EntityMoveInfo moveInfo = EntityMoveInfo.parseFrom(entry.getCombatData());
GenshinEntity entity = session.getPlayer().getWorld().getEntityById(moveInfo.getEntityId());
GenshinEntity entity = session.getPlayer().getScene().getEntityById(moveInfo.getEntityId());
if (entity != null) {
entity.getPosition().set(moveInfo.getMotionInfo().getPos());
entity.getRotation().set(moveInfo.getMotionInfo().getRot());
......
......@@ -24,10 +24,10 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
// Spawn player in world
session.getPlayer().getWorld().spawnPlayer(session.getPlayer());
session.getPlayer().getScene().spawnPlayer(session.getPlayer());
// Spawn other entites already in world
session.getPlayer().getWorld().showOtherEntities(session.getPlayer());
session.getPlayer().getScene().showOtherEntities(session.getPlayer());
// Locations
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
......
......@@ -15,7 +15,7 @@ public class HandlerEntityAiSyncNotify extends PacketHandler {
EntityAiSyncNotify notify = EntityAiSyncNotify.parseFrom(payload);
if (notify.getLocalAvatarAlertedMonsterListCount() > 0) {
session.getPlayer().getWorld().broadcastPacket(new PacketEntityAiSyncNotify(notify));
session.getPlayer().getScene().broadcastPacket(new PacketEntityAiSyncNotify(notify));
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment