mirror of
https://github.com/Melledy/Nebula.git
synced 2026-11-04 21:36:51 +01:00
Implement dorm
This commit is contained in:
1 parent
c585417b85
commit
bd4aabd464
47 files changed
+2364
-7
No files matched your search
@@ -21,12 +21,14 @@ Latest nightly compiled server jar: [Nightly](https://nightly.link/Melledy/Nebul
|
||||
- Commissions
|
||||
- Heartlink
|
||||
- Achievements
|
||||
- Tower (dorm system)
|
||||
- Monoliths
|
||||
- Bounty Trials
|
||||
- Menance Arena
|
||||
- Proving Grounds
|
||||
- Catacylsm Survivor (talents not fully working)
|
||||
- Boss Blitz
|
||||
- Shadow Siege
|
||||
- Events (Only tower defense and trials. Other events may work)
|
||||
|
||||
### Supported regions
|
||||
|
||||
@@ -71,6 +71,25 @@ public class GameConstants {
|
||||
public static final int[] TRACE_HUNT_TRACE_IDS = {21, 22, 23, 31, 41};
|
||||
public static final int TRACE_HUNT_MAX_TRACE_PROGRESS = 10_000;
|
||||
public static final int TRACE_HUNT_MAX_HUNT_PROGRESS = 10_000;
|
||||
|
||||
// Dorm
|
||||
public static final int DORM_MAX_PRESET_NUM = 20;
|
||||
public static final int DORM_DEFAULT_PRESET_NUM = 10;
|
||||
public static final int DORM_MAX_ROOM_NUM = 4;
|
||||
public static final int DORM_INVITATION_ROLE_NORMAL_NUM = 3;
|
||||
public static final int DORM_INVITATION_ROLE_RAND_NUM = 1;
|
||||
public static final int DORM_ROLE_INTERACTION_MAX_NUM = 5;
|
||||
public static final int DORM_ROLE_INTERACTION_DROP_ID = 4002;
|
||||
public static final int DORM_ROLE_FAVORABILITY = 300;
|
||||
public static final int DORM_ROLE_AFFINITY_GIFT_MAX_NUM = 5;
|
||||
public static final int DORM_ROLE_AFFINITY_GIFT_DAILY_NUM = 1;
|
||||
public static final int DORM_NAME_RESET_TIME_LIMIT = 604_800;
|
||||
public static final int DORM_LIKE_LIMIT = 3;
|
||||
public static final int DORM_BLOCKS_CONVERT_PROP = 1;
|
||||
public static final int DORM_DEFAULT_ROOM_ID = 701001;
|
||||
public static final int DORM_JADE_ITEM_ID = 2;
|
||||
public static final int DORM_FURNITURE_COIN_ITEM_ID = 701;
|
||||
public static final int DORM_MAX_NAME_LENGTH = 20;
|
||||
|
||||
// Etc
|
||||
public static final int REFRESH_TYPE_DAILY = 1;
|
||||
|
||||
@@ -146,6 +146,21 @@ public class GameData {
|
||||
@Getter private static DataTable<TraceHuntLevelDef> TraceHuntLevelDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<TraceHuntSelfHuntExtraCostDef> TraceHuntSelfHuntExtraCostDataTable = new DataTable<>();
|
||||
|
||||
// ===== Dorm =====
|
||||
@Getter private static DataTable<DormRoomDef> DormRoomDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormFurnitureDef> DormFurnitureDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormLayoutRewardDef> DormLayoutRewardDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormRoomLayoutDef> DormRoomLayoutDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormRewardDef> DormRewardDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormAchievementDef> DormAchievementDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormHonorTitleDef> DormHonorTitleDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormRoleDef> DormRoleDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormRoleSkinDef> DormRoleSkinDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormInteractiveDef> DormInteractiveDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormQuestDef> DormQuestDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormQuestGroupDef> DormQuestGroupDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DormRoomSceneDef> DormRoomSceneDataTable = new DataTable<>();
|
||||
|
||||
// ===== Misc =====
|
||||
@Getter private static DataTable<WorldClassDef> WorldClassDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<GuideGroupDef> GuideGroupDataTable = new DataTable<>();
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormAchievement.json")
|
||||
public class DormAchievementDef extends BaseDef {
|
||||
private int Id;
|
||||
private int CompleteCond;
|
||||
private int[] CompleteParams;
|
||||
private int Tid1;
|
||||
private int Qty1;
|
||||
private int Tid2;
|
||||
private int Qty2;
|
||||
private int Tid3;
|
||||
private int Qty3;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormFurniture.json")
|
||||
public class DormFurnitureDef extends BaseDef {
|
||||
private int Id;
|
||||
private int CollectionValue;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormHonorTitle.json")
|
||||
public class DormHonorTitleDef extends BaseDef {
|
||||
private int Id;
|
||||
private int NeedExp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormInteractive.json")
|
||||
public class DormInteractiveDef extends BaseDef {
|
||||
private int Id;
|
||||
private int CharId;
|
||||
private int FurniturnId;
|
||||
private int DormInterType;
|
||||
private String AnimationConfig;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormLayoutReward.json")
|
||||
public class DormLayoutRewardDef extends BaseDef {
|
||||
private int Id;
|
||||
private int RoomType;
|
||||
private int FurnitureCount;
|
||||
private int RewardId1;
|
||||
private int Qty1;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormQuest.json")
|
||||
public class DormQuestDef extends BaseDef {
|
||||
private int Id;
|
||||
private int DormQuestGroup;
|
||||
private String Title;
|
||||
private int Reward1;
|
||||
private int RewardQty1;
|
||||
private int Reward2;
|
||||
private int RewardQty2;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormQuestGroup.json")
|
||||
public class DormQuestGroupDef extends BaseDef {
|
||||
private int Id;
|
||||
private int PreGroup;
|
||||
private String Title;
|
||||
private int Item1;
|
||||
private int Qty1;
|
||||
private int Item2;
|
||||
private int Qty2;
|
||||
private int Item3;
|
||||
private int Qty3;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.util.JsonUtils;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormReward.json")
|
||||
public class DormRewardDef extends BaseDef {
|
||||
private int Id;
|
||||
private int DropId;
|
||||
private String Conditions;
|
||||
|
||||
private transient int[][] parsedConditions;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.parsedConditions = JsonUtils.decode(this.Conditions, int[][].class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the requirements for this dorm reward.
|
||||
* Condition type 1 = the player needs to have the room unlocked.
|
||||
*/
|
||||
public boolean isUnlocked(IntSet unlockedRoomIds) {
|
||||
if (this.parsedConditions == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int[] condition : this.parsedConditions) {
|
||||
if (condition.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (condition[0]) {
|
||||
case 1 -> {
|
||||
if (!unlockedRoomIds.contains(condition[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormRole.json")
|
||||
public class DormRoleDef extends BaseDef {
|
||||
private int Id;
|
||||
private int RoleType;
|
||||
private int[] Exclusions;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormRoleSkin.json")
|
||||
public class DormRoleSkinDef extends BaseDef {
|
||||
private int Id;
|
||||
private int TrId;
|
||||
private int TrQty;
|
||||
private int UnlockChar;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormRoom.json")
|
||||
public class DormRoomDef extends BaseDef {
|
||||
private int Id;
|
||||
private int RoomType;
|
||||
private int RoomSizeType;
|
||||
private int SceneRes;
|
||||
private String DefaultName;
|
||||
private int DefaultLayoutId;
|
||||
private boolean DefaultCanUse;
|
||||
private int RoleNum;
|
||||
private int FloorRatio;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormRoomLayout.json")
|
||||
public class DormRoomLayoutDef extends BaseDef {
|
||||
private int Id;
|
||||
private int RoomLayoutId;
|
||||
private int FurnitureId;
|
||||
private int[] Pos;
|
||||
private int Rot;
|
||||
private int ApplyRoomType;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "DormRoomScene.json")
|
||||
public class DormRoomSceneDef extends BaseDef {
|
||||
private int Id;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.PublicDorm.FurnitureInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class DormFurniture {
|
||||
private int furnitureId;
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private int rotation;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public DormFurniture() {
|
||||
|
||||
}
|
||||
|
||||
public DormFurniture(int furnitureId, int x, int y, int z, int rotation) {
|
||||
this.furnitureId = furnitureId;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public DormFurniture(FurnitureInfo info) {
|
||||
this.furnitureId = info.getFurnitureId();
|
||||
this.x = info.getX();
|
||||
this.y = info.getY();
|
||||
this.z = info.getZ();
|
||||
this.rotation = info.getRotation();
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public FurnitureInfo toProto() {
|
||||
return FurnitureInfo.newInstance()
|
||||
.setFurnitureId(this.furnitureId)
|
||||
.setX(this.x)
|
||||
.setY(this.y)
|
||||
.setZ(this.z)
|
||||
.setRotation(this.rotation);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,1000 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.resources.DormRoomDef;
|
||||
import emu.nebula.data.resources.DropPkgDef;
|
||||
import emu.nebula.database.GameDatabaseObject;
|
||||
import emu.nebula.game.character.GameCharacter;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.player.PlayerManager;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormInfo.DormInfoListResp;
|
||||
import emu.nebula.proto.Public;
|
||||
import emu.nebula.proto.PublicDorm.AchievementComplete;
|
||||
import emu.nebula.proto.PublicDorm.AchievementInfo;
|
||||
import emu.nebula.proto.PublicDorm.DormAffinityGiftInfo;
|
||||
import emu.nebula.proto.PublicDorm.DormHot;
|
||||
import emu.nebula.proto.PublicDorm.DormInfoData;
|
||||
import emu.nebula.proto.PublicDorm.DormRoomUnlock;
|
||||
import emu.nebula.proto.PublicDorm.RoleInteraction;
|
||||
import emu.nebula.util.Utils;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(value = "dorm", useDiscriminator = false)
|
||||
public class DormManager extends PlayerManager implements GameDatabaseObject {
|
||||
@Id
|
||||
private int uid;
|
||||
|
||||
// Dorm details
|
||||
private String dormName;
|
||||
private long dormNameRestTime;
|
||||
|
||||
// Furniture collection
|
||||
private Int2IntMap furnitureCollection;
|
||||
|
||||
// Saved room state
|
||||
private Map<Integer, DormRoomState> rooms;
|
||||
private Map<Integer, DormPreset> presets;
|
||||
|
||||
// Rewards / achievements
|
||||
private IntSet receivedLayoutRewardIds;
|
||||
private IntSet receivedRewardIds;
|
||||
private Map<Integer, Long> completedAchievements;
|
||||
|
||||
// Social stats
|
||||
private int likeNum;
|
||||
private int dayVisitNum;
|
||||
private int visitTotalNum;
|
||||
|
||||
// Daily state
|
||||
private long lastResetDay;
|
||||
private IntSet likedFriendUids;
|
||||
private IntSet dailyVisitorUids;
|
||||
private IntSet dailyInteractionRoleIds;
|
||||
private Int2IntMap dailyAffinityGiftCounts;
|
||||
private int dailyAffinityGiftTotal;
|
||||
|
||||
private transient boolean queueSave;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public DormManager() {
|
||||
|
||||
}
|
||||
|
||||
public DormManager(Player player) {
|
||||
super(player);
|
||||
|
||||
this.uid = player.getUid();
|
||||
this.dormName = "";
|
||||
this.furnitureCollection = new Int2IntOpenHashMap();
|
||||
this.presets = new HashMap<>();
|
||||
this.rooms = new HashMap<>();
|
||||
this.receivedLayoutRewardIds = new IntOpenHashSet();
|
||||
this.receivedRewardIds = new IntOpenHashSet();
|
||||
this.completedAchievements = new HashMap<>();
|
||||
this.likedFriendUids = new IntOpenHashSet();
|
||||
this.dailyVisitorUids = new IntOpenHashSet();
|
||||
this.dailyInteractionRoleIds = new IntOpenHashSet();
|
||||
this.dailyAffinityGiftCounts = new Int2IntOpenHashMap();
|
||||
this.lastResetDay = Utils.getResetEpochDay();
|
||||
|
||||
this.save();
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return this.getReceivedRewardIds().isEmpty() ? 1 : 0;
|
||||
}
|
||||
|
||||
// Daily reset
|
||||
|
||||
public synchronized void resetDailies() {
|
||||
long currentDay = Utils.getResetEpochDay();
|
||||
|
||||
if (currentDay <= this.lastResetDay) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.likedFriendUids.clear();
|
||||
this.dailyVisitorUids.clear();
|
||||
this.dailyInteractionRoleIds.clear();
|
||||
this.dailyAffinityGiftCounts.clear();
|
||||
this.dailyAffinityGiftTotal = 0;
|
||||
this.dayVisitNum = 0;
|
||||
this.lastResetDay = currentDay;
|
||||
this.queueSave = true;
|
||||
}
|
||||
|
||||
// Rooms
|
||||
|
||||
/**
|
||||
* Returns the ids of all rooms the player has access to. Rooms are unlocked
|
||||
* by acquiring the room item, which creates the room state in {@link #rooms}.
|
||||
*/
|
||||
public IntSet getUnlockedRoomIds() {
|
||||
var result = new IntOpenHashSet();
|
||||
|
||||
// Rooms that are available by default
|
||||
for (var room : GameData.getDormRoomDataTable()) {
|
||||
if (room.isDefaultCanUse()) {
|
||||
result.add(room.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// Rooms that have been unlocked by the player
|
||||
if (this.rooms != null) {
|
||||
result.addAll(this.rooms.keySet());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isRoomUnlocked(int roomId) {
|
||||
return this.getUnlockedRoomIds().contains(roomId);
|
||||
}
|
||||
|
||||
public synchronized DormRoomState getOrCreateRoom(int roomId) {
|
||||
var room = this.rooms.get(roomId);
|
||||
if (room != null) {
|
||||
return room;
|
||||
}
|
||||
|
||||
var data = GameData.getDormRoomDataTable().get(roomId);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
room = new DormRoomState(roomId);
|
||||
room.setFurnitureList(createDefaultFurniture(data));
|
||||
|
||||
this.rooms.put(roomId, room);
|
||||
this.queueSave = true;
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
public synchronized boolean unlockRoom(int roomId, PlayerChangeInfo change) {
|
||||
if (!GameData.getDormRoomDataTable().containsKey(roomId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.rooms.containsKey(roomId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.getOrCreateRoom(roomId);
|
||||
|
||||
if (change != null) {
|
||||
this.getPlayer().trigger(QuestCondition.DormUnlockRoom, 1);
|
||||
|
||||
if (this.getPlayer().hasSession()) {
|
||||
var proto = DormRoomUnlock.newInstance()
|
||||
.setDormRoomId(roomId)
|
||||
.setChangeInfo(change.toProto());
|
||||
|
||||
this.getPlayer().addNextPackage(NetMsgId.dorm_room_unlock_notify, proto);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Furniture
|
||||
|
||||
/**
|
||||
* Adds furniture to the collection
|
||||
*/
|
||||
public synchronized void addFurniture(int id, int amount) {
|
||||
this.furnitureCollection.put(id, this.furnitureCollection.get(id) + amount);
|
||||
this.queueSave = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many of the given furniture the player owns
|
||||
*/
|
||||
public int getFurnitureCount(int id) {
|
||||
if (this.furnitureCollection == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.furnitureCollection.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the player owns at least one of the given furniture
|
||||
*/
|
||||
public boolean hasFurniture(int id) {
|
||||
return this.getFurnitureCount(id) > 0;
|
||||
}
|
||||
|
||||
public static List<DormFurniture> createDefaultFurniture(DormRoomDef room) {
|
||||
var result = new ArrayList<DormFurniture>();
|
||||
|
||||
if (room == null || room.getDefaultLayoutId() <= 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var layoutReward = GameData.getDormLayoutRewardDataTable().get(room.getDefaultLayoutId());
|
||||
if (layoutReward == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int baseId = room.getDefaultLayoutId() * 100;
|
||||
|
||||
for (int i = 1; i <= layoutReward.getFurnitureCount(); i++) {
|
||||
var layout = GameData.getDormRoomLayoutDataTable().get(baseId + i);
|
||||
if (layout == null || layout.getPos() == null || layout.getPos().length < 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int[] pos = layout.getPos();
|
||||
result.add(new DormFurniture(layout.getFurnitureId(), pos[0], pos[1], pos[2], layout.getRot()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isValidFurnitureList(List<DormFurniture> furnitureList) {
|
||||
if (furnitureList == null || furnitureList.size() > 1000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var furniture : furnitureList) {
|
||||
if (furniture == null || furniture.getFurnitureId() <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (!GameData.getDormFurnitureDataTable().containsKey(furniture.getFurnitureId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized Long saveFurnitureLayout(int roomId, List<DormFurniture> furnitureList, int buildId) {
|
||||
if (!this.isRoomUnlocked(roomId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var roomData = GameData.getDormRoomDataTable().get(roomId);
|
||||
if (roomData == null || !isValidFurnitureList(furnitureList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long now = Nebula.getCurrentServerTime();
|
||||
|
||||
if (buildId == 0) {
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
if (room == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
room.setFurnitureList(new ArrayList<>(furnitureList));
|
||||
this.queueSave = true;
|
||||
|
||||
this.getPlayer().trigger(QuestCondition.DormPlaceFurniture, furnitureList.size());
|
||||
this.getPlayer().trigger(QuestCondition.DormSaveRoom, 1);
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
if (buildId < 1 || buildId > GameConstants.DORM_DEFAULT_PRESET_NUM) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var preset = this.presets.get(buildId);
|
||||
|
||||
if (preset == null) {
|
||||
if (this.presets.size() >= GameConstants.DORM_DEFAULT_PRESET_NUM) {
|
||||
return null;
|
||||
}
|
||||
|
||||
preset = new DormPreset(buildId, roomData.getRoomType(), now);
|
||||
this.presets.put(buildId, preset);
|
||||
} else {
|
||||
preset.setCreateTime(now);
|
||||
preset.setDormType(roomData.getRoomType());
|
||||
}
|
||||
|
||||
preset.setFurnitureList(new ArrayList<>(furnitureList));
|
||||
this.queueSave = true;
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
public synchronized boolean deletePreset(int buildId) {
|
||||
if (this.presets.remove(buildId) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.queueSave = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean renamePreset(int buildId, String name) {
|
||||
// Sanity check name
|
||||
if (name == null || name.length() > GameConstants.DORM_MAX_NAME_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var preset = this.presets.get(buildId);
|
||||
if (preset == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
preset.setBuildName(name);
|
||||
this.queueSave = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean renameRoom(int roomId, String name) {
|
||||
// Sanity check name
|
||||
if (name == null || name.length() > GameConstants.DORM_MAX_NAME_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check rename cooldown
|
||||
long now = Nebula.getCurrentServerTime();
|
||||
|
||||
if (roomId == 0) {
|
||||
if (now < this.dormNameRestTime + GameConstants.DORM_NAME_RESET_TIME_LIMIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.dormName = name;
|
||||
this.dormNameRestTime = now;
|
||||
this.queueSave = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.isRoomUnlocked(roomId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
if (room == null || now < room.getRestNameTime() + GameConstants.DORM_NAME_RESET_TIME_LIMIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
room.setRoomName(name);
|
||||
room.setRestNameTime(now);
|
||||
this.queueSave = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean setRoomBgm(int roomId, int discId) {
|
||||
if (discId < 0 || !this.isRoomUnlocked(roomId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
if (room == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
room.setDiscId(discId);
|
||||
this.queueSave = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean setRoomScene(int roomId, int sceneId) {
|
||||
if (sceneId < 0 || !this.isRoomUnlocked(roomId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var roomData = GameData.getDormRoomDataTable().get(roomId);
|
||||
|
||||
if (sceneId != 0) {
|
||||
if (!GameData.getDormRoomSceneDataTable().containsKey(sceneId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The default scene of the room is always available
|
||||
if (roomData == null || roomData.getSceneRes() != sceneId) {
|
||||
if (this.getPlayer().getInventory().getItemCount(sceneId) <= 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
if (room == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
room.setRoomScene(sceneId);
|
||||
this.queueSave = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean updateInvitationRoles(int roomId, List<Integer> roleIds) {
|
||||
if (!this.isRoomUnlocked(roomId) || roleIds == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var roomData = GameData.getDormRoomDataTable().get(roomId);
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
|
||||
if (roomData == null || room == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate role ids
|
||||
var requested = new IntOpenHashSet();
|
||||
for (int roleId : roleIds) {
|
||||
var roleData = GameData.getDormRoleDataTable().get(roleId);
|
||||
if (roleData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Playable characters need to be owned by the player.
|
||||
if (roleData.getRoleType() == 1 && this.getPlayer().getCharacters().getCharacterById(roleId) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
requested.add(roleId);
|
||||
}
|
||||
|
||||
// Keep existing invitation NPCs, mirroring the client
|
||||
var newRoles = new ArrayList<DormRole>();
|
||||
for (var role : room.getRoleList()) {
|
||||
var roleData = GameData.getDormRoleDataTable().get(role.getRoleId());
|
||||
if (role.isInvitationRole() && roleData != null && roleData.getRoleType() == 2) {
|
||||
newRoles.add(role);
|
||||
}
|
||||
}
|
||||
|
||||
// Add requested roles
|
||||
var existing = new IntOpenHashSet();
|
||||
for (var role : newRoles) {
|
||||
existing.add(role.getRoleId());
|
||||
}
|
||||
|
||||
for (int roleId : requested) {
|
||||
if (existing.contains(roleId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var role = new DormRole(roleId);
|
||||
role.setVisit(true);
|
||||
role.setInvitationRole(false);
|
||||
newRoles.add(role);
|
||||
}
|
||||
|
||||
if (newRoles.size() > roomData.getRoleNum()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
room.setRoleList(newRoles);
|
||||
|
||||
// Remove the requested roles from all other rooms
|
||||
for (var other : this.rooms.values()) {
|
||||
if (other.getDormRoomId() == roomId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
other.getRoleList().removeIf(role -> requested.contains(role.getRoleId()));
|
||||
}
|
||||
this.queueSave = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Interactions
|
||||
|
||||
public boolean hasInteracted(int roleId) {
|
||||
this.resetDailies();
|
||||
return this.dailyInteractionRoleIds.contains(roleId);
|
||||
}
|
||||
|
||||
public int getDailyInteractionCount() {
|
||||
this.resetDailies();
|
||||
return this.dailyInteractionRoleIds.size();
|
||||
}
|
||||
|
||||
public synchronized void addInteractionRole(int roleId) {
|
||||
if (this.dailyInteractionRoleIds.add(roleId)) {
|
||||
this.queueSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isParticipatingInRoom(int roomId, int roleId) {
|
||||
var room = this.rooms.get(roomId);
|
||||
if (room == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var role : room.getRoleList()) {
|
||||
if (role.getRoleId() == roleId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized int interactRole(GameCharacter character, int roleId, PlayerChangeInfo change) {
|
||||
if (character == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Affinity
|
||||
character.addAffinityExp(GameConstants.DORM_ROLE_FAVORABILITY, change);
|
||||
|
||||
// Random interaction reward
|
||||
int dropItemId = emu.nebula.data.resources.DropPkgDef.getRandomDrop(GameConstants.DORM_ROLE_INTERACTION_DROP_ID);
|
||||
if (dropItemId > 0) {
|
||||
this.getPlayer().getInventory().addItem(dropItemId, 1, change);
|
||||
}
|
||||
|
||||
this.addInteractionRole(roleId);
|
||||
this.getPlayer().trigger(QuestCondition.DormRoleInteractionReward, 1);
|
||||
|
||||
return dropItemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interacts with the roles of the given rooms.
|
||||
*
|
||||
* @param interactions the requested role interactions
|
||||
* @return the result of the interactions, or null if no interaction was possible
|
||||
*/
|
||||
public synchronized DormRoleInteractionResult interactRoles(Iterable<RoleInteraction> interactions) {
|
||||
var change = new PlayerChangeInfo();
|
||||
var results = new ArrayList<DormRoleInteractionResult.Interaction>();
|
||||
var processed = new IntOpenHashSet();
|
||||
|
||||
for (var interaction : interactions) {
|
||||
int roomId = interaction.getDormRoomId();
|
||||
int roleId = interaction.getRoleId();
|
||||
|
||||
// Sanity checks
|
||||
if (roleId <= 0 || !processed.add(roleId)) {
|
||||
continue;
|
||||
}
|
||||
if (!this.isRoomUnlocked(roomId) || !this.isParticipatingInRoom(roomId, roleId)) {
|
||||
continue;
|
||||
}
|
||||
if (this.getDailyInteractionCount() >= GameConstants.DORM_ROLE_INTERACTION_MAX_NUM) {
|
||||
break;
|
||||
}
|
||||
if (this.hasInteracted(roleId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var character = this.getPlayer().getCharacters().getCharacterById(roleId);
|
||||
if (character == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int dropItemId = this.interactRole(character, roleId, change);
|
||||
if (dropItemId < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.add(new DormRoleInteractionResult.Interaction(character, dropItemId));
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DormRoleInteractionResult(change, results);
|
||||
}
|
||||
|
||||
// Affinity gifts
|
||||
|
||||
public int getDailyGiftTotal() {
|
||||
return this.dailyAffinityGiftTotal;
|
||||
}
|
||||
|
||||
public int getDailyGiftCount(int roleId) {
|
||||
return this.dailyAffinityGiftCounts.get(roleId);
|
||||
}
|
||||
|
||||
public synchronized void addGift(int roleId, int count) {
|
||||
this.dailyAffinityGiftCounts.put(roleId, this.dailyAffinityGiftCounts.get(roleId) + count);
|
||||
this.dailyAffinityGiftTotal += count;
|
||||
this.queueSave = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends affinity gifts to a character. One gift action per character per day,
|
||||
* with a shared daily item limit.
|
||||
*
|
||||
* @return the changes of the gift, or null if the gifts could not be sent
|
||||
*/
|
||||
public synchronized PlayerChangeInfo sendAffinityGift(GameCharacter character, int roomId, ItemParamMap items) {
|
||||
// Validate room and gifts
|
||||
if (character == null || !this.isRoomUnlocked(roomId) || items == null || items.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int charId = character.getCharId();
|
||||
|
||||
// Validate gift items
|
||||
int giftCount = 0;
|
||||
|
||||
for (var entry : items.int2IntEntrySet()) {
|
||||
if (entry.getIntValue() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
giftCount += entry.getIntValue();
|
||||
|
||||
if (giftCount > GameConstants.DORM_ROLE_AFFINITY_GIFT_MAX_NUM) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// One gift action per character per day, with a shared daily item limit
|
||||
if (this.getDailyGiftCount(charId) > 0) {
|
||||
return null;
|
||||
}
|
||||
if (this.getDailyGiftTotal() + giftCount > GameConstants.DORM_ROLE_AFFINITY_GIFT_MAX_NUM) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove items and add affinity
|
||||
var change = character.sendGift(items);
|
||||
|
||||
if (change == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.addGift(charId, giftCount);
|
||||
this.getPlayer().trigger(QuestCondition.DormSendGift, giftCount);
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
// Blocks
|
||||
|
||||
/**
|
||||
* Converts dorm blocks into furniture coins.
|
||||
*
|
||||
* @return the changes of the conversion, or null if the conversion failed
|
||||
*/
|
||||
public synchronized PlayerChangeInfo convertBlocks(int count) {
|
||||
if (count <= 0 || count > Integer.MAX_VALUE / GameConstants.DORM_BLOCKS_CONVERT_PROP) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var inventory = this.getPlayer().getInventory();
|
||||
|
||||
if (inventory.getItemCount(GameConstants.DORM_JADE_ITEM_ID) < count) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
// Remove jade and add furniture coins
|
||||
inventory.removeItem(GameConstants.DORM_JADE_ITEM_ID, count, change);
|
||||
inventory.addItem(
|
||||
GameConstants.DORM_FURNITURE_COIN_ITEM_ID,
|
||||
count * GameConstants.DORM_BLOCKS_CONVERT_PROP,
|
||||
change
|
||||
);
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
// Rewards
|
||||
|
||||
public IntSet getClaimableRewardIds() {
|
||||
var result = new IntOpenHashSet();
|
||||
var unlocked = this.getUnlockedRoomIds();
|
||||
|
||||
for (var reward : GameData.getDormRewardDataTable()) {
|
||||
if (this.receivedRewardIds.contains(reward.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reward.isUnlocked(unlocked)) {
|
||||
result.add(reward.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isLayoutRewardClaimable(int layoutId) {
|
||||
var data = GameData.getDormLayoutRewardDataTable().get(layoutId);
|
||||
if (data == null || data.getRewardId1() <= 0 || data.getQty1() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= data.getFurnitureCount(); i++) {
|
||||
var layout = GameData.getDormRoomLayoutDataTable().get(layoutId * 100 + i);
|
||||
if (layout == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int required = 0;
|
||||
for (int j = 1; j <= data.getFurnitureCount(); j++) {
|
||||
var other = GameData.getDormRoomLayoutDataTable().get(layoutId * 100 + j);
|
||||
if (other != null && other.getFurnitureId() == layout.getFurnitureId()) {
|
||||
required++;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getFurnitureCount(layout.getFurnitureId()) < required) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized PlayerChangeInfo receiveLayoutRewards(int[] layoutIds) {
|
||||
var change = new PlayerChangeInfo();
|
||||
var rewards = new ItemParamMap();
|
||||
boolean received = false;
|
||||
|
||||
for (int layoutId : layoutIds) {
|
||||
if (this.receivedLayoutRewardIds.contains(layoutId) || !this.isLayoutRewardClaimable(layoutId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var data = GameData.getDormLayoutRewardDataTable().get(layoutId);
|
||||
rewards.add(data.getRewardId1(), data.getQty1());
|
||||
this.receivedLayoutRewardIds.add(layoutId);
|
||||
received = true;
|
||||
}
|
||||
|
||||
if (!received) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.getPlayer().getInventory().addItems(rewards, change);
|
||||
this.getPlayer().trigger(QuestCondition.DormRewardReceive, 1);
|
||||
this.queueSave = true;
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
public synchronized PlayerChangeInfo receiveRewards(int[] rewardIds) {
|
||||
var change = new PlayerChangeInfo();
|
||||
var unlocked = this.getUnlockedRoomIds();
|
||||
boolean received = false;
|
||||
|
||||
for (int rewardId : rewardIds) {
|
||||
if (this.receivedRewardIds.contains(rewardId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var data = GameData.getDormRewardDataTable().get(rewardId);
|
||||
if (data == null || !data.isUnlocked(unlocked)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int itemId = DropPkgDef.getRandomDrop(data.getDropId());
|
||||
if (itemId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.getPlayer().getInventory().addItem(itemId, 1, change);
|
||||
this.receivedRewardIds.add(rewardId);
|
||||
received = true;
|
||||
}
|
||||
|
||||
if (!received) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.getPlayer().trigger(QuestCondition.DormRewardReceive, 1);
|
||||
this.queueSave = true;
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
public int getCollectionValue() {
|
||||
if (this.furnitureCollection == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
|
||||
for (var entry : this.furnitureCollection.int2IntEntrySet()) {
|
||||
if (entry.getIntValue() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var furniture = GameData.getDormFurnitureDataTable().get(entry.getIntKey());
|
||||
if (furniture != null) {
|
||||
total += furniture.getCollectionValue();
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public synchronized AchievementComplete receiveAchievements(int[] achievementIds) {
|
||||
int collectionValue = this.getCollectionValue();
|
||||
var change = new PlayerChangeInfo();
|
||||
var proto = AchievementComplete.newInstance();
|
||||
var rewards = new ItemParamMap();
|
||||
boolean completed = false;
|
||||
|
||||
for (int achievementId : achievementIds) {
|
||||
if (this.completedAchievements.containsKey(achievementId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var data = GameData.getDormAchievementDataTable().get(achievementId);
|
||||
if (data == null || data.getCompleteCond() != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int required = data.getCompleteParams() != null && data.getCompleteParams().length > 0
|
||||
? data.getCompleteParams()[0]
|
||||
: 0;
|
||||
|
||||
if (collectionValue < required) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long completeTime = Nebula.getCurrentServerTime();
|
||||
this.completedAchievements.put(achievementId, completeTime);
|
||||
|
||||
if (data.getTid1() > 0 && data.getQty1() > 0) {
|
||||
rewards.add(data.getTid1(), data.getQty1());
|
||||
}
|
||||
if (data.getTid2() > 0 && data.getQty2() > 0) {
|
||||
rewards.add(data.getTid2(), data.getQty2());
|
||||
}
|
||||
if (data.getTid3() > 0 && data.getQty3() > 0) {
|
||||
rewards.add(data.getTid3(), data.getQty3());
|
||||
}
|
||||
|
||||
var info = AchievementInfo.newInstance()
|
||||
.setAchievementId(achievementId)
|
||||
.setCompleteTime(completeTime);
|
||||
|
||||
proto.addAchievementList(info);
|
||||
completed = true;
|
||||
}
|
||||
|
||||
if (!completed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.getPlayer().getInventory().addItems(rewards, change);
|
||||
proto.setChangeInfo(change.toProto());
|
||||
this.queueSave = true;
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
// Social
|
||||
|
||||
public boolean hasLikedFriend(int uid) {
|
||||
return this.likedFriendUids.contains(uid);
|
||||
}
|
||||
|
||||
public synchronized void addLikedFriend(int uid) {
|
||||
this.likedFriendUids.add(uid);
|
||||
}
|
||||
|
||||
public synchronized void addLike() {
|
||||
this.likeNum++;
|
||||
}
|
||||
|
||||
public synchronized void recordVisit(int visitorUid) {
|
||||
if (this.dailyVisitorUids.add(visitorUid)) {
|
||||
this.visitTotalNum++;
|
||||
this.dayVisitNum = this.dailyVisitorUids.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers for friend dorm data
|
||||
|
||||
public DormManager getFriendDorm(int uid) {
|
||||
var cached = Nebula.getGameContext().getPlayerModule().getPlayer(uid);
|
||||
|
||||
if (cached == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cached.getDormManager() == null) {
|
||||
cached.loadManagerFromDatabase(DormManager.class);
|
||||
}
|
||||
|
||||
return cached.getDormManager();
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public synchronized DormInfoListResp toProto() {
|
||||
var proto = DormInfoListResp.newInstance();
|
||||
|
||||
var unlocked = this.getUnlockedRoomIds();
|
||||
var sortedRooms = new ArrayList<>(unlocked);
|
||||
sortedRooms.sort(Integer::compareTo);
|
||||
|
||||
for (int roomId : sortedRooms) {
|
||||
var room = this.getOrCreateRoom(roomId);
|
||||
if (room != null) {
|
||||
proto.addDormList(room.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
var info = DormInfoData.newInstance()
|
||||
.setDormName(this.dormName == null ? "" : this.dormName)
|
||||
.setLikeNum(this.likeNum)
|
||||
.setDayVisitNum(this.dayVisitNum)
|
||||
.setVisitTotalNum(this.visitTotalNum)
|
||||
.setRestNameTime(this.dormNameRestTime)
|
||||
.setTaskGroup(Public.UI32V.newInstance().setValue(0).setVersion(0));
|
||||
|
||||
var rewardIds = new ArrayList<>(this.getClaimableRewardIds());
|
||||
rewardIds.sort(Integer::compareTo);
|
||||
for (int rewardId : rewardIds) {
|
||||
info.addRewardIds(rewardId);
|
||||
}
|
||||
|
||||
for (var entry : this.completedAchievements.entrySet()) {
|
||||
info.addAchievementList(
|
||||
AchievementInfo.newInstance()
|
||||
.setAchievementId(entry.getKey())
|
||||
.setCompleteTime(entry.getValue())
|
||||
);
|
||||
}
|
||||
|
||||
proto.setDormInfo(info);
|
||||
|
||||
for (int layoutId : this.receivedLayoutRewardIds) {
|
||||
proto.addReceivedRewardIds(layoutId);
|
||||
}
|
||||
|
||||
for (int roleId : this.dailyInteractionRoleIds) {
|
||||
proto.addInteractionRoleIds(roleId);
|
||||
}
|
||||
|
||||
for (var entry : this.dailyAffinityGiftCounts.int2IntEntrySet()) {
|
||||
proto.addAffinityGiftRoleInfos(
|
||||
DormAffinityGiftInfo.newInstance()
|
||||
.setRoleId(entry.getIntKey())
|
||||
.setSendGiftCnt(entry.getIntValue())
|
||||
);
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public DormHot getDormHotProto() {
|
||||
return DormHot.newInstance()
|
||||
.setCollectionValue(this.getCollectionValue());
|
||||
}
|
||||
|
||||
// Database
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
Nebula.getGameDatabase().save(this);
|
||||
this.queueSave = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.PublicDorm.FurniturePresetInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class DormPreset {
|
||||
private int buildId;
|
||||
private int dormType;
|
||||
private String buildName;
|
||||
private long createTime;
|
||||
private List<DormFurniture> furnitureList;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public DormPreset() {
|
||||
|
||||
}
|
||||
|
||||
public DormPreset(int buildId, int dormType, long createTime) {
|
||||
this.buildId = buildId;
|
||||
this.dormType = dormType;
|
||||
this.createTime = createTime;
|
||||
this.buildName = "";
|
||||
this.furnitureList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public FurniturePresetInfo toProto() {
|
||||
var proto = FurniturePresetInfo.newInstance()
|
||||
.setBuildId(this.buildId)
|
||||
.setDormType(this.dormType)
|
||||
.setBuildName(this.buildName == null ? "" : this.buildName)
|
||||
.setCreateTime(this.createTime);
|
||||
|
||||
if (this.furnitureList != null) {
|
||||
for (var furniture : this.furnitureList) {
|
||||
proto.addFurnitureList(furniture.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.PublicDorm.DormRoleInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class DormRole {
|
||||
private int roleId;
|
||||
private boolean isVisit;
|
||||
private boolean isInvitationRole;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public DormRole() {
|
||||
|
||||
}
|
||||
|
||||
public DormRole(int roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public DormRoleInfo toProto() {
|
||||
return DormRoleInfo.newInstance()
|
||||
.setRoleId(this.roleId)
|
||||
.setIsVisit(this.isVisit)
|
||||
.setIsInvitationRole(this.isInvitationRole);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.game.character.GameCharacter;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* The result of interacting with roles in a dorm room.
|
||||
*/
|
||||
@Getter
|
||||
public class DormRoleInteractionResult {
|
||||
// The changes of the interactions
|
||||
private final PlayerChangeInfo change;
|
||||
|
||||
// The interactions that were performed
|
||||
private final List<Interaction> interactions;
|
||||
|
||||
public DormRoleInteractionResult(PlayerChangeInfo change, List<Interaction> interactions) {
|
||||
this.change = change;
|
||||
this.interactions = interactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single role interaction.
|
||||
*/
|
||||
public record Interaction(GameCharacter character, int itemId) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package emu.nebula.game.dorm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.PublicDorm.DormRoomInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class DormRoomState {
|
||||
private int dormRoomId;
|
||||
private List<DormFurniture> furnitureList;
|
||||
private List<DormRole> roleList;
|
||||
private int discId;
|
||||
private String roomName;
|
||||
private int roomScene;
|
||||
private long restNameTime;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public DormRoomState() {
|
||||
|
||||
}
|
||||
|
||||
public DormRoomState(int dormRoomId) {
|
||||
this.dormRoomId = dormRoomId;
|
||||
this.furnitureList = new ArrayList<>();
|
||||
this.roleList = new ArrayList<>();
|
||||
this.roomName = "";
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public DormRoomInfo toProto() {
|
||||
var proto = DormRoomInfo.newInstance()
|
||||
.setDormRoomId(this.getDormRoomId())
|
||||
.setDiscId(this.getDiscId())
|
||||
.setRoomName(this.getRoomName() == null ? "" : this.getRoomName())
|
||||
.setRoomScene(this.getRoomScene())
|
||||
.setRestNameTime(this.getRestNameTime());
|
||||
|
||||
if (this.getFurnitureList() != null) {
|
||||
for (var furniture : this.getFurnitureList()) {
|
||||
proto.addFurnitureList(furniture.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getRoleList() != null) {
|
||||
for (var role : this.getRoleList()) {
|
||||
proto.addRoleList(role.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -459,6 +459,43 @@ public class Inventory extends PlayerManager implements GameDatabaseObject {
|
||||
change.add(proto);
|
||||
}
|
||||
}
|
||||
case DormFurniture -> {
|
||||
// Do not allow removing dorm furniture
|
||||
if (amount <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Dorm furniture sets/kits contain their furniture in UseArgs.
|
||||
// Unpack them instead of adding the set itself to the bag.
|
||||
if (data.getUseParams() != null && !data.getUseParams().isEmpty()) {
|
||||
// Add items from the set
|
||||
for (var entry : data.getUseParams()) {
|
||||
this.addItem(entry.getIntKey(), entry.getIntValue() * amount, change);
|
||||
}
|
||||
|
||||
// End early
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.getItemSubType() == ItemSubType.DormRoom) {
|
||||
// Unlock dorm rooms when the room item is acquired.
|
||||
this.getPlayer().getDormManager().unlockRoom(id, change);
|
||||
} else if (data.getItemSubType() == ItemSubType.DormFurniture) {
|
||||
// Add furniture to the dorm furniture collection
|
||||
var dormManager = this.getPlayer().getDormManager();
|
||||
boolean isFirst = dormManager.getFurnitureCount(id) <= 0;
|
||||
|
||||
dormManager.addFurniture(id, amount);
|
||||
|
||||
// Add to change info (to notify the game client)
|
||||
var proto = DormItem.newInstance()
|
||||
.setTid(id)
|
||||
.setQty(amount)
|
||||
.setIsFirst(isFirst);
|
||||
|
||||
change.add(proto);
|
||||
}
|
||||
}
|
||||
case Disc -> {
|
||||
// Cannot remove discs
|
||||
if (amount <= 0) break;
|
||||
|
||||
@@ -17,6 +17,7 @@ import emu.nebula.game.agent.AgentManager;
|
||||
import emu.nebula.game.battlepass.BattlePassManager;
|
||||
import emu.nebula.game.character.CharacterStorage;
|
||||
import emu.nebula.game.dating.DatingManager;
|
||||
import emu.nebula.game.dorm.DormManager;
|
||||
import emu.nebula.game.formation.FormationManager;
|
||||
import emu.nebula.game.friends.FriendList;
|
||||
import emu.nebula.game.gacha.GachaManager;
|
||||
@@ -113,6 +114,7 @@ public class Player implements GameDatabaseObject {
|
||||
private transient AgentManager agentManager;
|
||||
private transient TraceHuntManager traceHuntManager;
|
||||
private transient ActivityManager activityManager;
|
||||
private transient DormManager dormManager;
|
||||
|
||||
// Extra
|
||||
private transient Stack<NetMsgPacket> nextPackages;
|
||||
@@ -733,6 +735,9 @@ public class Player implements GameDatabaseObject {
|
||||
// Reset daily trace hunt items
|
||||
this.getTraceHuntManager().resetDailyQuota();
|
||||
|
||||
// Reset dorm dailies
|
||||
this.getDormManager().resetDailies();
|
||||
|
||||
// Check to reset weeklies
|
||||
if (resetWeekly) {
|
||||
// Add weekly boss entry item
|
||||
@@ -780,7 +785,7 @@ public class Player implements GameDatabaseObject {
|
||||
|
||||
// Login
|
||||
|
||||
private <T extends PlayerManager> T loadManagerFromDatabase(Class<T> cls) {
|
||||
public <T extends PlayerManager> T loadManagerFromDatabase(Class<T> cls) {
|
||||
var manager = Nebula.getGameDatabase().getObjectByField(cls, "_id", this.getUid());
|
||||
|
||||
if (manager != null) {
|
||||
@@ -824,6 +829,7 @@ public class Player implements GameDatabaseObject {
|
||||
this.agentManager = this.loadManagerFromDatabase(AgentManager.class);
|
||||
this.traceHuntManager = this.loadManagerFromDatabase(TraceHuntManager.class);
|
||||
this.activityManager = this.loadManagerFromDatabase(ActivityManager.class);
|
||||
this.dormManager = this.loadManagerFromDatabase(DormManager.class);
|
||||
|
||||
// Database fixes
|
||||
if (this.showChars == null) {
|
||||
@@ -1105,6 +1111,11 @@ public class Player implements GameDatabaseObject {
|
||||
if (this.getAchievementManager().isQueueSave()) {
|
||||
this.getAchievementManager().save();
|
||||
}
|
||||
|
||||
// Check if we need save dorm data
|
||||
if (this.getDormManager().isQueueSave()) {
|
||||
this.getDormManager().save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1146,7 +1157,8 @@ public class Player implements GameDatabaseObject {
|
||||
.setDailyShopRewardStatus(this.getQuestManager().hasDailyShopReward())
|
||||
.setDailyMallRewardStatus(this.getQuestManager().hasDailyMallReward())
|
||||
.setMusicInfo(this.getMusic())
|
||||
.setAchievements(new byte[64]);
|
||||
.setAchievements(new byte[64])
|
||||
.setDorm(this.getDormManager().getDormHotProto());
|
||||
|
||||
var acc = proto.getMutableAcc()
|
||||
.setNickName(this.getName())
|
||||
@@ -1262,6 +1274,7 @@ public class Player implements GameDatabaseObject {
|
||||
state.getMutableScoreBoss();
|
||||
state.getMutableCharAffinityRewards();
|
||||
state.getMutableTraceHunt().setBossRewardCanReceive(this.getTraceHuntManager().isHuntComplete());
|
||||
state.setDormStateFlag(this.getDormManager().getState());
|
||||
|
||||
// Star tower potential book state
|
||||
var book = state.getMutableStarTowerBook();
|
||||
|
||||
@@ -16,6 +16,7 @@ import emu.nebula.game.agent.AgentManager;
|
||||
import emu.nebula.game.battlepass.BattlePass;
|
||||
import emu.nebula.game.character.GameCharacter;
|
||||
import emu.nebula.game.character.GameDisc;
|
||||
import emu.nebula.game.dorm.DormManager;
|
||||
import emu.nebula.game.formation.FormationManager;
|
||||
import emu.nebula.game.friends.Friendship;
|
||||
import emu.nebula.game.gacha.GachaManager;
|
||||
@@ -187,6 +188,7 @@ public class PlayerModule extends GameContextModule {
|
||||
datastore.getCollection(TraceHuntManager.class).deleteOne(idFilter);
|
||||
datastore.getCollection(AchievementManager.class).deleteOne(idFilter);
|
||||
datastore.getCollection(ActivityManager.class).deleteOne(idFilter);
|
||||
datastore.getCollection(DormManager.class).deleteOne(idFilter);
|
||||
|
||||
datastore.getCollection(BattlePass.class).deleteOne(idFilter);
|
||||
datastore.getCollection(ScoreBossRankEntry.class).deleteOne(idFilter);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormAchievementRewardReceive.DormAchievementRewardReceiveReq;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_achievement_reward_receive_req)
|
||||
public class HandlerDormAchievementRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormAchievementRewardReceiveReq.parseFrom(message);
|
||||
|
||||
// Receive achievements
|
||||
var rsp = session.getPlayer().getDormManager().receiveAchievements(req.getAchievementIds().toArray());
|
||||
|
||||
if (rsp == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_achievement_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_achievement_reward_receive_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormAffinityGiftSend.DormAffinityGiftSendReq;
|
||||
import emu.nebula.proto.DormAffinityGiftSend.DormAffinityGiftSendResp;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_affinity_gift_send_req)
|
||||
public class HandlerDormAffinityGiftSendReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormAffinityGiftSendReq.parseFrom(message);
|
||||
|
||||
var player = session.getPlayer();
|
||||
var manager = player.getDormManager();
|
||||
|
||||
// Get character
|
||||
var character = player.getCharacters().getCharacterById(req.getCharId());
|
||||
if (character == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_affinity_gift_send_failed_ack);
|
||||
}
|
||||
|
||||
// Parse gift items
|
||||
var items = ItemParamMap.fromTemplates(req.getItems());
|
||||
|
||||
// Send gifts
|
||||
var change = manager.sendAffinityGift(character, req.getDormRoomId(), items);
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_affinity_gift_send_failed_ack);
|
||||
}
|
||||
|
||||
// Build response
|
||||
var rsp = DormAffinityGiftSendResp.newInstance()
|
||||
.setInfo(character.getAffinityProto())
|
||||
.setChange(change.toProto())
|
||||
.setSendGiftCnt(manager.getDailyGiftCount(character.getCharId()));
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_affinity_gift_send_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_blocks_convert_req)
|
||||
public class HandlerDormBlocksConvertReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Convert blocks
|
||||
var change = session.getPlayer().getDormManager().convertBlocks(req.getValue());
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_blocks_convert_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_blocks_convert_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFriendLike.DormFriendLikeReq;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_friend_like_req)
|
||||
public class HandlerDormFriendLikeReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormFriendLikeReq.parseFrom(message);
|
||||
|
||||
long friendId = req.getFriendId();
|
||||
|
||||
if (friendId <= 0 || friendId > Integer.MAX_VALUE) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_like_failed_ack);
|
||||
}
|
||||
|
||||
int uid = (int) friendId;
|
||||
var player = session.getPlayer();
|
||||
var manager = player.getDormManager();
|
||||
|
||||
// Friends only
|
||||
if (!player.getFriendList().getFriends().containsKey(uid)) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_like_failed_ack);
|
||||
}
|
||||
|
||||
// Daily limit and duplicate check
|
||||
if (manager.hasLikedFriend(uid) || manager.getLikedFriendUids().size() >= GameConstants.DORM_LIKE_LIMIT) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_like_failed_ack);
|
||||
}
|
||||
|
||||
manager.addLikedFriend(uid);
|
||||
|
||||
// Increment the friend's like counter
|
||||
var dorm = session.getPlayer().getDormManager().getFriendDorm(uid);
|
||||
|
||||
if (dorm != null) {
|
||||
dorm.addLike();
|
||||
dorm.save();
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_like_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFriendList.DormFriendListResp;
|
||||
import emu.nebula.proto.PublicDorm.DormFriendDetail;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_friend_list_req)
|
||||
public class HandlerDormFriendListReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
var player = session.getPlayer();
|
||||
var manager = player.getDormManager();
|
||||
|
||||
var rsp = DormFriendListResp.newInstance();
|
||||
|
||||
for (var friendship : player.getFriendList().getFriends().values()) {
|
||||
int uid = friendship.getFriendUid();
|
||||
|
||||
var dorm = session.getPlayer().getDormManager().getFriendDorm(uid);
|
||||
|
||||
var detail = DormFriendDetail.newInstance()
|
||||
.setUid(uid)
|
||||
.setLikeNum(dorm == null ? 0 : dorm.getLikeNum())
|
||||
.setCollectionValue(dorm == null ? 0 : dorm.getCollectionValue())
|
||||
.setIsLike(manager.hasLikedFriend(uid));
|
||||
|
||||
if (dorm != null && dorm.getDormName() != null) {
|
||||
detail.setDormName(dorm.getDormName());
|
||||
}
|
||||
|
||||
rsp.addFriends(detail);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_list_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFriendVisit.DormFriendVisitReq;
|
||||
import emu.nebula.proto.DormFriendVisit.DormFriendVisitResp;
|
||||
import emu.nebula.proto.PublicDorm.DormFriendInfo;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_friend_visit_req)
|
||||
public class HandlerDormFriendVisitReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormFriendVisitReq.parseFrom(message);
|
||||
|
||||
// Validate friend
|
||||
long friendId = req.getFriendId();
|
||||
|
||||
if (friendId <= 0 || friendId > Integer.MAX_VALUE) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_visit_failed_ack);
|
||||
}
|
||||
|
||||
int uid = (int) friendId;
|
||||
|
||||
if (!session.getPlayer().getFriendList().getFriends().containsKey(uid)) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_visit_failed_ack);
|
||||
}
|
||||
|
||||
// Load friend dorm data
|
||||
var dorm = session.getPlayer().getDormManager().getFriendDorm(uid);
|
||||
|
||||
if (dorm == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_visit_failed_ack);
|
||||
}
|
||||
|
||||
// Build response
|
||||
var rsp = DormFriendVisitResp.newInstance();
|
||||
|
||||
var unlockedRoomIds = dorm.getUnlockedRoomIds();
|
||||
var sortedRoomIds = new java.util.ArrayList<>(unlockedRoomIds);
|
||||
sortedRoomIds.sort(Integer::compareTo);
|
||||
|
||||
for (int roomId : sortedRoomIds) {
|
||||
var room = dorm.getOrCreateRoom(roomId);
|
||||
|
||||
if (room != null) {
|
||||
rsp.addDormList(room.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
var dormInfo = DormFriendInfo.newInstance();
|
||||
|
||||
if (dorm.getDormName() != null) {
|
||||
dormInfo.setDormName(dorm.getDormName());
|
||||
}
|
||||
|
||||
rsp.setDormInfo(dormInfo);
|
||||
|
||||
// Record the visit on the friend's dorm
|
||||
dorm.recordVisit(session.getPlayer().getUid());
|
||||
dorm.save();
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_friend_visit_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFurnitureList.DormBagListResp;
|
||||
import emu.nebula.proto.Public.ItemTpl;
|
||||
import emu.nebula.proto.PublicDorm.DormBagInfo;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_bag_list_req)
|
||||
public class HandlerDormFurnitureListReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Get dorm manager
|
||||
var dorm = session.getPlayer().getDormManager();
|
||||
|
||||
// Build response
|
||||
var rsp = DormBagListResp.newInstance();
|
||||
|
||||
// Encode dorm furniture inventory
|
||||
for (var entry : dorm.getFurnitureCollection().int2IntEntrySet()) {
|
||||
if (entry.getIntValue() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var item = ItemTpl.newInstance()
|
||||
.setTid(entry.getIntKey())
|
||||
.setQty(entry.getIntValue());
|
||||
|
||||
var info = DormBagInfo.newInstance()
|
||||
.setItemTplInfo(item);
|
||||
|
||||
rsp.addDormBagList(info);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_bag_list_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_furniture_preset_delete_req)
|
||||
public class HandlerDormFurniturePresetDeleteReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// The client does not send a request body for this packet in the current client version.
|
||||
// If a body is present, treat field 1 as the preset/build id.
|
||||
int buildId = 0;
|
||||
|
||||
if (message != null && message.length > 0) {
|
||||
try {
|
||||
buildId = UI32.parseFrom(message).getValue();
|
||||
} catch (Exception ignored) {
|
||||
buildId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (buildId > 0) {
|
||||
session.getPlayer().getDormManager().deletePreset(buildId);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_furniture_preset_delete_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.game.dorm.DormPreset;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFurniturePreset.DormFurniturePresetListResp;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_furniture_preset_list_req)
|
||||
public class HandlerDormFurniturePresetListReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Get player dorm
|
||||
var dorm = session.getPlayer().getDormManager();
|
||||
|
||||
// Build response
|
||||
var rsp = DormFurniturePresetListResp.newInstance()
|
||||
.setNum(GameConstants.DORM_DEFAULT_PRESET_NUM);
|
||||
|
||||
// Get preset list
|
||||
var list = new ArrayList<>(dorm.getPresets().values());
|
||||
|
||||
// Sort preset list
|
||||
list.sort(Comparator.comparingInt(DormPreset::getBuildId));
|
||||
|
||||
// Encode presets to proto
|
||||
for (var preset : list) {
|
||||
rsp.addPresetList(preset.toProto());
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_furniture_preset_list_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import emu.nebula.game.dorm.DormFurniture;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormFurnitureSave.DormFurnitureSaveReq;
|
||||
import emu.nebula.proto.Public.I64;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_furniture_save_req)
|
||||
public class HandlerDormFurnitureSaveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormFurnitureSaveReq.parseFrom(message);
|
||||
|
||||
// Build furniture list
|
||||
var furnitureList = new ArrayList<DormFurniture>();
|
||||
|
||||
for (var info : req.getFurniturePosInfoList()) {
|
||||
furnitureList.add(new DormFurniture(info));
|
||||
}
|
||||
|
||||
// Save room or preset
|
||||
var createTime = session.getPlayer().getDormManager().saveFurnitureLayout(
|
||||
req.getDormRoomId(),
|
||||
furnitureList,
|
||||
req.getBuildId()
|
||||
);
|
||||
|
||||
if (createTime == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_furniture_save_failed_ack);
|
||||
}
|
||||
|
||||
// The client reads the preset creation time from Value
|
||||
var rsp = I64.newInstance()
|
||||
.setValue(createTime);
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_furniture_save_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormGetChangeData.DormChangeDataResp;
|
||||
import emu.nebula.proto.PublicDorm.DormChangeDataInfo;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_get_change_data_req)
|
||||
public class HandlerDormGetChangeDataReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Get player dorm
|
||||
var dorm = session.getPlayer().getDormManager();
|
||||
|
||||
// Build response
|
||||
var info = DormChangeDataInfo.newInstance()
|
||||
.setDormName(dorm.getDormName())
|
||||
.setLikeNum(dorm.getLikeNum())
|
||||
.setDayVisitNum(dorm.getDayVisitNum())
|
||||
.setVisitTotalNum(dorm.getVisitTotalNum());
|
||||
|
||||
var rsp = DormChangeDataResp.newInstance()
|
||||
.setDormChangeData(info);
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_get_change_data_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_info_list_req)
|
||||
public class HandlerDormInfoListReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Build response
|
||||
var rsp = session.getPlayer().getDormManager().toProto();
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_info_list_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.StringV;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_info_update_name_req)
|
||||
public class HandlerDormInfoUpdateNameReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = StringV.parseFrom(message);
|
||||
|
||||
// Version = 0 means the dorm name, otherwise the room id
|
||||
if (!session.getPlayer().getDormManager().renameRoom(req.getVersion(), req.getValue())) {
|
||||
return session.encodeMsg(NetMsgId.dorm_info_update_name_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_info_update_name_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormInvitationRole.DormInvitationRoleReq;
|
||||
import emu.nebula.proto.Public;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_invitation_role_req)
|
||||
public class HandlerDormInvitationRoleReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormInvitationRoleReq.parseFrom(message);
|
||||
|
||||
// Get role ids
|
||||
var roleIds = new ArrayList<Integer>();
|
||||
for (var info : req.getInvitationRoleList()) {
|
||||
roleIds.add(info.getRoleId());
|
||||
}
|
||||
|
||||
// Update invitation roles
|
||||
if (!session.getPlayer().getDormManager().updateInvitationRoles(req.getDormRoomId(), roleIds)) {
|
||||
return session.encodeMsg(NetMsgId.dorm_invitation_role_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_invitation_role_succeed_ack, Public.Nil.newInstance());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormLayoutRewardReceive.DormLayoutRewardReceiveReq;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_layout_reward_receive_req)
|
||||
public class HandlerDormLayoutRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormLayoutRewardReceiveReq.parseFrom(message);
|
||||
|
||||
// Receive layout rewards
|
||||
var change = session.getPlayer().getDormManager().receiveLayoutRewards(req.getLayoutIds().toArray());
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_layout_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_layout_reward_receive_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_learn_req)
|
||||
public class HandlerDormLearnReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Dorm quests are not implemented yet, so acknowledge the request without changing state.
|
||||
return session.encodeMsg(NetMsgId.dorm_learn_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormRewardReceive.DormRewardReceiveReq;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_reward_receive_req)
|
||||
public class HandlerDormRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormRewardReceiveReq.parseFrom(message);
|
||||
|
||||
// Receive rewards
|
||||
var change = session.getPlayer().getDormManager().receiveRewards(req.getRewardIds().toArray());
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_reward_receive_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormRoleInteraction.DormRoleInteractionReq;
|
||||
import emu.nebula.proto.DormRoleInteraction.DormRoleInteractionResp;
|
||||
import emu.nebula.proto.Public;
|
||||
import emu.nebula.proto.PublicDorm.AffinityData;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_role_interaction_req)
|
||||
public class HandlerDormRoleInteractionReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormRoleInteractionReq.parseFrom(message);
|
||||
|
||||
// Interact with roles
|
||||
var result = session.getPlayer().getDormManager().interactRoles(req.getRoleInteractions());
|
||||
|
||||
if (result == null) {
|
||||
return session.encodeMsg(NetMsgId.dorm_role_interaction_failed_ack);
|
||||
}
|
||||
|
||||
// Build response
|
||||
var rsp = DormRoleInteractionResp.newInstance()
|
||||
.setChange(result.getChange().toProto());
|
||||
|
||||
for (var interaction : result.getInteractions()) {
|
||||
int itemId = interaction.itemId();
|
||||
|
||||
var itemInfo = Public.ItemTpl.newInstance()
|
||||
.setTid(Math.max(itemId, 0))
|
||||
.setQty(itemId > 0 ? 1 : 0);
|
||||
|
||||
rsp.addInfoList(
|
||||
AffinityData.newInstance()
|
||||
.setAffinityInfo(interaction.character().getAffinityProto())
|
||||
.setItemInfo(itemInfo)
|
||||
);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_role_interaction_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.DormRoomBgm.DormRoomBGMReq;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_room_bgm_req)
|
||||
public class HandlerDormRoomBgmReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = DormRoomBGMReq.parseFrom(message);
|
||||
|
||||
var manager = session.getPlayer().getDormManager();
|
||||
|
||||
// Validate the whole request before applying it
|
||||
for (var bgm : req.getBGMList()) {
|
||||
if (!manager.isRoomUnlocked(bgm.getDormRoomId()) || bgm.getDiscId() < 0) {
|
||||
return session.encodeMsg(NetMsgId.dorm_room_bgm_failed_ack);
|
||||
}
|
||||
}
|
||||
|
||||
for (var bgm : req.getBGMList()) {
|
||||
manager.setRoomBgm(bgm.getDormRoomId(), bgm.getDiscId());
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_room_bgm_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32V;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_set_room_scene_req)
|
||||
public class HandlerDormSetRoomSceneReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32V.parseFrom(message);
|
||||
|
||||
// Version = room id, Value = scene item id (0 clears the scene)
|
||||
if (!session.getPlayer().getDormManager().setRoomScene(req.getVersion(), req.getValue())) {
|
||||
return session.encodeMsg(NetMsgId.dorm_set_room_scene_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_set_room_scene_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.StringV;
|
||||
|
||||
@HandlerId(NetMsgId.dorm_update_preset_name_req)
|
||||
public class HandlerDormUpdatePresetNameReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = StringV.parseFrom(message);
|
||||
|
||||
// Version = preset/build id, Value = new name
|
||||
if (!session.getPlayer().getDormManager().renamePreset(req.getVersion(), req.getValue())) {
|
||||
return session.encodeMsg(NetMsgId.dorm_update_preset_name_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.dorm_update_preset_name_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"global": 141,
|
||||
"kr": 147,
|
||||
"jp": 143,
|
||||
"tw": 149,
|
||||
"cn": 140
|
||||
"global": 143,
|
||||
"kr": 150,
|
||||
"jp": 145,
|
||||
"tw": 151,
|
||||
"cn": 142
|
||||
}
|
||||
Reference in new issue
Block a user