From 9d62c1783c7931bdd83f636d0aaebc797cd3702b Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sun, 25 May 2025 17:54:41 +0200 Subject: [PATCH 01/27] 1.1.6-dev --- Campofinale/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 502d443..68b546b 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -48,7 +48,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.5"; + public static string ServerVersion = "1.1.6-dev"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true; From 8563aeb7399b1cfdf91e06819a5ccee61c560640 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sun, 25 May 2025 17:56:33 +0200 Subject: [PATCH 02/27] removing useless variables --- Campofinale/Server.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 68b546b..3ac301b 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -53,15 +53,10 @@ namespace Campofinale public static bool showLogs = true; public static bool showWarningLogs = true; public static bool showBodyLogs = false; - public static Dispatch dispatch; - public static ResourceManager resourceManager; - public static ConfigFile config; + public static Dispatch? dispatch; + public static ConfigFile? config; public static List csMessageToHide = new() { CsMsgId.CsMoveObjectMove, CsMsgId.CsBattleOp,CsMsgId.CsPing }; public static List scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing }; - public static ResourceManager GetResources() - { - return resourceManager; - } public void Start(ConfigFile config) { { From 4e280f18b5d4eeb9ee7fd5c128d84e4e3a934dda Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Mon, 26 May 2025 22:23:03 +0200 Subject: [PATCH 03/27] mission system now save, characters at start only 1 if quests are enabled --- Campofinale/ConfigFile.cs | 15 +- Campofinale/Database/Database.cs | 27 +++ .../Game/Entities/EntityInteractive.cs | 2 +- Campofinale/Game/Entities/EntityMonster.cs | 2 +- Campofinale/Game/MissionSys/MissionSystem.cs | 26 ++- Campofinale/Game/SceneManager.cs | 42 ++-- Campofinale/NotifyManager.cs | 2 +- Campofinale/Packets/Cs/HandleCsBitsetAdd.cs | 2 +- Campofinale/Packets/Cs/HandleCsLogin.cs | 183 ++++-------------- .../Cs/HandleCsSceneInteractSpInteractive.cs | 1 + .../HandleCsSceneInteractiveEventTrigger.cs | 17 +- .../Cs/HandleCsSceneSetLastSafeZone.cs | 11 +- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 103 ++-------- .../Packets/Cs/HandleCsTrackMission.cs | 3 +- .../Packets/Sc/PacketScEnterSceneNotify.cs | 2 +- .../Packets/Sc/PacketScSelfSceneInfo.cs | 1 + .../Packets/Sc/PacketScSyncAllMission.cs | 16 ++ Campofinale/Player.cs | 105 +++++++--- Campofinale/Program.cs | 5 +- Campofinale/Resource/ResourceManager.cs | 9 + .../Resource/Table/LevelScriptEvent.cs | 3 +- Campofinale/Server.cs | 1 - 22 files changed, 268 insertions(+), 310 deletions(-) create mode 100644 Campofinale/Packets/Sc/PacketScSyncAllMission.cs diff --git a/Campofinale/ConfigFile.cs b/Campofinale/ConfigFile.cs index 2f7d1b9..f1eef43 100644 --- a/Campofinale/ConfigFile.cs +++ b/Campofinale/ConfigFile.cs @@ -12,19 +12,28 @@ { public int defaultSceneNumId = 87; public int maxPlayers = 20; - public CharactersOptions defaultCharacters = new(); + /// + /// Experimental, Mission System is still a work in progress. + /// + public bool missionsEnabled = false; + public bool giveAllItems = false; + /// + /// Not yet implemented + /// + public bool useEncryption = false; + //public CharactersOptions defaultCharacters = new(); public ServerOptions() { } - public class CharactersOptions + /*public class CharactersOptions { public int defaultLevel = 1; public bool giveAllCharacters = true; public List characters = new List(); //used if giveAllCharacters is false public CharactersOptions() { } - } + }*/ /* public struct WelcomeMail { }*/ diff --git a/Campofinale/Database/Database.cs b/Campofinale/Database/Database.cs index 1f2af8c..5b591a6 100644 --- a/Campofinale/Database/Database.cs +++ b/Campofinale/Database/Database.cs @@ -2,6 +2,7 @@ using Campofinale.Game.Character; using Campofinale.Game.Gacha; using Campofinale.Game.Inventory; +using Campofinale.Game.MissionSys; using Campofinale.Game.Spaceship; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; @@ -38,6 +39,14 @@ namespace Campofinale.Database public Gender gender = Gender.GenFemale; public Dictionary bag = new(); } + public class MissionData + { + [BsonId] + public ulong roleId; + public List missions = new(); + public List quests = new(); + public string curMission = "e0m0"; + } public class Account { public string id; @@ -64,12 +73,17 @@ namespace Campofinale.Database public Database(string connectionString, string dbName) { var client = new MongoClient(connectionString); + _database = client.GetDatabase(dbName); } public List LoadMails(ulong roleId) { return _database.GetCollection("mails").Find(c => c.owner == roleId).ToList(); } + public MissionData LoadMissionData(ulong roleId) + { + return _database.GetCollection("missionsData").Find(c => c.roleId == roleId).FirstOrDefault(); + } public List LoadCharacters(ulong roleId) { return _database.GetCollection("avatars").Find(c=>c.owner== roleId).ToList(); @@ -176,6 +190,19 @@ namespace Campofinale.Database new ReplaceOptions { IsUpsert = true } ); } + public void UpsertMissionData(MissionData data) + { + var collection = _database.GetCollection("missionsData"); + + var filter = + Builders.Filter.Eq(p => p.roleId, data.roleId); + + collection.ReplaceOne( + filter, + data, + new ReplaceOptions { IsUpsert = true } + ); + } public void UpsertAccount(Account player) { var collection = _database.GetCollection("accounts"); diff --git a/Campofinale/Game/Entities/EntityInteractive.cs b/Campofinale/Game/Entities/EntityInteractive.cs index f57fafe..c543430 100644 --- a/Campofinale/Game/Entities/EntityInteractive.cs +++ b/Campofinale/Game/Entities/EntityInteractive.cs @@ -42,7 +42,7 @@ namespace Campofinale.Game.Entities { CommonInfo = new() { - Hp = 100, + Hp = 1, Id = guid, Templateid = templateId, diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index 1f79384..d9b6363 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -80,7 +80,7 @@ namespace Campofinale.Game.Entities SceneNumId = sceneNumId, Position = Position.ToProto(), Rotation = Rotation.ToProto(), - + Type =(int) ObjectTypeIndex.Enemy, }, diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs index 04ea850..898447e 100644 --- a/Campofinale/Game/MissionSys/MissionSystem.cs +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -19,6 +19,13 @@ namespace Campofinale.Game.MissionSys } public ScSyncAllMission ToProto() { + if (!Server.config.serverOptions.missionsEnabled) + { + string json1 = File.ReadAllText("44_ScSyncAllMission.json"); + ScSyncAllMission m = Newtonsoft.Json.JsonConvert.DeserializeObject(json1); + m.TrackMissionId = ""; + return m; + } ScSyncAllMission sync = new ScSyncAllMission(); sync.TrackMissionId = curMission; missions.ForEach(m => @@ -71,18 +78,23 @@ namespace Campofinale.Game.MissionSys } public void Save() { - + DatabaseManager.db.UpsertMissionData(new MissionData() + { + roleId=owner.roleId, + curMission=curMission, + missions=missions, + quests=quests, + }); } public void Load() { - - if (ResourceManager.missionDataTable.Count < 1) + MissionData data= DatabaseManager.db.LoadMissionData(owner.roleId); + if (data != null) { - //Disabling if no missions - return; + curMission = data.curMission; + missions = data.missions; + quests = data.quests; } - //TODO Saving and first initialization - AddMission("e0m0",MissionState.Processing); } public void AddMission(string id,MissionState state = MissionState.Available, bool notify=false) { diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 220ac67..3e3ad7c 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -215,7 +215,6 @@ namespace Campofinale.Game { return scenes.Find(s=>s.sceneNumId == sceneNumId).guid; } - //TODO Save and get public void Load() { foreach (var level in ResourceManager.levelDatas) @@ -335,19 +334,20 @@ namespace Campofinale.Game lv_scene.levelData.enemies.ForEach(en => { if(GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87) return; - if (en.defaultHide) return; + EntityMonster entity = new(en.entityDataIdKey,en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { type=en.entityType, belongLevelScriptId=en.belongLevelScriptId, - levelLogicId = en.levelLogicId + levelLogicId = en.levelLogicId, + }; entities.Add(entity); }); lv_scene.levelData.npcs.ForEach(en => { - if (en.defaultHide) return; - if (en.npcGroupId.Contains("chr")) return; + + if (en.npcGroupId.Contains("chr") && sceneNumId== 99) return; EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { belongLevelScriptId = en.belongLevelScriptId, @@ -359,8 +359,19 @@ namespace Campofinale.Game }); GetEntityExcludingChar().ForEach(e => { - // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e})); + if(e is EntityInteractive) + { + // e.spawned = true; + // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); + } + + }); + GetEntityExcludingChar().FindAll(e=> e is not EntityInteractive).ForEach(e => + { + + // e.spawned = true; + // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); }); UpdateShowEntities(); @@ -370,10 +381,16 @@ namespace Campofinale.Game { en.spawned = true; List toSpawn = new List(); - if(en.belongLevelScriptId != 0) + toSpawn.Add(en); + foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e.spawned == false)) + { + e.spawned = true; + toSpawn.Add(e); + } + /*if(en.belongLevelScriptId != 0) if (spawnedCheck) { - foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e.spawned == false)) + foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e.spawned == false && e.Position.Distance(GetOwner().position) < 100)) { e.spawned = true; toSpawn.Add(e); @@ -387,8 +404,8 @@ namespace Campofinale.Game toSpawn.Add(e); } - } - toSpawn.Add(en); + }*/ + toSpawn.ForEach(e => { GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e})); @@ -397,9 +414,12 @@ namespace Campofinale.Game } public void UpdateShowEntities() { + foreach(Entity en in GetEntityExcludingChar()) { - if (en.Position.Distance(GetOwner().position) < 100) + float minDis = en is EntityInteractive ? 180 : 50; + //todo new system + if (en.Position.DistanceXZ(GetOwner().position) < minDis) { if (!en.spawned) { diff --git a/Campofinale/NotifyManager.cs b/Campofinale/NotifyManager.cs index c508d2d..ea93f05 100644 --- a/Campofinale/NotifyManager.cs +++ b/Campofinale/NotifyManager.cs @@ -55,7 +55,7 @@ } else { - if (!Server.hideLog.Contains(cmdId) && Server.config.logOptions.packets) + if (!Server.csMessageToHide.Contains(cmdId) && Server.config.logOptions.packets) Logger.PrintWarn($"Can't find handler for {(Enum.GetName(typeof(CsMsgId), cmdId)).ToString().Pastel(Color.FromArgb(165, 229, 250))} ({(cmdId).ToString().Pastel(Color.FromArgb(165, 229, 250))})"); } } diff --git a/Campofinale/Packets/Cs/HandleCsBitsetAdd.cs b/Campofinale/Packets/Cs/HandleCsBitsetAdd.cs index 44f108d..c044771 100644 --- a/Campofinale/Packets/Cs/HandleCsBitsetAdd.cs +++ b/Campofinale/Packets/Cs/HandleCsBitsetAdd.cs @@ -16,7 +16,7 @@ namespace Campofinale.Packets.Cs { session.bitsetManager.AddValue((BitsetType)req.Type, (int)item); } - session.Send(new PacketScBitsetAdd(session,req.Type,req.Value.ToList())); + session.Send(new PacketScBitsetAdd(session,req.Type,req.Value.ToList()),packet.csHead.UpSeqid); } diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index 78c475d..6d19e02 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -1,6 +1,7 @@ using BeyondTools.VFS.Crypto; using Campofinale.Database; using Campofinale.Game; +using Campofinale.Game.Character; using Campofinale.Network; using Campofinale.Packets.Sc; using Campofinale.Protocol; @@ -16,11 +17,42 @@ namespace Campofinale.Packets.Cs public static void HandleCsSetGender(Player session, CsMsgId cmdId, Packet packet) { CsSetGender req = packet.DecodeBody(); + if(session.chars.Count < 2) + { + if (req.Gender == Gender.GenMale) + { + session.AddCharacter("chr_0002_endminm", true); + session.RemoveCharacter("chr_0003_endminf"); + } + else + { + session.AddCharacter("chr_0003_endminf", true); + session.RemoveCharacter("chr_0002_endminm"); + } + session.teamIndex = 0; + session.teams[0].leader = session.chars[0].guid; + session.teams[0].members = new() { session.chars[0].guid }; + ScCharBagSetTeam setTeam = new() + { + CharTeam = { session.teams[0].members }, + LeaderId = session.teams[0].leader, + ScopeName = 1, + TeamIndex = 0, + TeamType = CharBagTeamType.Main, + }; + + session.Send(ScMsgId.ScCharBagSetTeam, setTeam); + session.Send(new PacketScCharBagSetCurrTeamIndex(session)); + + session.Send(new PacketScSelfSceneInfo(session,SelfInfoReasonType.SlrChangeTeam)); + } + ScSetGender rsp = new() { Gender = req.Gender, }; session.gender = rsp.Gender; + session.Send(ScMsgId.ScSetGender, rsp); } @@ -95,29 +127,7 @@ namespace Campofinale.Packets.Cs return; } session.Send(new PacketScSyncBaseData(session)); - ScItemBagCommonSync common = new() - { - LostAndFound = new() - { - InstList = - { - new ScdItemGrid() - { - GridIndex=0, - Count=1, - Id="item_port_power_pole_2", - Inst = new() - { - InstId=300000000000, - - }, - - } - } - }, - - }; - session.Send(ScMsgId.ScItemBagCommonSync, common); + session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Weapon)); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.WeaponGem)); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Equip)); @@ -126,132 +136,7 @@ namespace Campofinale.Packets.Cs session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.SpecialItem)); session.Send(new PacketScSyncAllMail(session)); session.Send(new PacketScSceneCollectionSync(session)); - string json1 = File.ReadAllText("44_ScSyncAllMission.json"); - - - ScSyncAllMission m = Newtonsoft.Json.JsonConvert.DeserializeObject(json1); - m.TrackMissionId = ""; - - //Disabled the hardcoded one and enable the missionSystem one - //session.Send(ScMsgId.ScSyncAllMission, session.missionSystem.ToProto()); - session.Send(ScMsgId.ScSyncAllMission, m); - /*ession.Send(ScMsgId.ScSyncAllMission, new ScSyncAllMission() - { - NewMissionTags = - { - - }, - - Missions = - { - {"e0m0", new Mission() - { - MissionId="e0m0", - MissionState=(int)MissionState.Processing, - SucceedId=-1, - Properties = - { - {1,new DynamicParameter() - { - RealType=1, - ValueType=1, - ValueBoolList = - { - false - } - } } - } - } } - }, - TrackMissionId = "e0m0", - - CurQuests = - { - - {"e0m0_q#1", new Quest() - { - QuestId="e0m0_q#1", - QuestState=(int)QuestState.Processing, - QuestObjectives = - { - new QuestObjective() - { - ConditionId="f6415b84", - - IsComplete=false - } - } - } }, - {"e0m0_q#2", new Quest() - { - QuestId="e0m0_q#2", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - new QuestObjective() - { - ConditionId="81736ca7", - IsComplete=false, - } - } - } }, - {"e0m0_q#3", new Quest() - { - QuestId="e0m0_q#3", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } }, - {"e0m0_q#4", new Quest() - { - QuestId="e0m0_q#4", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } }, - {"e0m0_q#5", new Quest() - { - QuestId="e0m0_q#5", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } }, - {"e0m0_q#6", new Quest() - { - QuestId="e0m0_q#6", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } }, - {"e0m0_q#7", new Quest() - { - QuestId="e0m0_q#7", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } }, - {"e0m0_q#8", new Quest() - { - QuestId="e0m0_q#8", - QuestState=(int)QuestState.Available, - QuestObjectives = - { - - } - } } - } - });*/ - + session.Send(new PacketScSyncAllMission(session)); session.Send(new PacketScGachaSync(session)); ScSettlementSyncAll settlements = new ScSettlementSyncAll() { diff --git a/Campofinale/Packets/Cs/HandleCsSceneInteractSpInteractive.cs b/Campofinale/Packets/Cs/HandleCsSceneInteractSpInteractive.cs index eb39054..29effb9 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneInteractSpInteractive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneInteractSpInteractive.cs @@ -30,6 +30,7 @@ namespace Campofinale.Packets.Cs ScSceneInteractSpInteractive rsp = new() { ObjId = req.ObjId, + }; session.Send(ScMsgId.ScSceneInteractSpInteractive, rsp); } diff --git a/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs b/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs index d4cbf2b..eec5fcd 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs @@ -20,17 +20,14 @@ namespace Campofinale.Packets.Cs { } - else + ScSceneTriggerClientInteractiveEvent tr = new() { - ScSceneTriggerClientInteractiveEvent tr = new() - { - EventName = req.EventName, - Id = req.Id, - SceneNumId = req.SceneNumId, - - }; - session.Send(ScMsgId.ScSceneTriggerClientInteractiveEvent, tr); - } + EventName = req.EventName, + Id = req.Id, + SceneNumId = req.SceneNumId, + + }; + session.Send(ScMsgId.ScSceneTriggerClientInteractiveEvent, tr); } } diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs index 9a3e459..2095ed7 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs @@ -11,16 +11,7 @@ namespace Campofinale.Packets.Cs { CsSceneSetLastSafeZone req = packet.DecodeBody(); - //TODO understand how to work - if (req.SceneNumId != session.curSceneNumId) - { - //session.sceneManager.UnloadCurrent(true); - session.curSceneNumId = req.SceneNumId; - Logger.Print("Cur Scene id changed by SetLastSafeZone"); - - //session.sceneManager.LoadCurrent(); - //session.EnterScene(req.SceneNumId,new Vector3f(req.Position),new Vector3f(req.Rotation)); - } + } diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 48e5f0b..fe8532c 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -5,6 +5,7 @@ using Campofinale.Protocol; using Campofinale.Resource; using Campofinale.Resource.Table; using Pastel; +using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; namespace Campofinale.Packets.Cs { @@ -34,16 +35,18 @@ namespace Campofinale.Packets.Cs public static void HandleCsSceneSetLevelScriptStart(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLevelScriptStart req = packet.DecodeBody(); + if (req.IsStart) { ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() { SceneNumId = req.SceneNumId, ScriptId = req.ScriptId, - + State = 4 }; - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp,packet.csHead.UpSeqid); } @@ -62,6 +65,10 @@ namespace Campofinale.Packets.Cs case ScriptActionType.SpawnEnemy: player.sceneManager.GetCurScene().SpawnEnemy(action.valueUlong[0]); break; + case ScriptActionType.UnlockSystem: + UnlockSystemType type = (UnlockSystemType)Enum.Parse(typeof(UnlockSystemType), action.valueStr[0]); + player.UnlockSystem(type); + break; default: Logger.PrintWarn("Script Action not implemented"); break; @@ -73,7 +80,7 @@ namespace Campofinale.Packets.Cs CsSceneLevelScriptEventTrigger req = packet.DecodeBody(); Logger.Print(req.Properties.ToString()); - + if (ResourceManager.levelScriptsEvents.TryGetValue(req.EventName, out LevelScriptEvent levelScriptEvent)) { Logger.Print($"Event {req.EventName.Pastel(ConsoleColor.Yellow)} Executed."); @@ -90,84 +97,6 @@ namespace Campofinale.Packets.Cs Logger.PrintWarn($" ScriptID: {req.ScriptId.ToString().Pastel(ConsoleColor.White)} "); Logger.PrintWarn($"]"); } - /*if(req.EventName== "#8777e316") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#1", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#2", - QuestState = (int)QuestState.Processing, - }); - } - if(req.EventName== "#6ea2690d") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#2", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#3", - QuestState = (int)QuestState.Processing, - }); - } - if (req.EventName == "#bb79de30") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#3", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#4", - QuestState = (int)QuestState.Processing, - }); - } - if (req.EventName == "#4c76ec3c") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#4", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#5", - QuestState = (int)QuestState.Processing, - }); - } - if (req.EventName == "#251df3ad") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#5", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#6", - QuestState = (int)QuestState.Processing, - }); - } - if (req.EventName == "#e6ac322b") - { - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#6", - QuestState = (int)QuestState.Completed, - }); - session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() - { - QuestId = "e0m0_q#7", - QuestState = (int)QuestState.Processing, - }); - }*/ ScSceneUpdateLevelScriptProperty update1 = new() { @@ -175,8 +104,16 @@ namespace Campofinale.Packets.Cs ScriptId = req.ScriptId, }; + LevelScriptData levelscript= ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.Find(l=>l.scriptId == req.ScriptId); + if (levelscript != null) { + foreach (var item in req.Properties) + { + int key = levelscript.GetPropertyId(item.Key, new List()); + update1.Properties.Add(key, item.Value); + } + } session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update1); - ScSceneTriggerClientLevelScriptEvent trigger = new() + /*ScSceneTriggerClientLevelScriptEvent trigger = new() { EventName = req.EventName, SceneNumId = req.SceneNumId, @@ -191,7 +128,7 @@ namespace Campofinale.Packets.Cs }; - session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update2); + session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update2);*/ ScSceneLevelScriptEventTrigger rsp = new ScSceneLevelScriptEventTrigger() { diff --git a/Campofinale/Packets/Cs/HandleCsTrackMission.cs b/Campofinale/Packets/Cs/HandleCsTrackMission.cs index b2b07f8..c00af56 100644 --- a/Campofinale/Packets/Cs/HandleCsTrackMission.cs +++ b/Campofinale/Packets/Cs/HandleCsTrackMission.cs @@ -10,11 +10,12 @@ namespace Campofinale.Packets.Cs { CsTrackMission req = packet.DecodeBody(); session.missionSystem.curMission = req.MissionId; + ScTrackMissionChange rsp = new() { MissionId = req.MissionId }; - session.Send(ScMsgId.ScTrackMissionChange, rsp); + session.Send(ScMsgId.ScTrackMissionChange, rsp,packet.csHead.UpSeqid); } } } diff --git a/Campofinale/Packets/Sc/PacketScEnterSceneNotify.cs b/Campofinale/Packets/Sc/PacketScEnterSceneNotify.cs index 8c851ed..17328e6 100644 --- a/Campofinale/Packets/Sc/PacketScEnterSceneNotify.cs +++ b/Campofinale/Packets/Sc/PacketScEnterSceneNotify.cs @@ -19,7 +19,7 @@ namespace Campofinale.Packets.Sc SceneNumId = sceneNumId, }; - + SetData(ScMsgId.ScEnterSceneNotify, proto); } diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index cb08b06..9b9abc0 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -60,6 +60,7 @@ namespace Campofinale.Packets.Sc }); //Levelscripts here? + if(infoReason!= SelfInfoReasonType.SlrChangeTeam) ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.ForEach(l => { LevelScriptInfo script = new LevelScriptInfo() diff --git a/Campofinale/Packets/Sc/PacketScSyncAllMission.cs b/Campofinale/Packets/Sc/PacketScSyncAllMission.cs new file mode 100644 index 0000000..1c594f6 --- /dev/null +++ b/Campofinale/Packets/Sc/PacketScSyncAllMission.cs @@ -0,0 +1,16 @@ +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Sc +{ + public class PacketScSyncAllMission : Packet + { + + public PacketScSyncAllMission(Player client) { + + + SetData(ScMsgId.ScSyncAllMission, client.missionSystem.ToProto()); + } + + } +} diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 78f1ddd..7b9faeb 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -170,12 +170,13 @@ namespace Campofinale } bitsetManager.Load(data.bitsets); savedSaveZone = data.savedSafeZone; + if(Server.config.serverOptions.missionsEnabled) missionSystem.Load(); } else { Initialize(); //only if no account found } - missionSystem.Load(); + sceneManager.Load(); factoryManager.Load(); return (data != null); @@ -202,39 +203,80 @@ namespace Campofinale { return chars.Find(c => c.id==templateId); } + /// + /// Add a character with template id if not present in the chars list *Added in 1.1.6* + /// + /// + public void AddCharacter(string id, bool notify = false) + { + Character chara = GetCharacter(id); + if (chara == null) + { + Character c = new Character(roleId, id, 1); + chars.Add(c); + if (notify) + { + Send(new PacketScCharBagAddChar(this,c)); + } + } + } + /// + /// Remove a character using template id *Added in 1.1.6* + /// + /// + public void RemoveCharacter(string id) + { + Character chara = GetCharacter(id); + if (chara == null) + { + return; + } + chars.Remove(chara); + Send(new PacketScCharBagDelChar(this,chara)); + } + public void ReplaceCharacter(string id, string newId) + { + Character chara = GetCharacter(id); + if (chara == null) + { + return; + } + chara.id = newId; + Send(new PacketScSyncCharBagInfo(this)); + } public void Initialize() { - if (Server.config.serverOptions.defaultCharacters.giveAllCharacters) + if (Server.config.serverOptions.missionsEnabled) { - foreach (var item in ResourceManager.characterTable) - { - chars.Add(new Character(roleId, item.Key, Server.config.serverOptions.defaultCharacters.defaultLevel)); - } + chars.Add(new Character(roleId, "chr_0002_endminm", 1)); + missionSystem.AddMission("e0m0", MissionState.Processing); } else { - foreach (var item in Server.config.serverOptions.defaultCharacters.characters) + foreach (var item in ResourceManager.characterTable) { - chars.Add(new Character(roleId, item, Server.config.serverOptions.defaultCharacters.defaultLevel)); + chars.Add(new Character(roleId, item.Key, 1)); + } + UnlockImportantSystems(); + } + if (Server.config.serverOptions.giveAllItems) + { + foreach (var item in itemTable) + { + if (item.Value.GetStorage() != ItemStorageSpace.BagAndFactoryDepot) + { + if (item.Value.maxStackCount == -1) + { + inventoryManager.items.Add(new Item(roleId, item.Value.id, 10000000)); + } + else + { + inventoryManager.items.Add(new Item(roleId, item.Value.id, item.Value.maxStackCount)); + } + } } } - foreach(var item in itemTable) - { - if(item.Value.GetStorage()!= ItemStorageSpace.BagAndFactoryDepot) - { - if (item.Value.maxStackCount == -1) - { - inventoryManager.items.Add(new Item(roleId, item.Value.id, 10000000)); - } - else - { - inventoryManager.items.Add(new Item(roleId, item.Value.id, item.Value.maxStackCount)); - } - } - - - } teams.Add(new Team() { leader = chars[0].guid, @@ -262,8 +304,8 @@ namespace Campofinale } });*/ + - UnlockImportantSystems(); spaceshipManager.Load(); } public void UnlockImportantSystems() @@ -511,6 +553,7 @@ namespace Campofinale DatabaseManager.db.SavePlayerData(this); inventoryManager.Save(); spaceshipManager.Save(); + if(Server.config.serverOptions.missionsEnabled) missionSystem.Save(); SaveCharacters(); SaveMails(); @@ -636,5 +679,17 @@ namespace Campofinale } } + /// + /// Unlock a system + /// + /// + public void UnlockSystem(UnlockSystemType t) + { + unlockedSystems.Add((int)t); + Send(ScMsgId.ScUnlockSystem, new ScUnlockSystem() + { + UnlockSystemType = (int)t + }); + } } } diff --git a/Campofinale/Program.cs b/Campofinale/Program.cs index 0d54c17..2663065 100644 --- a/Campofinale/Program.cs +++ b/Campofinale/Program.cs @@ -11,9 +11,6 @@ class Program private static void StartServer(string[] args) { Console.Title = "Initializing..."; - - //bool disableLogs = args.Length > 0 && args[0].ToLower() == "nologs"; - ConfigFile config = new ConfigFile(); if (File.Exists("server_config.json")) { @@ -27,7 +24,7 @@ class Program }).Start(); AppDomain.CurrentDomain.ProcessExit += (_, _) => { - Console.WriteLine("Shutting down..."); + Logger.Print("Shutting down..."); Server.Shutdown(); }; diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 16adb7a..109dbb5 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -480,6 +480,8 @@ namespace Campofinale.Resource public List levelDataPaths; [JsonIgnore] public LevelData levelData; + + //public List levelDataList; public class LevelData { public string sceneId=""; @@ -757,6 +759,13 @@ namespace Campofinale.Resource float dz = z - other.z; return MathF.Sqrt(dx * dx + dy * dy + dz * dz); } + public float DistanceXZ(Vector3f other) + { + float dx = x - other.x; + float dy = 0; + float dz = z - other.z; + return MathF.Sqrt(dx * dx + dy * dy + dz * dz); + } public ScdVec3Int ToProtoScd() { return new ScdVec3Int() diff --git a/Campofinale/Resource/Table/LevelScriptEvent.cs b/Campofinale/Resource/Table/LevelScriptEvent.cs index ee6fbdc..3ba79db 100644 --- a/Campofinale/Resource/Table/LevelScriptEvent.cs +++ b/Campofinale/Resource/Table/LevelScriptEvent.cs @@ -24,7 +24,8 @@ namespace Campofinale.Resource.Table None = 0, CompleteQuest = 1, ProcessQuest = 2, - SpawnEnemy = 3 + SpawnEnemy = 3, + UnlockSystem = 4, } } diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 3ac301b..fc79073 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -174,7 +174,6 @@ namespace Campofinale dispatch = new Dispatch(); dispatch.Start(); } - public static CsMsgId[] hideLog = []; public static string ColoredText(string text, string color) { From 7c0a512ad646ca83933d869b54ae891c62c60aad Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 28 May 2025 12:12:04 +0200 Subject: [PATCH 04/27] test --- Campofinale/Game/Entities/Entity.cs | 1 + .../Game/Entities/EntityInteractive.cs | 2 + Campofinale/Game/SceneManager.cs | 46 ++-- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 17 +- .../Resource/Table/LevelScriptEvent.cs | 4 +- Dotfuscator1.xml | 229 ++++++++++++++++++ 6 files changed, 266 insertions(+), 33 deletions(-) create mode 100644 Dotfuscator1.xml diff --git a/Campofinale/Game/Entities/Entity.cs b/Campofinale/Game/Entities/Entity.cs index 4cb04aa..264e3f1 100644 --- a/Campofinale/Game/Entities/Entity.cs +++ b/Campofinale/Game/Entities/Entity.cs @@ -21,6 +21,7 @@ namespace Campofinale.Game.Entities public List properties=new(); public int sceneNumId; public bool spawned = false; + public bool defaultHide = false; public Entity() { diff --git a/Campofinale/Game/Entities/EntityInteractive.cs b/Campofinale/Game/Entities/EntityInteractive.cs index c543430..9034815 100644 --- a/Campofinale/Game/Entities/EntityInteractive.cs +++ b/Campofinale/Game/Entities/EntityInteractive.cs @@ -14,6 +14,7 @@ namespace Campofinale.Game.Entities { } + public EntityInteractive(string templateId, ulong worldOwner, Vector3f pos, Vector3f rot, int scene, ulong g=0) { if (g == 0) @@ -86,6 +87,7 @@ namespace Campofinale.Game.Entities (bool, int) index = GetPropertyIndex(prop.key, proto.Properties.Keys.Count > 0 ? proto.Properties.Keys.Max() : 0); if (p != null && index.Item1) { + if(!proto.Properties.ContainsKey(index.Item2)) proto.Properties.Add(index.Item2, p); } diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 3e3ad7c..d66768f 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -253,6 +253,8 @@ namespace Campofinale.Game public List entities = new(); [BsonIgnore, JsonIgnore] public bool alreadyLoaded = false; + [BsonIgnore, JsonIgnore] + public List activeScripts = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -379,53 +381,35 @@ namespace Campofinale.Game } public void SpawnEntity(Entity en,bool spawnedCheck=true) { + if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0) + { + return; + } en.spawned = true; - List toSpawn = new List(); - toSpawn.Add(en); - foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e.spawned == false)) + ParamKeyValue targetList=en.properties.Find(p => p.key == "target_list"); + if(targetList!=null) + foreach (Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned == false && targetList.value.valueArray.Any(v=>v.valueBit64== (long)e.levelLogicId))) { - e.spawned = true; - toSpawn.Add(e); + SpawnEntity(e); } - /*if(en.belongLevelScriptId != 0) - if (spawnedCheck) - { - foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e.spawned == false && e.Position.Distance(GetOwner().position) < 100)) - { - e.spawned = true; - toSpawn.Add(e); - } - } - else - { - foreach (Entity e in GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == en.belongLevelScriptId && e != en)) - { - e.spawned = true; - toSpawn.Add(e); - - } - }*/ - - toSpawn.ForEach(e => - { - GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e})); - }); + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en})); } public void UpdateShowEntities() { foreach(Entity en in GetEntityExcludingChar()) { - float minDis = en is EntityInteractive ? 180 : 50; + float minDis = 100; + //todo new system if (en.Position.DistanceXZ(GetOwner().position) < minDis) { if (!en.spawned) { SpawnEntity(en); - - + + } } else diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index fe8532c..8c90662 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -25,7 +25,13 @@ namespace Campofinale.Packets.Cs State = 3 }; + + if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) + { + session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); + } session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } @@ -45,7 +51,7 @@ namespace Campofinale.Packets.Cs State = 4 }; - + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp,packet.csHead.UpSeqid); } @@ -69,6 +75,15 @@ namespace Campofinale.Packets.Cs UnlockSystemType type = (UnlockSystemType)Enum.Parse(typeof(UnlockSystemType), action.valueStr[0]); player.UnlockSystem(type); break; + case ScriptActionType.EnterScene: + player.EnterScene((int)action.valueUlong[0]); + break; + case ScriptActionType.AddMission: + player.missionSystem.AddMission(action.valueStr[0]); + break; + case ScriptActionType.CompleteMission: + //player.missionSystem.C(action.valueStr[0]); + break; default: Logger.PrintWarn("Script Action not implemented"); break; diff --git a/Campofinale/Resource/Table/LevelScriptEvent.cs b/Campofinale/Resource/Table/LevelScriptEvent.cs index 3ba79db..e57fc4a 100644 --- a/Campofinale/Resource/Table/LevelScriptEvent.cs +++ b/Campofinale/Resource/Table/LevelScriptEvent.cs @@ -26,6 +26,8 @@ namespace Campofinale.Resource.Table ProcessQuest = 2, SpawnEnemy = 3, UnlockSystem = 4, - + EnterScene = 5, + AddMission = 6, + CompleteMission = 7, } } diff --git a/Dotfuscator1.xml b/Dotfuscator1.xml new file mode 100644 index 0000000..44bfed3 --- /dev/null +++ b/Dotfuscator1.xml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0a42b8077283e0ee5822d9d8214e77f05f383ee5 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 28 May 2025 17:45:23 +0200 Subject: [PATCH 05/27] scene manager "test" --- Campofinale/Game/SceneManager.cs | 66 +++++++++++-------- Campofinale/Packets/Cs/HandleCsLogin.cs | 5 +- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 6 +- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index d66768f..d1148f2 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -279,6 +279,7 @@ namespace Campofinale.Game { return entities.FindAll(c => c is not EntityCharacter); } + public void Unload() { List guids = new(); @@ -375,6 +376,7 @@ namespace Campofinale.Game // e.spawned = true; // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); }); + UpdateShowEntities(); @@ -393,38 +395,50 @@ namespace Campofinale.Game SpawnEntity(e); } - GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en})); + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en })); } public void UpdateShowEntities() { - - foreach(Entity en in GetEntityExcludingChar()) + List toSpawn = new(); + foreach(Entity e in GetEntityExcludingChar()) { - float minDis = 100; + if(e.spawned==false && (activeScripts.Contains(e.belongLevelScriptId) || e.belongLevelScriptId==0)) + { + toSpawn.Add(e); + e.spawned= true; + } - //todo new system - if (en.Position.DistanceXZ(GetOwner().position) < minDis) - { - if (!en.spawned) - { - SpawnEntity(en); - - - } - } - else - { - - /*if (en.spawned) - { - - en.spawned = false; - GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), new List() { en.guid })); - en.Position=en.BornPos; - en.Rotation = en.Rotation; - }*/ - } } + if(toSpawn.Count > 0) + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), toSpawn)); + + /* foreach(Entity en in GetEntityExcludingChar()) + { + float minDis = 100; + + //todo new system + if (en.Position.DistanceXZ(GetOwner().position) < minDis) + { + if (!en.spawned) + { + SpawnEntity(en); + + + } + } + else + { + + /*if (en.spawned) + { + + en.spawned = false; + GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), new List() { en.guid })); + en.Position=en.BornPos; + en.Rotation = en.Rotation; + } + } + }*/ } public Player GetOwner() diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index 6d19e02..d21c0f2 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -127,7 +127,10 @@ namespace Campofinale.Packets.Cs return; } session.Send(new PacketScSyncBaseData(session)); - + session.Send(ScMsgId.ScSceneClientIdInfo, new ScSceneClientIdInfo() + { + + }); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Weapon)); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.WeaponGem)); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Equip)); diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 8c90662..ce2ff2e 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -26,12 +26,14 @@ namespace Campofinale.Packets.Cs State = 3 }; + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) { session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); + session.sceneManager.GetCurScene().UpdateShowEntities(); } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); - + } From f416665d40e33ff5633e80b06cef83a4805c599f Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Thu, 29 May 2025 00:32:39 +0200 Subject: [PATCH 06/27] new types --- Campofinale/Game/SceneManager.cs | 23 ++++-- Campofinale/Packets/Cs/HandleCsLogin.cs | 4 +- .../Packets/Cs/HandleCsSceneSetBattle.cs | 22 ++++++ .../Cs/HandleCsSceneSetLevelScriptActive.cs | 71 ++++++++++++++----- .../Resource/Table/LevelScriptEvent.cs | 2 + 5 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 Campofinale/Packets/Cs/HandleCsSceneSetBattle.cs diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index d1148f2..589a499 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -297,7 +297,7 @@ namespace Campofinale.Game public void Load() { if (info().isSeamless && alreadyLoaded) return; - alreadyLoaded = true; + //alreadyLoaded = true; Unload(); LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); @@ -345,6 +345,7 @@ namespace Campofinale.Game levelLogicId = en.levelLogicId, }; + entity.defaultHide=en.defaultHide; entities.Add(entity); }); lv_scene.levelData.npcs.ForEach(en => @@ -381,6 +382,7 @@ namespace Campofinale.Game } + public void SpawnEntity(Entity en,bool spawnedCheck=true) { if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0) @@ -404,8 +406,12 @@ namespace Campofinale.Game { if(e.spawned==false && (activeScripts.Contains(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { - toSpawn.Add(e); - e.spawned= true; + if (!e.defaultHide) + { + toSpawn.Add(e); + e.spawned = true; + } + } } @@ -445,7 +451,14 @@ namespace Campofinale.Game { return Server.clients.Find(c => c.roleId == ownerId); } - + public void SpawnEnemyByScriptId(ulong id) + { + GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == id).ForEach(e => + { + e.spawned = true; + }); + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == id))); + } public void SpawnEnemy(ulong v) { LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); @@ -462,5 +475,7 @@ namespace Campofinale.Game SpawnEntity(entity); } } + + } } diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index d21c0f2..7e08074 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -29,6 +29,7 @@ namespace Campofinale.Packets.Cs session.AddCharacter("chr_0003_endminf", true); session.RemoveCharacter("chr_0002_endminm"); } + session.teamIndex = 0; session.teams[0].leader = session.chars[0].guid; session.teams[0].members = new() { session.chars[0].guid }; @@ -129,7 +130,8 @@ namespace Campofinale.Packets.Cs session.Send(new PacketScSyncBaseData(session)); session.Send(ScMsgId.ScSceneClientIdInfo, new ScSceneClientIdInfo() { - + RoleIdx=6, + LastMaxIdx=session.random.v }); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Weapon)); session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.WeaponGem)); diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetBattle.cs b/Campofinale/Packets/Cs/HandleCsSceneSetBattle.cs new file mode 100644 index 0000000..667197f --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSceneSetBattle.cs @@ -0,0 +1,22 @@ +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsSceneSetBattle + { + + [Server.Handler(CsMsgId.CsSceneSetBattle)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSceneSetBattle req = packet.DecodeBody(); + + ScSceneSetBattle rsp = new() + { + InBattle = req.InBattle, + }; + session.Send(ScMsgId.ScSceneSetBattle, rsp); + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index ce2ff2e..2229b04 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -5,6 +5,7 @@ using Campofinale.Protocol; using Campofinale.Resource; using Campofinale.Resource.Table; using Pastel; +using System.Net.Sockets; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; namespace Campofinale.Packets.Cs @@ -26,13 +27,17 @@ namespace Campofinale.Packets.Cs State = 3 }; - - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) { session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); session.sceneManager.GetCurScene().UpdateShowEntities(); } + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + + + } + else + { } @@ -50,17 +55,29 @@ namespace Campofinale.Packets.Cs { SceneNumId = req.SceneNumId, ScriptId = req.ScriptId, - + State = 4 }; - - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp,packet.csHead.UpSeqid); - } - + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp, packet.csHead.UpSeqid); + } + else + { + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = 4 + }; + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp, packet.csHead.UpSeqid); + } + + } - public static void ExecuteEventAction(Player player, ScriptAction action) + public static void ExecuteEventAction(Player player, ScriptAction action, CsSceneLevelScriptEventTrigger req) { switch (action.action) { @@ -71,7 +88,17 @@ namespace Campofinale.Packets.Cs player.missionSystem.ProcessQuest(action.valueStr[0]); break; case ScriptActionType.SpawnEnemy: - player.sceneManager.GetCurScene().SpawnEnemy(action.valueUlong[0]); + foreach (ulong id in action.valueUlong) + { + player.sceneManager.GetCurScene().SpawnEnemy(id); + } + + break; + case ScriptActionType.SpawnEnemyByScriptId: + foreach(ulong id in action.valueUlong) + { + player.sceneManager.GetCurScene().SpawnEnemyByScriptId(id); + } break; case ScriptActionType.UnlockSystem: UnlockSystemType type = (UnlockSystemType)Enum.Parse(typeof(UnlockSystemType), action.valueStr[0]); @@ -83,6 +110,19 @@ namespace Campofinale.Packets.Cs case ScriptActionType.AddMission: player.missionSystem.AddMission(action.valueStr[0]); break; + case ScriptActionType.CallClientEvent: + foreach(string id in action.valueStr) + { + ScSceneTriggerClientLevelScriptEvent trigger = new() + { + EventName = id, + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + }; + + player.Send(ScMsgId.ScSceneTriggerClientLevelScriptEvent, trigger); + } + break; case ScriptActionType.CompleteMission: //player.missionSystem.C(action.valueStr[0]); break; @@ -104,7 +144,7 @@ namespace Campofinale.Packets.Cs Logger.Print($"{levelScriptEvent.comment}"); levelScriptEvent.actions.ForEach(a => { - ExecuteEventAction(session, a); + ExecuteEventAction(session, a,req); }); } else @@ -130,15 +170,8 @@ namespace Campofinale.Packets.Cs } } session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update1); - /*ScSceneTriggerClientLevelScriptEvent trigger = new() - { - EventName = req.EventName, - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - }; - session.Send(ScMsgId.ScSceneTriggerClientLevelScriptEvent, trigger); - ScSceneUpdateLevelScriptProperty update2 = new() + + /*ScSceneUpdateLevelScriptProperty update2 = new() { SceneNumId = req.SceneNumId, ScriptId = req.ScriptId, diff --git a/Campofinale/Resource/Table/LevelScriptEvent.cs b/Campofinale/Resource/Table/LevelScriptEvent.cs index e57fc4a..f5d2d2d 100644 --- a/Campofinale/Resource/Table/LevelScriptEvent.cs +++ b/Campofinale/Resource/Table/LevelScriptEvent.cs @@ -29,5 +29,7 @@ namespace Campofinale.Resource.Table EnterScene = 5, AddMission = 6, CompleteMission = 7, + SpawnEnemyByScriptId = 8, + CallClientEvent = 9 } } From 5ae50be50798fc3a91df23f79256f64f8e0c1db9 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 30 May 2025 00:32:25 +0200 Subject: [PATCH 07/27] new levelscriptevent action types --- Campofinale/Game/MissionSys/MissionSystem.cs | 33 +++++ Campofinale/Game/SceneManager.cs | 13 ++ Campofinale/Game/Spawners/GameSpawner.cs | 67 +++++++++++ .../Packets/Cs/HandleCsCharBagSetTeam.cs | 11 +- Campofinale/Packets/Cs/HandleCsCheckName.cs | 22 ++++ .../Packets/Cs/HandleCsCheckSensitive.cs | 22 ++++ .../Cs/HandleCsSceneSetLevelScriptActive.cs | 113 +++++++++++++++--- Campofinale/Packets/Cs/HandleCsSetName.cs | 23 ++++ .../Packets/Sc/PacketScCharBagSetTeam.cs | 24 ++++ .../Packets/Sc/PacketScObjectEnterView.cs | 3 +- Campofinale/Player.cs | 39 +++++- Campofinale/Resource/Dynamic/SpawnerConfig.cs | 55 +++++++++ .../{Table => Json}/LevelScriptEvent.cs | 11 +- Campofinale/Resource/ResourceManager.cs | 75 +++++++++++- 14 files changed, 468 insertions(+), 43 deletions(-) create mode 100644 Campofinale/Game/Spawners/GameSpawner.cs create mode 100644 Campofinale/Packets/Cs/HandleCsCheckName.cs create mode 100644 Campofinale/Packets/Cs/HandleCsCheckSensitive.cs create mode 100644 Campofinale/Packets/Cs/HandleCsSetName.cs create mode 100644 Campofinale/Packets/Sc/PacketScCharBagSetTeam.cs create mode 100644 Campofinale/Resource/Dynamic/SpawnerConfig.cs rename Campofinale/Resource/{Table => Json}/LevelScriptEvent.cs (75%) diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs index 898447e..914dd0e 100644 --- a/Campofinale/Game/MissionSys/MissionSystem.cs +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -104,6 +104,7 @@ namespace Campofinale.Game.MissionSys missions.Add(new GameMission(id, state)); if (notify) { + ScMissionStateUpdate s = new() { MissionId = data.missionId, @@ -231,6 +232,38 @@ namespace Campofinale.Game.MissionSys quests.Remove(quest); } } + + public void TrackMission(string v) + { + curMission = v; + owner.Send(ScMsgId.ScTrackMissionChange, new ScTrackMissionChange() + { + MissionId = curMission, + }); + } + + public void CompleteMission(string v) + { + if(curMission == v) + { + TrackMission(""); + } + GameMission mission = missions.Find(m => m.missionId == v); + MissionDataTable data = ResourceManager.missionDataTable.Find(m => m.missionId == v); + if (mission != null && data != null) + { + mission.state=MissionState.Completed; + ScMissionStateUpdate s = new() + { + MissionId = mission.missionId, + MissionState = (int)mission.state, + SucceedId = -1, + + }; + owner.Send(ScMsgId.ScMissionStateUpdate, s); + //TODO rewards + } + } } public class GameQuest { diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 589a499..e81d4ef 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -1,5 +1,6 @@ using Campofinale.Game.Entities; using Campofinale.Game.Inventory; +using Campofinale.Game.Spawners; using Campofinale.Packets.Sc; using Campofinale.Resource; using MongoDB.Bson.Serialization.Attributes; @@ -255,6 +256,8 @@ namespace Campofinale.Game public bool alreadyLoaded = false; [BsonIgnore, JsonIgnore] public List activeScripts = new(); + [BsonIgnore, JsonIgnore] + public List gameSpawners = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -359,6 +362,7 @@ namespace Campofinale.Game type = en.entityType, }; + entity.defaultHide = en.defaultHide; entities.Add(entity); }); GetEntityExcludingChar().ForEach(e => @@ -401,6 +405,15 @@ namespace Campofinale.Game } public void UpdateShowEntities() { + for (int i = 0; i < gameSpawners.Count; i++) + { + GameSpawner spawner = gameSpawners[i]; + if(spawner != null) + { + spawner.Update(GetOwner()); + } + } + List toSpawn = new(); foreach(Entity e in GetEntityExcludingChar()) { diff --git a/Campofinale/Game/Spawners/GameSpawner.cs b/Campofinale/Game/Spawners/GameSpawner.cs new file mode 100644 index 0000000..0016bab --- /dev/null +++ b/Campofinale/Game/Spawners/GameSpawner.cs @@ -0,0 +1,67 @@ +using Campofinale.Game.Entities; +using Campofinale.Resource; +using Campofinale.Resource.Dynamic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.Spawners +{ + public class GameSpawner + { + public Scene scene; + public int curWave = 1; + public int curGroup = 1; + public string configId; + public bool spawned; + + public SpawnerConfig GetConfig() + { + return ResourceManager.spawnerConfigs.Find(s => s.configId == configId); + } + public SpawnerConfig.WaveGroup GetCurrentWaveGroup() + { + return GetConfig().waveMap[$"{curWave}"].groupMap[$"{curGroup}"]; + } + public int GetEnemiesOfCurrentWave() + { + return scene.entities.FindAll(e => e.dependencyGroupId == GetCurrentWaveGroup().groupId).Count; + } + + public void Update(Player player) + { + if (spawned) + { + if (GetEnemiesOfCurrentWave() < 1) + { + if (GetConfig().waveMap.ContainsKey($"{curWave + 1}")) + { + curWave++; + spawned = false; + } + } + } + else + { + + foreach (var item in GetCurrentWaveGroup().actionMap.Values) + { + Logger.Print($"Debug: Spawning {item.libraryKey}"); + scene.entities.Add(new EntityMonster(item.libraryKey, 1, player.roleId, item.position, item.rotation, scene.sceneNumId) + { + dependencyGroupId = GetCurrentWaveGroup().groupId, + defaultHide = false, + spawned = false + }); + + + } + spawned = true; + + } + + } + } +} diff --git a/Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs b/Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs index e588c68..0fa34ab 100644 --- a/Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs +++ b/Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs @@ -14,16 +14,7 @@ namespace Campofinale.Packets.Cs session.teams[req.TeamIndex].leader=req.LeaderId; session.teams[req.TeamIndex].members= req.CharTeam.ToList(); - ScCharBagSetTeam team = new() - { - CharTeam = { req.CharTeam }, - LeaderId = req.LeaderId, - ScopeName = 1, - TeamIndex = req.TeamIndex, - TeamType = CharBagTeamType.Main, - }; - - session.Send(ScMsgId.ScCharBagSetTeam,team); + session.Send(new PacketScCharBagSetTeam(session,session.teams[req.TeamIndex], req.TeamIndex)); session.Send(new PacketScSelfSceneInfo(session, Resource.SelfInfoReasonType.SlrChangeTeam)); } diff --git a/Campofinale/Packets/Cs/HandleCsCheckName.cs b/Campofinale/Packets/Cs/HandleCsCheckName.cs new file mode 100644 index 0000000..90f3a39 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsCheckName.cs @@ -0,0 +1,22 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + + public class HandleCsCheckName + { + [Server.Handler(CsMsgId.CsCheckName)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsCheckName req = packet.DecodeBody(); + session.Send(ScMsgId.ScCheckName, new ScCheckName() + { + Name = req.Name, + Pass=true + },packet.csHead.UpSeqid); + } + } +} diff --git a/Campofinale/Packets/Cs/HandleCsCheckSensitive.cs b/Campofinale/Packets/Cs/HandleCsCheckSensitive.cs new file mode 100644 index 0000000..296a537 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsCheckSensitive.cs @@ -0,0 +1,22 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + + public class HandleCsCheckSensitive + { + [Server.Handler(CsMsgId.CsCheckSensitive)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsCheckSensitive req = packet.DecodeBody(); + + session.Send(ScMsgId.ScCheckSensitive, new ScCheckSensitive() + { + + }); + } + } +} diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 2229b04..3e98a2f 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -3,7 +3,7 @@ using Campofinale.Game.Entities; using Campofinale.Network; using Campofinale.Protocol; using Campofinale.Resource; -using Campofinale.Resource.Table; +using Campofinale.Resource.Json; using Pastel; using System.Net.Sockets; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; @@ -38,7 +38,20 @@ namespace Campofinale.Packets.Cs } else { + /* ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + State = 3 + }; + + if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) + { + session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); + session.sceneManager.GetCurScene().UpdateShowEntities(); + } + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp);*/ } @@ -59,22 +72,11 @@ namespace Campofinale.Packets.Cs State = 4 }; - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp, packet.csHead.UpSeqid); - } - else - { - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() - { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - State = 4 - }; - - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp, packet.csHead.UpSeqid); + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } + } public static void ExecuteEventAction(Player player, ScriptAction action, CsSceneLevelScriptEventTrigger req) @@ -107,25 +109,98 @@ namespace Campofinale.Packets.Cs case ScriptActionType.EnterScene: player.EnterScene((int)action.valueUlong[0]); break; + case ScriptActionType.CompleteMission: + player.missionSystem.CompleteMission(action.valueStr[0]); + break; case ScriptActionType.AddMission: - player.missionSystem.AddMission(action.valueStr[0]); + player.missionSystem.AddMission(action.valueStr[0],MissionState.Processing,true); + if(action.valueUlong.Length > 0) + { + + player.missionSystem.TrackMission(action.valueStr[0]); + } + break; + case ScriptActionType.StartSpawner: + + player.sceneManager.GetCurScene().gameSpawners.Add(new Game.Spawners.GameSpawner() + { + configId = action.valueStr[0], + scene= player.sceneManager.GetCurScene() + }); + break; + case ScriptActionType.AddCharacter: + Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true); + player.AddToTeam(player.teamIndex, chara.guid); + break; + case ScriptActionType.ChangeScriptPropertyBool: + int i = 0; + ScSceneUpdateLevelScriptProperty update1 = new() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + }; + foreach (string keyId in action.valueStr) + { + long val = (long)action.valueUlong[i]; + + LevelScriptData levelscript = ResourceManager.GetLevelData(player.curSceneNumId).levelData.levelScripts.Find(l => l.scriptId == req.ScriptId); + if (levelscript != null) + { + int key = levelscript.GetPropertyId(keyId, new List()); + ParamKeyValue v = new() + { + key = keyId, + value = new ParamKeyValue.ParamValue() + { + type = ParamRealType.Bool, + valueArray = new[] + { + new ParamKeyValue.ParamValueAtom() + { + valueBit64=val, + + } + } + } + }; + update1.Properties.Add(key, v.ToProto()); + } + + i++; + + } + player.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update1); + break; + case ScriptActionType.StartScript: + foreach (ulong id in action.valueUlong) + { + + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = id, + + State = 4 + }; + + player.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } break; case ScriptActionType.CallClientEvent: foreach(string id in action.valueStr) { + LevelScriptData levelscript = ResourceManager.GetLevelData(player.curSceneNumId).levelData.levelScripts.Find(l => l.actionMap.dataMap.headerList.Any(h=>h._eventKey.constValue==id)); ScSceneTriggerClientLevelScriptEvent trigger = new() { EventName = id, SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, + ScriptId = levelscript== null ? req.ScriptId : levelscript.scriptId, }; player.Send(ScMsgId.ScSceneTriggerClientLevelScriptEvent, trigger); } break; - case ScriptActionType.CompleteMission: - //player.missionSystem.C(action.valueStr[0]); - break; default: Logger.PrintWarn("Script Action not implemented"); break; diff --git a/Campofinale/Packets/Cs/HandleCsSetName.cs b/Campofinale/Packets/Cs/HandleCsSetName.cs new file mode 100644 index 0000000..ceb9c6c --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSetName.cs @@ -0,0 +1,23 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + + public class HandleCsSetName + { + [Server.Handler(CsMsgId.CsSetName)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSetName req = packet.DecodeBody(); + session.nickname = req.Name; + session.Send(ScMsgId.ScSetName, new ScSetName() + { + Name = req.Name, + + },packet.csHead.UpSeqid); + } + } +} diff --git a/Campofinale/Packets/Sc/PacketScCharBagSetTeam.cs b/Campofinale/Packets/Sc/PacketScCharBagSetTeam.cs new file mode 100644 index 0000000..5ac198f --- /dev/null +++ b/Campofinale/Packets/Sc/PacketScCharBagSetTeam.cs @@ -0,0 +1,24 @@ +using Campofinale.Game; +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Sc +{ + public class PacketScCharBagSetTeam : Packet + { + + public PacketScCharBagSetTeam(Player client, Team team, int index) { + + ScCharBagSetTeam proto = new ScCharBagSetTeam() + { + CharTeam = {team.members }, + LeaderId = team.leader, + ScopeName = 1, + TeamIndex = index, + TeamType = CharBagTeamType.Main, + }; + SetData(ScMsgId.ScCharBagSetTeam, proto); + } + + } +} diff --git a/Campofinale/Packets/Sc/PacketScObjectEnterView.cs b/Campofinale/Packets/Sc/PacketScObjectEnterView.cs index 856153b..6f5ff3c 100644 --- a/Campofinale/Packets/Sc/PacketScObjectEnterView.cs +++ b/Campofinale/Packets/Sc/PacketScObjectEnterView.cs @@ -16,7 +16,8 @@ namespace Campofinale.Packets.Sc SummonList = { - } + }, + }, HasExtraObject = entities.Count > 1 diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 7b9faeb..65de5b5 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -207,18 +207,37 @@ namespace Campofinale /// Add a character with template id if not present in the chars list *Added in 1.1.6* /// /// - public void AddCharacter(string id, bool notify = false) + public Character AddCharacter(string id, bool notify = false) { Character chara = GetCharacter(id); if (chara == null) { - Character c = new Character(roleId, id, 1); - chars.Add(c); + chara = new Character(roleId, id, 1); + chars.Add(chara); if (notify) { - Send(new PacketScCharBagAddChar(this,c)); + Send(new PacketScCharBagAddChar(this,chara)); } } + return chara; + } + /// + /// Add a character with template id and level if not present in the chars list *Added in 1.1.6* + /// + /// + public Character AddCharacter(string id, int level, bool notify = false) + { + Character chara = GetCharacter(id); + if (chara == null) + { + chara = new Character(roleId, id, level); + chars.Add(chara); + if (notify) + { + Send(new PacketScCharBagAddChar(this, chara)); + } + } + return chara; } /// /// Remove a character using template id *Added in 1.1.6* @@ -691,5 +710,17 @@ namespace Campofinale UnlockSystemType = (int)t }); } + + public void AddToTeam(int index, ulong guid) + { + if (teams[index].members.Count < 4) + { + teams[index].members.Add(guid); + Send(new PacketScCharBagSetTeam(this, teams[index], index)); + if(index==this.teamIndex) + Send(new PacketScSelfSceneInfo(this, Resource.SelfInfoReasonType.SlrChangeTeam)); + } + + } } } diff --git a/Campofinale/Resource/Dynamic/SpawnerConfig.cs b/Campofinale/Resource/Dynamic/SpawnerConfig.cs new file mode 100644 index 0000000..d739539 --- /dev/null +++ b/Campofinale/Resource/Dynamic/SpawnerConfig.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Resource.Dynamic +{ + public class SpawnerConfig + { + public string configId; + public Dictionary waveMap = new(); + + + + public SpawnerConfig() { } + + public class SpawnerWave + { + public int waveId; + public bool repeatable; + public int waveModeKillCount; + + + public Dictionary groupMap = new(); + + } + public class WaveGroup + { + public int groupId; + public int groupMode; + public int groupModeKillCount; + public float timestamp; + public Dictionary actionMap = new(); + + + } + public class GroupAction + { + [JsonPropertyName("$type")] + public string type; + public int actionId; + public float timestamp; + public string libraryKey; + public int spawnCount; + public float spawnInterval; + public Vector3f position; + public Vector3f rotation; + public float randomizeRadius; + public int routeId; + } + } +} diff --git a/Campofinale/Resource/Table/LevelScriptEvent.cs b/Campofinale/Resource/Json/LevelScriptEvent.cs similarity index 75% rename from Campofinale/Resource/Table/LevelScriptEvent.cs rename to Campofinale/Resource/Json/LevelScriptEvent.cs index f5d2d2d..ef6832c 100644 --- a/Campofinale/Resource/Table/LevelScriptEvent.cs +++ b/Campofinale/Resource/Json/LevelScriptEvent.cs @@ -4,10 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Campofinale.Resource.Table +namespace Campofinale.Resource.Json { - [TableCfgType("Json/LevelScriptEvents.json", LoadPriority.LOW)] - public class LevelScriptEvent : TableCfgResource + public class LevelScriptEvent { public string eventName; public string comment; @@ -30,6 +29,10 @@ namespace Campofinale.Resource.Table AddMission = 6, CompleteMission = 7, SpawnEnemyByScriptId = 8, - CallClientEvent = 9 + CallClientEvent = 9, + StartScript = 10, + ChangeScriptPropertyBool = 11, + StartSpawner = 12, + AddCharacter = 13 } } diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 109dbb5..7a0c04b 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -1,4 +1,6 @@ -using Campofinale.Resource.Table; +using Campofinale.Resource.Dynamic; +using Campofinale.Resource.Json; +using Campofinale.Resource.Table; using Newtonsoft.Json; using static Campofinale.Resource.ResourceManager.LevelScene; @@ -72,8 +74,8 @@ namespace Campofinale.Resource public static InteractiveTable interactiveTable = new(); // public static List levelDatas = new(); - public static List interactiveData = new(); - + public static List interactiveData = new(); + public static List spawnerConfigs = new(); public static int GetSceneNumIdFromLevelData(string name) { if (levelDatas.Find(a => a.id == name) == null) return 0; @@ -102,6 +104,7 @@ namespace Campofinale.Resource public static void Init() { Logger.Print("Loading TableCfg resources"); + // TODO: move all tables to the folder sceneAreaTable=JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SceneAreaTable.json")); strIdNumTable = JsonConvert.DeserializeObject(ReadJsonFile("TableCfg/StrIdNumTable.json")); characterTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/CharacterTable.json")); @@ -146,6 +149,8 @@ namespace Campofinale.Resource interactiveTable = JsonConvert.DeserializeObject(ReadJsonFile("Json/Interactive/InteractiveTable.json")); LoadInteractiveData(); LoadLevelDatas(); + LoadScriptsEvent(); + LoadSpawners(); ResourceLoader.LoadTableCfg(); if (missingResources) @@ -233,6 +238,43 @@ namespace Campofinale.Resource } } + public static void LoadScriptsEvent() + { + Logger.Print("Loading ScriptsEvents"); + string directoryPath = @"Json/ScriptEvents"; + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) + { + Dictionary events = JsonConvert.DeserializeObject>(ReadJsonFile(json)); + foreach(KeyValuePair e in events) + { + if (levelScriptsEvents.ContainsKey(e.Key)) + { + Logger.PrintWarn($"{e.Key} already added, skipping the one in {json}"); + } + else + { + levelScriptsEvents.Add(e.Key,e.Value); + } + + } + + } + Logger.Print($"Loaded {levelScriptsEvents.Count} ScriptsEvents"); + } + public static void LoadSpawners() + { + Logger.Print("Loading Spawners"); + string directoryPath = @"DynamicAssets\gamedata\spawnerconfig"; + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) + { + SpawnerConfig spawner = JsonConvert.DeserializeObject(ReadJsonFile(json)); + spawnerConfigs.Add(spawner); + + } + Logger.Print($"Loaded {spawnerConfigs.Count} Spawners"); + } public static void LoadLevelDatas() { Logger.Print("Loading LevelData resources"); @@ -512,8 +554,9 @@ namespace Campofinale.Resource public class LevelScriptData { public ulong scriptId; - public List properties; - public Dictionary propertyIdToKeyMap; + public List properties = new(); + public Dictionary propertyIdToKeyMap = new(); + public ScriptActionMap actionMap = new(); public int GetPropertyId(string key, List toExclude) @@ -527,6 +570,28 @@ namespace Campofinale.Resource } return 0; } + + public class ScriptActionMap + { + public ActionDataMap dataMap = new(); + + + public class ScriptHeader + { + public string _uid = ""; + + public EventKey _eventKey = new(); + + public class EventKey + { + public string constValue =""; + } + } + public class ActionDataMap + { + public List headerList = new(); + } + } } public class LevelFactoryRegionData { From e26138d1709f6b6133de87988ddd34edefea0ff0 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 30 May 2025 15:36:49 +0200 Subject: [PATCH 08/27] spawners, todo: saving levelscript states and properties --- Campofinale/Game/Entities/EntityMonster.cs | 3 +- Campofinale/Game/SceneManager.cs | 77 +++++++++---------- Campofinale/Game/Spawners/GameSpawner.cs | 67 ---------------- .../HandleCsSceneMonsterSpawnerBeginWave.cs | 24 ++++++ .../Cs/HandleCsSceneSetLevelScriptActive.cs | 12 +-- Campofinale/Resource/Dynamic/SpawnerConfig.cs | 10 ++- Campofinale/Resource/ResourceManager.cs | 8 ++ 7 files changed, 86 insertions(+), 115 deletions(-) delete mode 100644 Campofinale/Game/Spawners/GameSpawner.cs create mode 100644 Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index d9b6363..8494bb1 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -7,6 +7,7 @@ namespace Campofinale.Game.Entities public class EntityMonster : Entity { public string templateId; + public ulong originId; public EntityMonster() { @@ -83,7 +84,7 @@ namespace Campofinale.Game.Entities Type =(int) ObjectTypeIndex.Enemy, }, - + OriginId= originId, Attrs = { GetAttributes() diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index e81d4ef..e2de607 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -3,10 +3,14 @@ using Campofinale.Game.Inventory; using Campofinale.Game.Spawners; using Campofinale.Packets.Sc; using Campofinale.Resource; +using Campofinale.Resource.Dynamic; using MongoDB.Bson.Serialization.Attributes; +using System.Numerics; using System.Text.Json.Serialization; +using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; +using static System.Formats.Asn1.AsnWriter; namespace Campofinale.Game { @@ -256,8 +260,6 @@ namespace Campofinale.Game public bool alreadyLoaded = false; [BsonIgnore, JsonIgnore] public List activeScripts = new(); - [BsonIgnore, JsonIgnore] - public List gameSpawners = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -354,7 +356,7 @@ namespace Campofinale.Game lv_scene.levelData.npcs.ForEach(en => { - if (en.npcGroupId.Contains("chr") && sceneNumId== 99) return; + if (en.npcGroupId.Contains("chr")) return; EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { belongLevelScriptId = en.belongLevelScriptId, @@ -365,22 +367,7 @@ namespace Campofinale.Game entity.defaultHide = en.defaultHide; entities.Add(entity); }); - GetEntityExcludingChar().ForEach(e => - { - if(e is EntityInteractive) - { - // e.spawned = true; - // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); - } - - - }); - GetEntityExcludingChar().FindAll(e=> e is not EntityInteractive).ForEach(e => - { - - // e.spawned = true; - // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); - }); + UpdateShowEntities(); @@ -389,31 +376,13 @@ namespace Campofinale.Game public void SpawnEntity(Entity en,bool spawnedCheck=true) { - if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0) - { - return; - } - en.spawned = true; - ParamKeyValue targetList=en.properties.Find(p => p.key == "target_list"); - if(targetList!=null) - foreach (Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned == false && targetList.value.valueArray.Any(v=>v.valueBit64== (long)e.levelLogicId))) - { - SpawnEntity(e); - } + en.spawned = true; + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en })); } public void UpdateShowEntities() { - for (int i = 0; i < gameSpawners.Count; i++) - { - GameSpawner spawner = gameSpawners[i]; - if(spawner != null) - { - spawner.Update(GetOwner()); - } - } - List toSpawn = new(); foreach(Entity e in GetEntityExcludingChar()) { @@ -489,6 +458,34 @@ namespace Campofinale.Game } } - + public void SpawnWaveEnemy(ulong spawnerId, int waveId) + { + LevelSpawnerData data=info().levelData.spawners.Find(s => s.spawnerId == spawnerId); + if (data!=null) + { + SpawnerConfig config = spawnerConfigs.Find(s => s.configId == data.configId); + if (config != null) + { + foreach(var group in config.waveMap[$"{waveId}"].groupMap.Values) + { + foreach (var act in group.actionMap.Values) + { + EnemyLibraryData enemyData = config.enemyLibrary.Find(e=>e.key==act.libraryKey); + if (enemyData != null) + { + entities.Add(new EntityMonster(enemyData.enemyId, enemyData.enemyLevel, ownerId, act.position, act.rotation, sceneNumId) + { + + defaultHide = false, + spawned = false, + belongLevelScriptId = data.belongLevelScriptId + }); + } + + } + } + } + } + } } } diff --git a/Campofinale/Game/Spawners/GameSpawner.cs b/Campofinale/Game/Spawners/GameSpawner.cs deleted file mode 100644 index 0016bab..0000000 --- a/Campofinale/Game/Spawners/GameSpawner.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Campofinale.Game.Entities; -using Campofinale.Resource; -using Campofinale.Resource.Dynamic; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Campofinale.Game.Spawners -{ - public class GameSpawner - { - public Scene scene; - public int curWave = 1; - public int curGroup = 1; - public string configId; - public bool spawned; - - public SpawnerConfig GetConfig() - { - return ResourceManager.spawnerConfigs.Find(s => s.configId == configId); - } - public SpawnerConfig.WaveGroup GetCurrentWaveGroup() - { - return GetConfig().waveMap[$"{curWave}"].groupMap[$"{curGroup}"]; - } - public int GetEnemiesOfCurrentWave() - { - return scene.entities.FindAll(e => e.dependencyGroupId == GetCurrentWaveGroup().groupId).Count; - } - - public void Update(Player player) - { - if (spawned) - { - if (GetEnemiesOfCurrentWave() < 1) - { - if (GetConfig().waveMap.ContainsKey($"{curWave + 1}")) - { - curWave++; - spawned = false; - } - } - } - else - { - - foreach (var item in GetCurrentWaveGroup().actionMap.Values) - { - Logger.Print($"Debug: Spawning {item.libraryKey}"); - scene.entities.Add(new EntityMonster(item.libraryKey, 1, player.roleId, item.position, item.rotation, scene.sceneNumId) - { - dependencyGroupId = GetCurrentWaveGroup().groupId, - defaultHide = false, - spawned = false - }); - - - } - spawned = true; - - } - - } - } -} diff --git a/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs b/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs new file mode 100644 index 0000000..2c6f979 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs @@ -0,0 +1,24 @@ +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsSceneMonsterSpawnerBeginWave + { + + [Server.Handler(CsMsgId.CsSceneMonsterSpawnerBeginWave)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSceneMonsterSpawnerBeginWave req = packet.DecodeBody(); + session.sceneManager.GetCurScene().SpawnWaveEnemy(req.SpawnerId, req.WaveId); + session.Send(ScMsgId.ScSceneMonsterSpawnerBeginWave, new ScSceneMonsterSpawnerBeginWave() + { + SceneNumId=req.SceneNumId, + SpawnerId=req.SpawnerId, + WaveId=req.WaveId, + }); + + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 3e98a2f..5ae0b23 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -71,7 +71,7 @@ namespace Campofinale.Packets.Cs State = 4 }; - + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } @@ -122,11 +122,13 @@ namespace Campofinale.Packets.Cs break; case ScriptActionType.StartSpawner: - player.sceneManager.GetCurScene().gameSpawners.Add(new Game.Spawners.GameSpawner() + ScSceneMonsterSpawnerStart start = new() { - configId = action.valueStr[0], - scene= player.sceneManager.GetCurScene() - }); + SceneNumId = player.curSceneNumId, + SpawnerId = action.valueUlong[0], + + }; + player.Send(ScMsgId.ScSceneMonsterSpawnerStart,start); break; case ScriptActionType.AddCharacter: Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true); diff --git a/Campofinale/Resource/Dynamic/SpawnerConfig.cs b/Campofinale/Resource/Dynamic/SpawnerConfig.cs index d739539..1f2857b 100644 --- a/Campofinale/Resource/Dynamic/SpawnerConfig.cs +++ b/Campofinale/Resource/Dynamic/SpawnerConfig.cs @@ -12,11 +12,17 @@ namespace Campofinale.Resource.Dynamic { public string configId; public Dictionary waveMap = new(); + public List enemyLibrary = new(); - - + public SpawnerConfig() { } + public class EnemyLibraryData + { + public string key; + public string enemyId; + public int enemyLevel; + } public class SpawnerWave { public int waveId; diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 7a0c04b..cae533a 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -534,6 +534,7 @@ namespace Campofinale.Resource public List levelScripts = new(); public List worldWayPointSets = new(); public List factoryRegions = new(); + public List spawners = new(); public void Merge(LevelData other) { this.sceneId = other.sceneId; @@ -544,6 +545,7 @@ namespace Campofinale.Resource this.levelScripts.AddRange(other.levelScripts); this.worldWayPointSets.AddRange(other.worldWayPointSets); this.factoryRegions.AddRange(other.factoryRegions); + this.spawners.AddRange(other.spawners); } public class WorldWayPointSets @@ -551,6 +553,12 @@ namespace Campofinale.Resource public int id; public Dictionary pointIdToIndex = new(); } + public class LevelSpawnerData + { + public ulong spawnerId; + public string configId; + public ulong belongLevelScriptId; + } public class LevelScriptData { public ulong scriptId; From 864f4307c83f7a0e2dabd44d875fda92fa7221d5 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 30 May 2025 19:58:55 +0200 Subject: [PATCH 09/27] levelscript saving --- Campofinale/Game/MissionSys/MissionSystem.cs | 1 + Campofinale/Game/SceneManager.cs | 24 +++- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 52 ++++--- .../Packets/Sc/PacketScSelfSceneInfo.cs | 22 ++- Campofinale/Resource/ResourceManager.cs | 128 ++++++++++++++++++ 5 files changed, 203 insertions(+), 24 deletions(-) diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs index 914dd0e..8b9428d 100644 --- a/Campofinale/Game/MissionSys/MissionSystem.cs +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -30,6 +30,7 @@ namespace Campofinale.Game.MissionSys sync.TrackMissionId = curMission; missions.ForEach(m => { + if(!sync.Missions.ContainsKey(m.missionId)) sync.Missions.Add(m.missionId, new Mission() { MissionId = m.missionId, diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index e2de607..c85f309 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -1,6 +1,5 @@ using Campofinale.Game.Entities; using Campofinale.Game.Inventory; -using Campofinale.Game.Spawners; using Campofinale.Packets.Sc; using Campofinale.Resource; using Campofinale.Resource.Dynamic; @@ -10,6 +9,7 @@ using System.Text.Json.Serialization; using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; +using static Campofinale.Resource.ResourceManager.LevelScene.LevelData.ParamKeyValue; using static System.Formats.Asn1.AsnWriter; namespace Campofinale.Game @@ -247,7 +247,12 @@ namespace Campofinale.Game } } } - + public class LevelScript + { + public ulong scriptId; + public int state; + public Dictionary properties = new(); + } public class Scene { public ulong ownerId; @@ -260,6 +265,7 @@ namespace Campofinale.Game public bool alreadyLoaded = false; [BsonIgnore, JsonIgnore] public List activeScripts = new(); + public List scripts = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -381,12 +387,24 @@ namespace Campofinale.Game GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en })); } + public bool GetActiveScript(ulong id) + { + LevelScript script = scripts.Find(s => s.scriptId == id); + if (script != null) + { + return script.state > 2; + } + else + { + return true; + } + } public void UpdateShowEntities() { List toSpawn = new(); foreach(Entity e in GetEntityExcludingChar()) { - if(e.spawned==false && (activeScripts.Contains(e.belongLevelScriptId) || e.belongLevelScriptId==0)) + if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { if (!e.defaultHide) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 5ae0b23..5b151f7 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -18,21 +18,27 @@ namespace Campofinale.Packets.Cs CsSceneSetLevelScriptActive req = packet.DecodeBody(); if (req.IsActive) { - - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, + sceneScript.state = 3; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, - State = 3 - }; + State = sceneScript.state + }; - if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) - { - session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); - session.sceneManager.GetCurScene().UpdateShowEntities(); + if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) + { + session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); + session.sceneManager.GetCurScene().UpdateShowEntities(); + } + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } @@ -64,15 +70,21 @@ namespace Campofinale.Packets.Cs if (req.IsStart) { - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, + sceneScript.state = 4; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, - State = 4 - }; + State = sceneScript.state + }; + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } @@ -239,10 +251,14 @@ namespace Campofinale.Packets.Cs }; LevelScriptData levelscript= ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.Find(l=>l.scriptId == req.ScriptId); - if (levelscript != null) { + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + + if (levelscript != null && sceneScript != null) { foreach (var item in req.Properties) { int key = levelscript.GetPropertyId(item.Key, new List()); + + sceneScript.properties[item.Key] = new ScriptProperty(item.Value); update1.Properties.Add(key, item.Value); } } diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index 9b9abc0..3e21a2a 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -70,13 +70,29 @@ namespace Campofinale.Packets.Sc State = 2, }; + var sceneScript=session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == l.scriptId); + if (sceneScript == null) + { + sceneScript = new() + { + scriptId = l.scriptId, + + state = 2 + }; + l.properties.ForEach(p => + { + sceneScript.properties.Add(p.key,p.ToScriptProperty()); + }); + + session.sceneManager.GetCurScene().scripts.Add(sceneScript); + } int i = 0; - foreach (var item in l.properties) + foreach (var item in sceneScript.properties) { - DynamicParameter p=item.ToProto(); + DynamicParameter p=item.Value.ToProto(); if (p != null) - script.Properties.Add(l.GetPropertyId(item.key,script.Properties.Keys.ToList()), p); + script.Properties.Add(l.GetPropertyId(item.Key,script.Properties.Keys.ToList()), p); } sceneInfo.LevelScripts.Add(script); }); diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index cae533a..97c924e 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -663,6 +663,42 @@ namespace Campofinale.Resource public List properties; public Dictionary> componentProperties = new(); } + public class ScriptProperty + { + public int RealType; + public int ValueType; + public List ValueStringList = new(); + public List ValueFloatList = new(); + public List ValueIntList = new(); + public List ValueBoolList = new(); + + public ScriptProperty() + { + + } + public ScriptProperty(DynamicParameter p) + { + this.RealType = p.RealType; + this.ValueType = p.ValueType; + this.ValueBoolList.AddRange(p.ValueBoolList.ToList()); + this.ValueFloatList.AddRange(p.ValueFloatList.ToList()); + this.ValueIntList.AddRange(p.ValueIntList.ToList()); + this.ValueStringList.AddRange(p.ValueStringList.ToList()); + } + public DynamicParameter ToProto() + { + return new DynamicParameter() + { + RealType = RealType, + ValueType = ValueType, + ValueStringList = { ValueStringList }, + ValueBoolList = { ValueBoolList }, + ValueFloatList = { ValueFloatList }, + ValueIntList = { ValueIntList }, + + }; + } + } public class ParamKeyValue { public string key; @@ -752,6 +788,98 @@ namespace Campofinale.Resource return param; } + + public ScriptProperty ToScriptProperty() + { + ScriptProperty param = new() + { + RealType = (int)value.type, + ValueType = (int)value.type, + + }; + foreach (var val in value.valueArray) + { + switch (value.type) + { + case ParamRealType.LangKey: + param.ValueStringList.Add(val.valueString); + param.ValueType = (int)ParamValueType.String; + break; + case ParamRealType.LangKeyList: + param.ValueStringList.Add(val.valueString); + param.ValueType = (int)ParamValueType.StringList; + break; + case ParamRealType.String: + param.ValueStringList.Add(val.valueString); + param.ValueType = (int)ParamValueType.String; + break; + case ParamRealType.StringList: + param.ValueStringList.Add(val.valueString); + param.ValueType = (int)ParamValueType.StringList; + break; + case ParamRealType.Vector3: + param.ValueFloatList.Add(val.ToFloat()); + param.ValueType = (int)ParamValueType.FloatList; + break; + case ParamRealType.Float: + param.ValueFloatList.Add(val.ToFloat()); + param.ValueType = (int)ParamValueType.Float; + break; + case ParamRealType.FloatList: + param.ValueFloatList.Add(val.ToFloat()); + param.ValueType = (int)ParamValueType.FloatList; + break; + case ParamRealType.Int: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; + case ParamRealType.IntList: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.IntList; + break; + case ParamRealType.Bool: + param.ValueBoolList.Add(val.valueBit64 == 1); + param.ValueType = (int)ParamValueType.Bool; + break; + case ParamRealType.Vector3List: + param.ValueFloatList.Add(val.ToFloat()); + param.ValueType = (int)ParamValueType.FloatList; + break; + case ParamRealType.BoolList: + param.ValueBoolList.Add(val.valueBit64 == 1); + param.ValueType = (int)ParamValueType.BoolList; + break; + case ParamRealType.EntityPtr: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; + case ParamRealType.EntityPtrList: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; + case ParamRealType.UInt64: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; + case ParamRealType.WaterVolumePtr: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; + default: + return null; + break; + } + } + + return param; + } + public void Update(DynamicParameter value) + { + foreach (var item in value.ValueBoolList) + { + + } + } public class ParamValue { From 723b81d5e463882653dbcf7caa3318624542649d Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 4 Jun 2025 14:31:56 +0200 Subject: [PATCH 10/27] some fix --- Campofinale/Game/SceneManager.cs | 35 ++++++++++++------- Campofinale/NotifyManager.cs | 24 ++++++++----- .../Packets/Cs/HandleCsSceneLoadFinish.cs | 6 +--- .../Packets/Cs/HandleCsSceneMoveStateSet.cs | 1 - .../Packets/Cs/HandleCsSceneTeleport.cs | 9 +++++ .../Packets/Sc/PacketScSelfSceneInfo.cs | 11 ++++-- Campofinale/Player.cs | 6 ++-- 7 files changed, 58 insertions(+), 34 deletions(-) diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index c85f309..318a4c7 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -265,6 +265,7 @@ namespace Campofinale.Game public bool alreadyLoaded = false; [BsonIgnore, JsonIgnore] public List activeScripts = new(); + public List scripts = new(); public int GetCollection(string id) { @@ -294,7 +295,7 @@ namespace Campofinale.Game public void Unload() { List guids = new(); - foreach(Entity e in entities) + foreach(Entity e in GetEntityExcludingChar().FindAll(e => e.spawned)) { guids.Add(e.guid); } @@ -307,8 +308,6 @@ namespace Campofinale.Game } public void Load() { - if (info().isSeamless && alreadyLoaded) return; - //alreadyLoaded = true; Unload(); LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); @@ -362,7 +361,7 @@ namespace Campofinale.Game lv_scene.levelData.npcs.ForEach(en => { - if (en.npcGroupId.Contains("chr")) return; + if (en.npcGroupId.Contains("chr") && sceneNumId == 98) return; EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { belongLevelScriptId = en.belongLevelScriptId, @@ -373,11 +372,11 @@ namespace Campofinale.Game entity.defaultHide = en.defaultHide; entities.Add(entity); }); - - - UpdateShowEntities(); - + + + + UpdateShowEntities(); } public void SpawnEntity(Entity en,bool spawnedCheck=true) @@ -399,10 +398,12 @@ namespace Campofinale.Game return true; } } - public void UpdateShowEntities() + //Bug on scene 101: spawning entities in this way make the game break if you try to load another scene from scene 101 + public async void UpdateShowEntities() { + List toSpawn = new(); - foreach(Entity e in GetEntityExcludingChar()) + foreach(Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned==false)) { if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { @@ -415,9 +416,17 @@ namespace Campofinale.Game } } - if(toSpawn.Count > 0) - GetOwner().Send(new PacketScObjectEnterView(GetOwner(), toSpawn)); - + if (toSpawn.Count > 0) + { + for (int i = 0; i < toSpawn.Count; i += 5) + { + int chunkSize = Math.Min(5, toSpawn.Count - i); + var chunk = toSpawn.GetRange(i, chunkSize); + + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), chunk)); + } + } + /* foreach(Entity en in GetEntityExcludingChar()) { float minDis = 100; diff --git a/Campofinale/NotifyManager.cs b/Campofinale/NotifyManager.cs index ea93f05..657acc8 100644 --- a/Campofinale/NotifyManager.cs +++ b/Campofinale/NotifyManager.cs @@ -47,17 +47,23 @@ s_notifyReqGroup = handlers.ToImmutable(); } - public static void Notify(Player session, CsMsgId cmdId, Network.Packet packet) + public static async void Notify(Player session, CsMsgId cmdId, Network.Packet packet) { - if (s_notifyReqGroup.TryGetValue(cmdId, out var handler)) + await Task.Run(() => { - handler.Item2.Invoke(session, ((int)cmdId), packet); - } - else - { - if (!Server.csMessageToHide.Contains(cmdId) && Server.config.logOptions.packets) - Logger.PrintWarn($"Can't find handler for {(Enum.GetName(typeof(CsMsgId), cmdId)).ToString().Pastel(Color.FromArgb(165, 229, 250))} ({(cmdId).ToString().Pastel(Color.FromArgb(165, 229, 250))})"); - } + + if (s_notifyReqGroup.TryGetValue(cmdId, out var handler)) + { + + handler.Item2.Invoke(session, ((int)cmdId), packet); + } + else + { + if (!Server.csMessageToHide.Contains(cmdId) && Server.config.logOptions.packets) + Logger.PrintWarn($"Can't find handler for {(Enum.GetName(typeof(CsMsgId), cmdId)).ToString().Pastel(Color.FromArgb(165, 229, 250))} ({(cmdId).ToString().Pastel(Color.FromArgb(165, 229, 250))})"); + } + }); + } public static void AddReqGroupHandler(Type type) diff --git a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs index 55c7904..c392d95 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs @@ -18,11 +18,7 @@ namespace Campofinale.Packets.Cs session.sceneManager.LoadCurrentTeamEntities(); session.sceneManager.LoadCurrent(); session.LoadFinish = true; - session.Send(ScMsgId.ScSceneClientIdInfo, new ScSceneClientIdInfo() - { - RoleIdx = (uint)session.roleId, - LastMaxIdx = session.random.usedGuids.Max() - }); + if (session.curSceneNumId == 98) { session.Send(new PacketScSyncGameMode(session, "spaceship")); diff --git a/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs b/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs index fde66ad..21c3f0c 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs @@ -10,7 +10,6 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneMoveStateSet req = packet.DecodeBody(); - //req. } diff --git a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs index 086b3c0..06a9ded 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs @@ -14,6 +14,15 @@ namespace Campofinale.Packets.Cs if (session.curSceneNumId != req.SceneNumId) { session.EnterScene(req.SceneNumId, new Resource.ResourceManager.Vector3f(req.Position), new Resource.ResourceManager.Vector3f(req.Rotation)); + /* ScSceneTeleport t = new() + { + TeleportReason = req.TeleportReason, + PassThroughData = req.PassThroughData, + Position = req.Position, + Rotation = req.Rotation, + SceneNumId = req.SceneNumId, + }; + session.Send(ScMsgId.ScSceneTeleport, t);*/ } else { diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index 3e21a2a..9f33e37 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -81,18 +81,23 @@ namespace Campofinale.Packets.Sc }; l.properties.ForEach(p => { + if(!sceneScript.properties.ContainsKey(p.key)) sceneScript.properties.Add(p.key,p.ToScriptProperty()); }); session.sceneManager.GetCurScene().scripts.Add(sceneScript); } + script.State = sceneScript.state; int i = 0; foreach (var item in sceneScript.properties) { + if(item.Value != null) + { + DynamicParameter p = item.Value.ToProto(); + if (p != null) + script.Properties.Add(l.GetPropertyId(item.Key, script.Properties.Keys.ToList()), p); + } - DynamicParameter p=item.Value.ToProto(); - if (p != null) - script.Properties.Add(l.GetPropertyId(item.Key,script.Properties.Keys.ToList()), p); } sceneInfo.LevelScripts.Add(script); }); diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 65de5b5..18a6f1a 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -436,7 +436,7 @@ namespace Campofinale { Send(Packet.EncodePacket((int)id, mes, seq, totalPackCount, currentPackIndex)); } - public void Send(Packet packet) + public async void Send(Packet packet) { byte[] datas = packet.set_body.ToByteArray(); int maxChunkSize = 65535; @@ -463,11 +463,11 @@ namespace Campofinale Send(Packet.EncodePacket(packet.cmdId, data, seqNext, (uint)chunks.Count, (uint)i)); } } - public void Send(byte[] data) + public async void Send(byte[] data) { try { - socket.Send(data); + await socket.SendAsync(data); } catch (Exception e) { From c00d7cf0d74ca871f36093780a9034dabea0003f Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Mon, 9 Jun 2025 16:04:19 +0200 Subject: [PATCH 11/27] os android cbt --- Campofinale/Game/SceneManager.cs | 3 --- Campofinale/Http/Dispatch.cs | 27 ++++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 318a4c7..c90de27 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -4,13 +4,10 @@ using Campofinale.Packets.Sc; using Campofinale.Resource; using Campofinale.Resource.Dynamic; using MongoDB.Bson.Serialization.Attributes; -using System.Numerics; using System.Text.Json.Serialization; using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; -using static Campofinale.Resource.ResourceManager.LevelScene.LevelData.ParamKeyValue; -using static System.Formats.Asn1.AsnWriter; namespace Campofinale.Game { diff --git a/Campofinale/Http/Dispatch.cs b/Campofinale/Http/Dispatch.cs index 9d2e621..4a495a7 100644 --- a/Campofinale/Http/Dispatch.cs +++ b/Campofinale/Http/Dispatch.cs @@ -241,7 +241,32 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } - + //ANDROID + [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/remote_config/get_remote_config/1003/prod-cbt/default/Android/res_version")] + public static async Task os_android_res_version(HttpContext ctx) + { + + string resp = "{\"version\": \"2413221-312\", \"kickFlag\": false}"; + + + ctx.Response.StatusCode = 200; + //ctx.Response.ContentLength = resp.Length; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } + [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/remote_config/get_remote_config/1003/prod-cbt/default/Android/game_config")] + public static async Task game_config_os_android(HttpContext ctx) + { + string resp = "{\"mockLogin\": false, \"selectSrv\": false, \"enableHotUpdate\": true, \"enableNpcOptimize\": false, \"enableEntitySpawnLog\": false, \"enableCBT2AccessForbidden\": false, \"enableMobileFullScreenWaterMark\": false}"; + + ctx.Response.StatusCode = 200; + ctx.Response.ContentLength = resp.Length; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } + public static async Task data(HttpContext ctx) { string fileId = ctx.Request.Url.Elements.LastOrDefault(); From 5e68f54c48034f829dde10938e7dfaf8c72dd1e5 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Tue, 10 Jun 2025 21:14:38 +0200 Subject: [PATCH 12/27] real enemy drops, improved code etc, i dont remember everything i made LOL --- Campofinale/Game/Entities/Entity.cs | 5 ++ Campofinale/Game/Entities/EntityMonster.cs | 19 ++++++ Campofinale/Game/Inventory/Item.cs | 3 +- Campofinale/Game/MissionSys/GameMission.cs | 25 ++++++++ Campofinale/Game/MissionSys/GameQuest.cs | 24 +++++++ Campofinale/Game/MissionSys/MissionSystem.cs | 31 +--------- Campofinale/Game/SceneManager.cs | 58 ++++++++--------- Campofinale/Http/Dispatch.cs | 14 ++++- .../Cs/HandleCsSceneSetLastSafeZone.cs | 4 +- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 38 +++++++++--- Campofinale/Player.cs | 6 +- Campofinale/Resource/GameEnums.cs | 10 ++- Campofinale/Resource/ResourceManager.cs | 62 ++++++++++++------- .../Resource/Table/WikiEnemyDropTable.cs | 8 +++ 14 files changed, 206 insertions(+), 101 deletions(-) create mode 100644 Campofinale/Game/MissionSys/GameMission.cs create mode 100644 Campofinale/Game/MissionSys/GameQuest.cs create mode 100644 Campofinale/Resource/Table/WikiEnemyDropTable.cs diff --git a/Campofinale/Game/Entities/Entity.cs b/Campofinale/Game/Entities/Entity.cs index 264e3f1..df9363a 100644 --- a/Campofinale/Game/Entities/Entity.cs +++ b/Campofinale/Game/Entities/Entity.cs @@ -1,4 +1,5 @@ using Campofinale.Resource; +using System.Threading; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; @@ -41,6 +42,10 @@ namespace Campofinale.Game.Entities public virtual void Heal(double heal) { + } + public virtual void OnDie() + { + } public virtual bool Interact(string eventName, Google.Protobuf.Collections.MapField properties) { diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index 8494bb1..08cdc94 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -1,5 +1,7 @@ using Campofinale.Protocol; using Campofinale.Resource; +using Campofinale.Resource.Table; +using System.Threading; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Entities @@ -97,6 +99,23 @@ namespace Campofinale.Game.Entities }; return proto; } + public override void OnDie() + { + if (!wikiEnemyDropTable.ContainsKey(templateId)) return; + WikiEnemyDropTable table = wikiEnemyDropTable[templateId]; + if (table!=null) + { + table.dropItemIds.ForEach(id => + { + GetOwner().sceneManager.CreateDrop(Position, new RewardTable.ItemBundle() + { + id = id, + count = 1 + }); + }); + } + + } public override void Damage(double dmg) { curHp -= dmg; diff --git a/Campofinale/Game/Inventory/Item.cs b/Campofinale/Game/Inventory/Item.cs index d887947..a35230a 100644 --- a/Campofinale/Game/Inventory/Item.cs +++ b/Campofinale/Game/Inventory/Item.cs @@ -11,6 +11,7 @@ using static Campofinale.Resource.ResourceManager; using Google.Protobuf.Collections; using Campofinale.Packets.Sc; using Campofinale.Protocol; +using CsvHelper.Configuration.Attributes; namespace Campofinale.Game.Inventory { @@ -101,7 +102,7 @@ namespace Campofinale.Game.Inventory GemId = guid, TemplateId= ResourceManager.GetItemTemplateId(id), WeaponId= GetOwner().inventoryManager.items.Find(i=>i.attachGemId==guid)!=null ? GetOwner().inventoryManager.items.Find(i => i.attachGemId == guid).guid: 0, - + }, IsLock = locked } diff --git a/Campofinale/Game/MissionSys/GameMission.cs b/Campofinale/Game/MissionSys/GameMission.cs new file mode 100644 index 0000000..ddc1837 --- /dev/null +++ b/Campofinale/Game/MissionSys/GameMission.cs @@ -0,0 +1,25 @@ +using Campofinale.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.MissionSys +{ + public class GameMission + { + public string missionId; + public MissionState state; + + public GameMission() + { + + } + public GameMission(string id, MissionState state = MissionState.Available) + { + missionId = id; + this.state = state; + } + } +} diff --git a/Campofinale/Game/MissionSys/GameQuest.cs b/Campofinale/Game/MissionSys/GameQuest.cs new file mode 100644 index 0000000..7137bf6 --- /dev/null +++ b/Campofinale/Game/MissionSys/GameQuest.cs @@ -0,0 +1,24 @@ +using Campofinale.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.MissionSys +{ + public class GameQuest + { + public string questId; + public QuestState state; + public GameQuest() + { + + } + public GameQuest(string id, QuestState state = QuestState.Available) + { + questId = id; + this.state = state; + } + } +} diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs index 8b9428d..70f24cb 100644 --- a/Campofinale/Game/MissionSys/MissionSystem.cs +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -266,33 +266,6 @@ namespace Campofinale.Game.MissionSys } } } - public class GameQuest - { - public string questId; - public QuestState state; - public GameQuest() - { - - } - public GameQuest(string id, QuestState state = QuestState.Available) - { - questId = id; - this.state = state; - } - } - public class GameMission - { - public string missionId; - public MissionState state; - - public GameMission() - { - - } - public GameMission(string id, MissionState state = MissionState.Available) - { - missionId = id; - this.state = state; - } - } + + } diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index c90de27..35a1ada 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -90,43 +90,40 @@ namespace Campofinale.Game if (scene != null) { - if(GetEntity(guid) is EntityMonster) + Entity entity = GetEntity(guid); + if (entity != null) { - EntityMonster monster = (EntityMonster)GetEntity(guid); - CreateDrop(monster.Position, new RewardTable.ItemBundle() + entity.OnDie(); + if (killClient) { - id = "item_gem_rarity_3", - count=1 - }); - LevelScene lv_scene = ResourceManager.GetLevelData(GetEntity(guid).sceneNumId); - LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid); - if (d != null) - { - if (!d.respawnable) + ScSceneDestroyEntity destroy = new() { - player.noSpawnAnymore.Add(monster.guid); + Id = guid, + Reason = reason, + SceneNumId = GetEntity(guid).sceneNumId, + }; + player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy); + + } + if (entity is EntityMonster monster) + { + LevelScene lv_scene = ResourceManager.GetLevelData(entity.sceneNumId); + LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid); + if (d != null) + { + if (!d.respawnable) + { + player.noSpawnAnymore.Add(monster.guid); + } } } - } - if (killClient) - { - ScSceneDestroyEntity destroy = new() + if (scenes.Find(s => s.sceneNumId == entity.sceneNumId) != null) { - Id = guid, - Reason = reason, - SceneNumId = GetEntity(guid).sceneNumId, - }; - player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy); - } - if (GetEntity(guid) != null) - { - if(scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId) != null) - { - scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId).entities.Remove(GetEntity(guid)); + scenes.Find(s => s.sceneNumId == entity.sceneNumId).entities.Remove(entity); } + } - } } public void CreateDrop(Vector3f pos,ResourceManager.RewardTable.ItemBundle bundle) @@ -400,8 +397,11 @@ namespace Campofinale.Game { List toSpawn = new(); - foreach(Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned==false)) + List toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false); + toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position))); + foreach (Entity e in toCheck) { + if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { if (!e.defaultHide) diff --git a/Campofinale/Http/Dispatch.cs b/Campofinale/Http/Dispatch.cs index 4a495a7..24d56be 100644 --- a/Campofinale/Http/Dispatch.cs +++ b/Campofinale/Http/Dispatch.cs @@ -122,7 +122,19 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } - + [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/remote_config/get_remote_config/1003/prod-cbt/default/Windows/res_version")] + public static async Task os_windows_res_version(HttpContext ctx) + { + + string resp = "{\"version\": \"2089329-32\", \"kickFlag\": true}"; + + + ctx.Response.StatusCode = 200; + //ctx.Response.ContentLength = resp.Length; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/gameBulletin/version")] public static async Task Version(HttpContext ctx) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs index 2095ed7..30c39d0 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs @@ -10,9 +10,7 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLastSafeZone req = packet.DecodeBody(); - - - + } } diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 5b151f7..73ed6b9 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -44,20 +44,21 @@ namespace Campofinale.Packets.Cs } else { - /* ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, + sceneScript.state = 2; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, - State = 3 - }; + State = sceneScript.state + }; - if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) - { - session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); session.sceneManager.GetCurScene().UpdateShowEntities(); + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp);*/ } @@ -84,7 +85,24 @@ namespace Campofinale.Packets.Cs session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - + + } + else + { + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) + { + sceneScript.state = 3; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = sceneScript.state + }; + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } } diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 18a6f1a..4659602 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -81,8 +81,8 @@ namespace Campofinale //Data public string accountId = ""; public string nickname = "Endministrator"; - public ulong roleId= 1; - public Gender gender=Gender.GenFemale; + public ulong roleId = 1; + public Gender gender = Gender.GenFemale; public uint level = 20; public uint xp = 0; // @@ -99,7 +99,7 @@ namespace Campofinale public FactoryManager factoryManager; public MissionSystem missionSystem; public int teamIndex = 0; - public List teams= new List(); + public List teams = new List(); public List mails = new List(); public List unlockedSystems = new(); public List noSpawnAnymore = new(); diff --git a/Campofinale/Resource/GameEnums.cs b/Campofinale/Resource/GameEnums.cs index f53c5f5..e74b912 100644 --- a/Campofinale/Resource/GameEnums.cs +++ b/Campofinale/Resource/GameEnums.cs @@ -1,6 +1,6 @@ namespace Campofinale.Resource { - public enum MissionState : int// TypeDefIndex: 33630 + public enum MissionState { None = 0, Available = 1, @@ -17,6 +17,14 @@ Completed = 3, Failed = 4, } + public enum LevelScriptState + { + None = 0, + Disabled = 1, + Enabled = 2, + Active = 3, + Running = 4 + } public enum InteractiveComponentType { TriggerObserver = 0, diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 97c924e..63ec522 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -54,6 +54,7 @@ namespace Campofinale.Resource public static Dictionary gachaWeaponPoolTable = new(); // public static Dictionary enemyTable = new(); + public static Dictionary wikiEnemyDropTable = new(); public static Dictionary equipTable = new(); public static Dictionary equipSuitTable = new(); public static Dictionary spaceShipCharBehaviourTable = new(); @@ -107,7 +108,6 @@ namespace Campofinale.Resource // TODO: move all tables to the folder sceneAreaTable=JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SceneAreaTable.json")); strIdNumTable = JsonConvert.DeserializeObject(ReadJsonFile("TableCfg/StrIdNumTable.json")); - characterTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/CharacterTable.json")); systemJumpTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SystemJumpTable.json")); settlementBasicDataTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SettlementBasicDataTable.json")); blocMissionTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/BlocMissionTable.json")); @@ -138,15 +138,12 @@ namespace Campofinale.Resource spaceshipRoomInsTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SpaceshipRoomInsTable.json")); dungeonTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/DungeonTable.json")); equipSuitTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/EquipSuitTable.json")); - levelGradeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/LevelGradeTable.json")); levelShortIdTable = JsonConvert.DeserializeObject>(ReadJsonFile("DynamicAssets/gamedata/gameplayconfig/jsoncfg/LevelShortIdTable.json")); rewardTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/RewardTable.json")); adventureTaskTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/AdventureTaskTable.json")); factoryBuildingTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FactoryBuildingTable.json")); facSTTNodeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FacSTTNodeTable.json")); facSTTLayerTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FacSTTLayerTable.json")); - itemTypeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/ItemTypeTable.json")); - interactiveTable = JsonConvert.DeserializeObject(ReadJsonFile("Json/Interactive/InteractiveTable.json")); LoadInteractiveData(); LoadLevelDatas(); LoadScriptsEvent(); @@ -155,7 +152,7 @@ namespace Campofinale.Resource if (missingResources) { - Logger.PrintWarn("Missing some resources. The gameserver will probably crash."); + Logger.PrintWarn("Some Resources are Missing. The Game server may not work properly."); } } public static List GetAllShortIds() @@ -242,38 +239,55 @@ namespace Campofinale.Resource { Logger.Print("Loading ScriptsEvents"); string directoryPath = @"Json/ScriptEvents"; - string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); - foreach (string json in jsonFiles) + try { - Dictionary events = JsonConvert.DeserializeObject>(ReadJsonFile(json)); - foreach(KeyValuePair e in events) + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) { - if (levelScriptsEvents.ContainsKey(e.Key)) + Dictionary events = JsonConvert.DeserializeObject>(ReadJsonFile(json)); + foreach (KeyValuePair e in events) { - Logger.PrintWarn($"{e.Key} already added, skipping the one in {json}"); + if (levelScriptsEvents.ContainsKey(e.Key)) + { + Logger.PrintWarn($"{e.Key} already added, skipping the one in {json}"); + } + else + { + levelScriptsEvents.Add(e.Key, e.Value); + } + } - else - { - levelScriptsEvents.Add(e.Key,e.Value); - } - + } - + Logger.Print($"Loaded {levelScriptsEvents.Count} ScriptsEvents"); } - Logger.Print($"Loaded {levelScriptsEvents.Count} ScriptsEvents"); + catch (Exception e) + { + Logger.PrintWarn($"No ScriptsEvents folder found in Json."); + } + + } public static void LoadSpawners() { Logger.Print("Loading Spawners"); string directoryPath = @"DynamicAssets\gamedata\spawnerconfig"; - string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); - foreach (string json in jsonFiles) + try { - SpawnerConfig spawner = JsonConvert.DeserializeObject(ReadJsonFile(json)); - spawnerConfigs.Add(spawner); + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) + { + SpawnerConfig spawner = JsonConvert.DeserializeObject(ReadJsonFile(json)); + spawnerConfigs.Add(spawner); + } + Logger.Print($"Loaded {spawnerConfigs.Count} Spawners"); } - Logger.Print($"Loaded {spawnerConfigs.Count} Spawners"); + catch (Exception e) + { + Logger.PrintError($"Error occured when loading SpawnerConfigs: " + e.Message); + } + } public static void LoadLevelDatas() { @@ -302,7 +316,7 @@ namespace Campofinale.Resource catch (Exception ex) { //Logger.PrintError(ex.Message); - Logger.PrintWarn("Missing levelData natural spawns file for scene " + data.mapIdStr + " path: " + path); + Logger.PrintWarn("Missing LevelData natural spawns file for scene " + data.mapIdStr + " path: " + path); } } diff --git a/Campofinale/Resource/Table/WikiEnemyDropTable.cs b/Campofinale/Resource/Table/WikiEnemyDropTable.cs new file mode 100644 index 0000000..6402dc5 --- /dev/null +++ b/Campofinale/Resource/Table/WikiEnemyDropTable.cs @@ -0,0 +1,8 @@ +namespace Campofinale.Resource.Table +{ + [TableCfgType("TableCfg/WikiEnemyDropTable.json", LoadPriority.LOW)] + public class WikiEnemyDropTable + { + public List dropItemIds = new(); + } +} From 80f0d161549431612fd752127c0c15820a5fd846 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Thu, 12 Jun 2025 20:27:36 +0200 Subject: [PATCH 13/27] bug fix --- Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs | 1 + Campofinale/Resource/Json/LevelScriptEvent.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 73ed6b9..76ff9e7 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -144,6 +144,7 @@ namespace Campofinale.Packets.Cs break; case ScriptActionType.AddMission: player.missionSystem.AddMission(action.valueStr[0],MissionState.Processing,true); + if(action.valueUlong !=null) if(action.valueUlong.Length > 0) { diff --git a/Campofinale/Resource/Json/LevelScriptEvent.cs b/Campofinale/Resource/Json/LevelScriptEvent.cs index ef6832c..ff628c8 100644 --- a/Campofinale/Resource/Json/LevelScriptEvent.cs +++ b/Campofinale/Resource/Json/LevelScriptEvent.cs @@ -15,8 +15,8 @@ namespace Campofinale.Resource.Json public class ScriptAction { public ScriptActionType action; - public string[] valueStr; - public ulong[] valueUlong; + public string[] valueStr = new string[0]; + public ulong[] valueUlong = new ulong[0]; } public enum ScriptActionType { From 3fbe2b6fc11a584a85351834ac05b1e4ac055e40 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 18 Jun 2025 12:26:36 +0200 Subject: [PATCH 14/27] added disableLevelscripts on config file --- Campofinale/ConfigFile.cs | 4 ++++ Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Campofinale/ConfigFile.cs b/Campofinale/ConfigFile.cs index f1eef43..ff11295 100644 --- a/Campofinale/ConfigFile.cs +++ b/Campofinale/ConfigFile.cs @@ -18,6 +18,10 @@ public bool missionsEnabled = false; public bool giveAllItems = false; /// + /// Bug: on mobile some scenes doesn't want to load fine + /// + public bool disableLevelscripts = true; + /// /// Not yet implemented /// public bool useEncryption = false; diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index 9f33e37..a07c902 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -87,7 +87,15 @@ namespace Campofinale.Packets.Sc session.sceneManager.GetCurScene().scripts.Add(sceneScript); } - script.State = sceneScript.state; + if (Server.config.serverOptions.disableLevelscripts) + { + script.State = 1; + } + else + { + script.State = sceneScript.state; + } + int i = 0; foreach (var item in sceneScript.properties) { From 623f7a111c63de9208b2263c7e1bab2e0b61e57b Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 9 Jul 2025 19:35:51 +0200 Subject: [PATCH 15/27] planning to add option to use external sdk for login --- Campofinale/ConfigFile.cs | 14 ++------------ Campofinale/Database/Database.cs | 5 +++++ Campofinale/Http/SDK.cs | 22 +++------------------- Campofinale/Packets/Cs/HandleCsLogin.cs | 10 ++++++++++ 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/Campofinale/ConfigFile.cs b/Campofinale/ConfigFile.cs index ff11295..99887b7 100644 --- a/Campofinale/ConfigFile.cs +++ b/Campofinale/ConfigFile.cs @@ -25,22 +25,10 @@ /// Not yet implemented /// public bool useEncryption = false; - //public CharactersOptions defaultCharacters = new(); public ServerOptions() { } - /*public class CharactersOptions - { - public int defaultLevel = 1; - public bool giveAllCharacters = true; - public List characters = new List(); //used if giveAllCharacters is false - - public CharactersOptions() { } - }*/ - /* public struct WelcomeMail - { - }*/ } public class LogSettings { @@ -59,6 +47,8 @@ public int bindPort = 30000; public string accessAddress = "127.0.0.1"; public int accessPort = 30000; + public bool useExternalAuthSdk = false; + public string externalAuthSdkUrl = ""; public GameserverSettings() { } diff --git a/Campofinale/Database/Database.cs b/Campofinale/Database/Database.cs index 5b591a6..84af0ee 100644 --- a/Campofinale/Database/Database.cs +++ b/Campofinale/Database/Database.cs @@ -362,6 +362,11 @@ namespace Campofinale.Database } public Account GetAccountByTokenGrant(string token) { + if (Server.config.gameServer.useExternalAuthSdk) + { + //TODO get account info from external auth sdk + return null; + } try { return _database.GetCollection("accounts").Find(p => p.grantToken == token).ToList().FirstOrDefault(); diff --git a/Campofinale/Http/SDK.cs b/Campofinale/Http/SDK.cs index f6261a4..c097c30 100644 --- a/Campofinale/Http/SDK.cs +++ b/Campofinale/Http/SDK.cs @@ -14,10 +14,7 @@ namespace Campofinale.Http string requestBody = ctx.Request.DataAsString; Console.WriteLine(requestBody); string resp = "{}"; - - ctx.Response.StatusCode = 200; - //ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); @@ -42,7 +39,6 @@ namespace Campofinale.Http } ctx.Response.StatusCode = 200; - //ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); @@ -66,7 +62,6 @@ namespace Campofinale.Http } ctx.Response.StatusCode = 200; - //ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); @@ -87,7 +82,7 @@ namespace Campofinale.Http if (account != null) { /* - * {"data":{"hgId":"1326618825955","phone":"153****5243","email":null,"identityNum":"5002**********1619","identityName":"金*","isMinor":false,"isLatestUserAgreement":true},"msg":"OK","status":0,"type":"A"} + * {"data":{"hgId":"**********","phone":"153****5243","email":null,"identityNum":"5002**********1619","identityName":"金*","isMinor":false,"isLatestUserAgreement":true},"msg":"OK","status":0,"type":"A"} */ resp = "{\"data\":{\"phone\":\"153****5243\", \"identityNum\": \"5002**********1619\",\"identityName\":\"金*\",\"isMinor\":false,\"hgId\":\"" + account.id + "\",\"email\":\"" + account.username +Server.config.dispatchServer.emailFormat +"\",\"realEmail\":\"" + account.username + Server.config.dispatchServer.emailFormat + "\",\"isLatestUserAgreement\":true,\"nickName\":\"" + account.username + "\"},\"msg\":\"OK\",\"status\":0,\"type\":\"A\"}"; } @@ -100,7 +95,6 @@ namespace Campofinale.Http ctx.Response.StatusCode = 200; - //ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); @@ -182,14 +176,7 @@ namespace Campofinale.Http } } - /*{ - "appCode": "2fe67ec91610377d", - "code": "121212", - "email": "aaaa@a.cc", - "from": 0, - "password": "aaaaaaaaaaaaaa1" - }*/ - public struct RegisterData + public struct RegisterFormData { public string appCode; public string code; @@ -203,7 +190,7 @@ namespace Campofinale.Http { string requestBody = ctx.Request.DataAsString; Console.WriteLine(requestBody); - RegisterData data = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); + RegisterFormData data = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); string username = data.email.Split("@")[0]; (string,int) msg=DatabaseManager.db.CreateAccount(username); string resp = ""; @@ -267,9 +254,6 @@ namespace Campofinale.Http resp = File.ReadAllText("Data/GachaHistory/index_noplayerfound.html"); } - - - ctx.Response.StatusCode = 200; await ctx.Response.SendAsync(resp); diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index 7e08074..c79efbd 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -72,6 +72,16 @@ namespace Campofinale.Packets.Cs return; } Account account = DatabaseManager.db.GetAccountByTokenGrant(req.Token); + if (account==null) + { + session.Send(ScMsgId.ScNtfErrorCode, new ScNtfErrorCode() + { + Details = "Auth Error", + ErrorCode = (int)CODE.ErrLoginProcessLogin, + }); + session.Disconnect(); + return; + } ScLogin rsp = new() { IsEnc = false, From f47ec48073e4017cb9452f21510d5d302f8d24d4 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 9 Jul 2025 22:38:12 +0200 Subject: [PATCH 16/27] FakeClientTester --- .../Campofinale.Protocol.csproj | 7 + Campofinale.Protocol/Campofinale.proto | 6678 +++++++++++++++++ Campofinale/Network/Packet.cs | 23 + Campofinale/Program.cs | 67 + 4 files changed, 6775 insertions(+) create mode 100644 Campofinale.Protocol/Campofinale.proto diff --git a/Campofinale.Protocol/Campofinale.Protocol.csproj b/Campofinale.Protocol/Campofinale.Protocol.csproj index 4b595fb..230ae6f 100644 --- a/Campofinale.Protocol/Campofinale.Protocol.csproj +++ b/Campofinale.Protocol/Campofinale.Protocol.csproj @@ -19,6 +19,10 @@ + + + + @@ -897,5 +901,8 @@ + + + \ No newline at end of file diff --git a/Campofinale.Protocol/Campofinale.proto b/Campofinale.Protocol/Campofinale.proto new file mode 100644 index 0000000..eb58019 --- /dev/null +++ b/Campofinale.Protocol/Campofinale.proto @@ -0,0 +1,6678 @@ +syntax = "proto3"; + +message Vector2 { + int32 x = 1; + int32 y = 2; +} + +message SubPort { + Vector2 pos = 1; + Direction direction = 2; +} + +enum Direction { + Direction_Up = 0; + Direction_Right = 1; + Direction_Down = 2; + Direction_Left = 3; + Direction_Max = 4; +} + +message ItemUnit { + string id = 1; + uint64 count = 2; +} + +message ItemBox { + string id = 1; + uint64 count = 2; + int32 index = 3; + int64 offset = 4; +} + +message Formula { + string id = 1; + int64 progress_per_round = 2; + repeated ItemUnit from = 3; + repeated ItemUnit to = 4; +} + +message SDShape { + ShapeType type = 1; + repeated Vector2 points = 2; +} + +enum ShapeType { + ShapeType_Invalid = 0; + ShapeType_Rect = 1; + ShapeType_Line = 2; + ShapeType_Max = 3; +} + +message SDTemplate { + string id = 1; + NodeType type = 2; + SDShape shape = 3; + oneof s_d_node { + SDNodeBus bus = 21; + SDNodeBusUnloader bus_unloader = 22; + SDNodeBusLoader bus_loader = 23; + SDNodeCollector collector = 24; + SDNodeProducer producer = 25; + SDNodeBoxConveyor box_conveyor = 26; + SDNodeBoxRouter box_router = 27; + } +} + +enum NodeType { + NodeType_Invalid = 0; + NodeType_Inventory = 1; + NodeType_Bus = 2; + NodeType_Hub = 3; + NodeType_Collector = 4; + NodeType_Producer = 5; + NodeType_BoxConveyor = 6; + NodeType_BoxRouter = 7; + NodeType_BusUnloader = 8; + NodeType_BusLoader = 9; + NodeType_Max = 10; +} + +message SDNodeBus { + SDComponentBus bus = 1; +} + +message SDComponentBus { + repeated SubPort ports = 1; +} + +message SDNodeBusUnloader { + SDComponentBusUnloader bus_unloader = 1; + SDComponentSelector selector = 2; +} + +message SDComponentBusUnloader { + repeated SubPort ports = 1; +} + +message SDComponentSelector { + repeated SubPort ports = 1; +} + +message SDNodeBusLoader { + SDComponentBusLoader bus_loader = 1; +} + +message SDComponentBusLoader { + repeated SubPort ports_in = 1; + repeated SubPort ports_out = 2; +} + +message SDNodeCollector { + SDComponentCollector collector = 1; + repeated SDComponentCache caches = 2; +} + +message SDComponentCollector { + int64 progress_per_round = 1; +} + +message SDComponentCache { + int32 size = 1; + repeated SubPort ports = 2; +} + +message SDNodeProducer { + SDComponentProducer producer = 1; + SDComponentFormulaMan formula_man = 2; + repeated SDComponentCache caches_in = 3; + repeated SDComponentCache caches_out = 4; +} + +message SDComponentProducer { + int64 produce_scale = 1; +} + +message SDComponentFormulaMan { + repeated string formula_ids = 1; +} + +message SDNodeBoxConveyor { + SDComponentBoxConveyor box_conveyor = 1; +} + +message SDComponentBoxConveyor { + int64 m_s_per_step = 1; +} + +message SDNodeBoxRouter { + SDComponentBoxRouter box_router = 1; +} + +message SDComponentBoxRouter { + int64 m_s_hold = 1; + repeated SubPort ports = 2; +} + +message LayoutShape { + ShapeType type = 1; + repeated Vector2 points = 2; + repeated Direction dynamic_dir_in = 3; + repeated Direction dynamic_dir_out = 4; +} + +message Node { + uint64 node_id = 1; + NodeType type = 2; + string template_id = 3; + LayoutShape shape = 4; + repeated Component component = 11; +} + +message Component { + uint64 component_id = 1; + ComponentType type = 2; + oneof content { + ComponentCache cache = 11; + ComponentInventory inventory = 12; + ComponentCollector collector = 13; + ComponentProducer producer = 14; + ComponentSelector selector = 15; + ComponentBoxConveyor box_conveyor = 16; + ComponentBoxRouter box_router = 17; + ComponentMap map = 18; + ComponentTransform transform = 19; + } +} + +enum ComponentType { + ComponentType_Invalid = 0; + ComponentType_Map = 1; + ComponentType_Transform = 2; + ComponentType_Bus = 3; + ComponentType_Inventory = 4; + ComponentType_Cache = 5; + ComponentType_Selector = 6; + ComponentType_Collector = 7; + ComponentType_Producer = 8; + ComponentType_FormulaMan = 9; + ComponentType_BoxConveyor = 10; + ComponentType_BoxRouter = 11; + ComponentType_BusUnloader = 12; + ComponentType_BusLoader = 13; + ComponentType_Max = 14; +} + +message ComponentCache { + repeated ItemUnit cache = 1; +} + +message ComponentInventory { + repeated ItemUnit store = 1; +} + +message ComponentCollector { + int64 current_progress = 1; + int64 progress_per_round = 2; + repeated ItemUnit items_per_round = 3; +} + +message ComponentProducer { + int64 current_progress = 1; + string current_formula_id = 2; +} + +message ComponentSelector { + string selected_item_id = 1; +} + +message ComponentBoxConveyor { + SubPort port_in = 1; + SubPort port_out = 2; + repeated ItemBox list = 6; +} + +message ComponentBoxRouter { + ItemBox content = 1; +} + +message ComponentMap { + map com_as_kind = 1; +} + +message ComponentTransform { + Vector2 position = 1; + Direction direction = 2; +} + +message ContextBrief { + uint64 c_d = 1; + int64 now = 2; + bool is_active = 3; +} + +message ContextBlackboard { + int64 electric_current = 1; + int64 electric_max = 2; +} + +message ContextStatus { + ContextBrief brief = 1; + ContextBlackboard blackboard = 2; + repeated uint64 node_ids = 3; +} + +message Event { + int64 timestamp_m_s = 1; + uint64 sequence = 2; + EventType type = 3; + oneof payload { + EventPrepared prepared = 11; + EventLayoutChg layout_chg = 12; + EventComponentChg component_chg = 13; + EventRelationChg relation_chg = 14; + } +} + +enum EventType { + EventType_Invalid = 0; + EventType_Prepared = 1; + EventType_LayoutChg = 2; + EventType_ComponentChg = 3; + EventType_RelationChg = 4; + EventType_Max = 5; +} + +message EventPrepared { +} + +message EventLayoutChg { + repeated uint64 node_ids = 1; +} + +message EventComponentChg { + repeated uint64 component_ids = 1; +} + +message EventRelationChg { + bool is_got = 1; + repeated uint64 com_id = 2; +} + +message Operate { + OperateType type = 1; + oneof payload { + OperatePayloadPlace place = 11; + OperatePayloadPlaceConveyor place_conveyor = 12; + OperatePayloadDismantle dismantle = 13; + OperatePayloadSetCollectTarget set_collect_target = 14; + OperatePayloadSetUnloaderSelect set_unloader_select = 15; + OperatePayloadPutInItemsToCache put_in_items_to_cache = 16; + OperatePayloadTakeOutItemsFromCache take_out_items_from_cache = 17; + OperatePayloadAddNewArea add_new_area = 18; + OperatePayloadSetEventEnable set_event_enable = 19; + } +} + +enum OperateType { + OperateType_Invalid = 0; + OperateType_Place = 1; + OperateType_PlaceConveyor = 2; + OperateType_Dismantle = 3; + OperateType_SetCollectTarget = 4; + OperateType_SetUnloaderSelect = 5; + OperateType_PutInItemsToCache = 6; + OperateType_TakeOutItemsFromCache = 7; + OperateType_AddNewArea = 8; + OperateType_SetEventEnable = 9; +} + +message OperatePayloadPlace { + string template_id = 1; + Vector2 pos = 2; + Direction direction = 3; +} + +message OperatePayloadPlaceConveyor { + string template_id = 1; + Direction direction_in = 2; + Direction direction_out = 3; + repeated Vector2 points = 4; +} + +message OperatePayloadDismantle { + uint64 node_id = 1; +} + +message OperatePayloadSetCollectTarget { + uint64 node_id = 1; + repeated ItemUnit items_per_round = 2; +} + +message OperatePayloadSetUnloaderSelect { + uint64 node_id = 1; + string item_id = 2; +} + +message OperatePayloadPutInItemsToCache { + uint64 com_id = 1; + repeated ItemUnit items = 2; +} + +message OperatePayloadTakeOutItemsFromCache { + uint64 com_id = 1; + repeated ItemUnit items = 2; +} + +message OperatePayloadAddNewArea { + repeated Vector2 area = 1; +} + +message OperatePayloadSetEventEnable { + bool enable = 1; + repeated EventType event_type_list = 2; +} + +message OperateReturn { + OperateRetCode ret_code = 1; + int64 timestamp_m_s = 2; + uint64 sequence = 3; + oneof payload { + OperateReturnPlace place = 11; + OperateReturnPlaceConveyor place_conveyor = 12; + OperateReturnPutInItemsToCache put_in_items_to_cache = 13; + OperateReturnTakeOutItemsFromCache take_out_items_from_cache = 14; + } +} + +enum OperateRetCode { + OperateRetCode_OK = 0; + OperateRetCode_Unknown = 1; + OperateRetCode_Fail = 2; + OperateRetCode_InvalidParameter = 3; + OperateRetCode_UnknownTemplate = 4; + OperateRetCode_MeshConflict = 5; +} + +message OperateReturnPlace { + uint64 node_id = 1; +} + +message OperateReturnPlaceConveyor { + uint64 node_id = 1; +} + +message OperateReturnPutInItemsToCache { + repeated ItemUnit least_items = 1; +} + +message OperateReturnTakeOutItemsFromCache { + repeated ItemUnit got_items = 1; +} + +message MeshArea { + repeated Vector2 range = 1; +} + +message MeshAreaBitmap { + repeated Vector2 area = 1; + repeated uint64 bitmaps = 2; +} + +message ContextArchive { + ContextBrief brief = 1; + ContextBlackboard blackboard = 2; + repeated MeshArea areas = 3; + repeated Node nodes = 11; +} + +message BattleClientData { + repeated BattleClientOpData op_list = 1; +} + +message BattleClientOpData { + uint64 owner_id = 1; + BattleActionOperateType op_type = 2; + uint32 generation = 3; + int32 chapter_map_id = 17; + oneof op_data_impl { + BattleAddBuffOpData add_buff_op_data = 4; + BattleFinishBuffOpData finish_buff_op_data = 5; + BattleSkillAttachOpData skill_attach_op_data = 6; + BattleSkillDetachOpData skill_detach_op_data = 7; + BattleSkillStartCastOpData skill_start_cast_op_data = 8; + BattleSkillEndCastOpData skill_end_cast_op_data = 9; + BattleSwitchModeOpData skill_switch_mode_op_data = 10; + BattleTriggerActionOpData trigger_action_op_data = 11; + BattleUpdateHubOpData update_hub_op_data = 12; + BattleEntityDieOpData entity_die_op_data = 13; + BattleEntityValueModifyData entity_value_modify_data = 14; + BattleResetBattleDataOpData reset_battle_op_data = 15; + BattleUpdateDataVersionOpData update_data_version_op_data = 16; + } +} + +enum BattleActionOperateType { + BATTLE_OP_NONE = 0; + BATTLE_OP_ADD_BUFF = 1; + BATTLE_OP_FINISH_BUFF = 2; + BATTLE_OP_SKILL_ATTACH = 3; + BATTLE_OP_SKILL_DETACH = 4; + BATTLE_OP_SKILL_START_CAST = 5; + BATTLE_OP_SKILL_END_CAST = 6; + BATTLE_OP_SWITCH_MODE = 7; + BATTLE_OP_TRIGGER_ACTION = 8; + BATTLE_OP_UPDATE_HUB = 9; + BATTLE_OP_ENTITY_DIE = 10; + BATTLE_OP_ENTITY_VALUE_MODIFY = 11; + BATTLE_OP_RESET_BATTLE_DATA = 12; + BATTLE_OP_UPDATE_DATA_VERSION = 13; +} + +message BattleAddBuffOpData { + uint64 src_inst_id = 1; + uint64 target_inst_id = 2; + string buff_id = 3; + uint64 buff_inst_id = 4; + int64 client_add_ts = 5; + BattleBlackboard assigned_items = 6; + int32 buff_src_type = 7; + string buff_src_args = 8; +} + +message BattleBlackboard { + map blackboard = 1; +} + +message BattleBlackboardData { + string str_value = 1; + double float_value = 2; + bool is_dynamic = 3; +} + +message BattleFinishBuffOpData { + uint64 buff_inst_id = 1; + int32 reduce_layer = 2; + bool force = 3; +} + +message BattleSkillAttachOpData { + uint64 src_inst_id = 1; + string skill_id = 2; + int32 skill_lv = 3; + BattleSkillSource skill_source = 4; + uint64 skill_inst_id = 5; +} + +enum BattleSkillSource { + BATTLE_SKILL_SOURCE_DEFAULT = 0; + BATTLE_SKILL_SOURCE_MODE = 1; + BATTLE_SKILL_SOURCE_WEAPON = 2; + BATTLE_SKILL_SOURCE_EQUIP_SUIT = 3; + BATTLE_SKILL_SOURCE_OTHER = 4; + BATTLE_SKILL_SOURCE_INTERACTIVE = 5; + BATTLE_SKILL_SOURCE_SUMMON = 6; + BATTLE_SKILL_SOURCE_PLUNGING_ATTACK = 7; + BATTLE_SKILL_SOURCE_POWER_ATTACK = 8; + BATTLE_SKILL_SOURCE_TALENT_NODE_SKILL = 9; + BATTLE_SKILL_SOURCE_POTENTIAL_LV_SKILL = 10; +} + +message BattleSkillDetachOpData { + uint64 skill_inst_id = 1; +} + +message BattleSkillStartCastOpData { + uint64 inst_id = 1; + BattleTargetHandle target = 2; +} + +message BattleTargetHandle { + repeated BattleTargetWrapper targets = 1; +} + +message BattleTargetWrapper { + uint64 target_id = 1; + Vector target_pos = 2; +} + +message Vector { + float x = 1; + float y = 2; + float z = 3; +} + +message BattleSkillEndCastOpData { + uint64 inst_id = 1; +} + +message BattleSwitchModeOpData { + uint32 mode_inst_id = 1; + string mode_id = 2; + int32 mode_change_type = 3; + bool is_enable = 4; +} + +message BattleTriggerActionOpData { + uint64 owner_id = 1; + uint64 inst_id = 2; + string template_id = 3; + BattleTargetHandle input_targets = 4; + BattleActionInst action = 5; + BattleTriggerType trigger_type = 6; + BattleActionOwnerType owner_type = 7; +} + +message BattleActionInst { + int32 action_id = 1; + ServerBattleActionType action_type = 2; + oneof inst_impl { + BattleDamageActionRuntime damage_action = 3; + BattleCreateBuffActionRuntime create_buff_action = 4; + BattleFinishBuffActionRuntime finish_buff_action = 5; + BattleGainCostActionRuntime gain_cost_action = 6; + BattleHealActionRuntime heal_action = 7; + BattleSwitchModeActionRuntime switch_mode_action = 8; + BattleModifyDynamicBlackboardActionRuntime modify_dynamic_blackboard_action = 9; + BattleSpawnEnemyActionRuntime spawn_enemy_action = 10; + BattleCheckDamageTypeActionRuntime check_damage_type_action = 11; + BattleCheckDamageDecorateMaskActionRuntime check_damage_decorate_mask_action = 12; + BattleCheckDistanceConditionActionRuntime check_distance_condition_action = 13; + BattleCheckEntityNumActionRuntime check_entity_num_action = 14; + BattleCheckHpActionRuntime check_hp_action = 15; + BattleCheckIsCriticalDamageActionRuntime check_is_critical_damage_action = 16; + BattleCheckMainCharacterActionRuntime check_main_character_action = 17; + BattleCheckObjectTypeMatchActionRuntime check_object_type_match_action = 18; + BattleCheckSkillTypeActionRuntime check_skill_type_action = 19; + BattleCheckSquadInFightActionRuntime check_squad_in_fight_action = 20; + BattleCheckTagMatchActionRuntime check_tag_match_action = 21; + BattleCheckTargetAngleActionRuntime check_target_angle_action = 22; + BattleCompareFloatActionRuntime compare_float_action = 23; + BattleProbabilityActionRuntime probability_action = 24; + BattleLaunchProjectileActionRuntime launch_projectile_action = 25; + BattleSpawnAbilityEntityActionRuntime spawn_ability_entity_action = 26; + BattleSpawnCustomSummonActionRuntime spawn_custom_summon_action = 27; + BattleRefreshBuffAttrModifierValueActionRuntime refresh_buff_attr_modifier_value_action = 28; + BattleStoreAttributeValueActionRuntime store_attribute_value_action = 29; + BattleSetBlackboardFromPresetRuntime set_blackboard_from_preset_action = 30; + EmptyBattleAction empty_action = 999; + } +} + +enum ServerBattleActionType { + BATTLE_ACTION_NONE = 0; + BATTLE_ACTION_DAMAGE = 1; + BATTLE_ACTION_CREATE_BUFF = 2; + BATTLE_ACTION_FINISH_BUFF = 3; + BATTLE_ACTION_GAIN_COST = 4; + BATTLE_ACTION_HEAL = 5; + BATTLE_ACTION_SWITCH_MODE = 6; + BATTLE_ACTION_MODIFY_DYNAMIC_BLACKBOARD = 7; + BATTLE_ACTION_SPAWN_ENEMY = 8; + BATTLE_ACTION_CHECK_DAMAGE_TYPE = 9; + BATTLE_ACTION_CHECK_DAMAGE_DECORATE_MASK = 10; + BATTLE_ACTION_CHECK_DISTANCE_CONDITION = 11; + BATTLE_ACTION_CHECK_ENTITY_NUM = 12; + BATTLE_ACTION_CHECK_HP = 13; + BATTLE_ACTION_CHECK_IS_CRITICAL_DAMAGE = 14; + BATTLE_ACTION_CHECK_MAIN_CHARACTER = 15; + BATTLE_ACTION_CHECK_OBJECT_TYPE_MATCH = 16; + BATTLE_ACTION_CHECK_SKILL_TYPE = 17; + BATTLE_ACTION_CHECK_SQUAD_IN_FIGHT = 18; + BATTLE_ACTION_CHECK_TAG_MATCH = 19; + BATTLE_ACTION_CHECK_TARGET_ANGLE = 20; + BATTLE_ACTION_COMPARE_FLOAT = 21; + BATTLE_ACTION_PROBABILITY = 22; + BATTLE_ACTION_LAUNCH_PROJECTILE = 23; + BATTLE_ACTION_SPAWN_ABILITY_ENTITY = 24; + BATTLE_ACTION_IF_ELSE = 25; + BATTLE_ACTION_FOR_EACH = 26; + BATTLE_ACTION_AURA = 27; + BATTLE_ACTION_SPAWN_CUSTOM_SUMMON = 28; + BATTLE_ACTION_CHANNELING = 29; + BATTLE_ACTION_STORE_ATTRIBUTE_VALUE = 30; + BATTLE_ACTION_REFRESH_BUFF_ATTR_MODIFIER_VALUE = 31; + BATTLE_ACTION_SET_BLACKBOARD_FROM_PRESET = 32; +} + +message BattleDamageActionRuntime { + uint64 attacker_id = 1; + repeated BattleDamageDetail details = 2; +} + +message BattleDamageDetail { + uint64 target_id = 1; + int32 damage_unit_index = 2; + bool is_crit = 3; + double value = 4; + BattleDamageModifierArgs modifier_args = 5; + double cur_hp = 6; +} + +message BattleDamageModifierArgs { + uint64 attacker_id = 1; + uint64 defender_id = 2; + repeated BattleModifierHandle attacker_modifiers = 3; + repeated BattleModifierHandle defender_modifiers = 4; +} + +message BattleModifierHandle { + uint64 buff_inst_id = 1; + int32 index = 2; +} + +message BattleCreateBuffActionRuntime { + repeated BattleCreateBuffActionDetail details = 2; +} + +message BattleCreateBuffActionDetail { + uint64 source_id = 1; + uint64 target_id = 2; + uint64 buff_inst_id = 3; + int32 buff_input_index = 4; + repeated BattleBlackboardAssignItem assigned_items = 5; +} + +message BattleBlackboardAssignItem { + string target_key = 1; + string input_value_key = 2; + bool use_direct_value = 3; + float numeric_value = 4; + string string_value = 5; +} + +message BattleFinishBuffActionRuntime { + repeated BattleFinishBuffActionDetail finish_buffs = 1; +} + +message BattleFinishBuffActionDetail { + uint64 target_id = 1; + uint64 buff_inst_id = 2; +} + +message BattleGainCostActionRuntime { + uint64 source_id = 1; + uint64 target_id = 2; + double final_value = 3; +} + +message BattleHealActionRuntime { + repeated BattleHealActionDetail details = 1; +} + +message BattleHealActionDetail { + uint64 source_id = 1; + uint64 target_id = 2; + double value = 3; + BattleHealModifierArgs modifier_args = 4; + double cur_hp = 5; +} + +message BattleHealModifierArgs { + uint64 healer_id = 1; + uint64 heal_receive_id = 2; + repeated BattleModifierHandle healer_modifiers = 3; + repeated BattleModifierHandle heal_receive_modifiers = 4; +} + +message BattleSwitchModeActionRuntime { + uint64 source_id = 1; + string mode_id = 2; + uint32 mode_inst_id = 3; +} + +message BattleModifyDynamicBlackboardActionRuntime { + double client_value = 1; +} + +message BattleSpawnEnemyActionRuntime { + uint32 client_key = 1; + repeated BattleSpawnEnemyActionDetail details = 2; +} + +message BattleSpawnEnemyActionDetail { + uint64 source_id = 1; + uint32 enemy_lv = 2; + Vector pos = 3; + Vector rotation = 4; + int32 scene_num_id = 5; +} + +message BattleCheckDamageTypeActionRuntime { + bool result = 1; +} + +message BattleCheckDamageDecorateMaskActionRuntime { + bool result = 1; +} + +message BattleCheckDistanceConditionActionRuntime { + Vector pos_a = 1; + Vector pos_b = 2; + float distance = 4; + bool result = 3; +} + +message BattleCheckEntityNumActionRuntime { + bool result = 1; +} + +message BattleCheckHpActionRuntime { + uint64 source_id = 1; + bool result = 2; +} + +message BattleCheckIsCriticalDamageActionRuntime { + bool result = 1; +} + +message BattleCheckMainCharacterActionRuntime { + uint64 check_target_id = 1; + bool result = 2; +} + +message BattleCheckObjectTypeMatchActionRuntime { + bool result = 3; +} + +message BattleCheckSkillTypeActionRuntime { + bool result = 1; +} + +message BattleCheckSquadInFightActionRuntime { + bool result = 1; +} + +message BattleCheckTagMatchActionRuntime { + repeated uint64 target_ids = 1; + bool result = 2; +} + +message BattleCheckTargetAngleActionRuntime { + Vector source_Vector = 1; + Vector target_Vector = 2; + bool result = 3; +} + +message BattleCompareFloatActionRuntime { + bool result = 1; +} + +message BattleProbabilityActionRuntime { + bool result = 1; +} + +message BattleLaunchProjectileActionRuntime { + uint64 source_id = 1; + repeated BattleProjectileDetail details = 2; +} + +message BattleProjectileDetail { + uint64 client_projectile_id = 1; +} + +message BattleSpawnAbilityEntityActionRuntime { + repeated BattleAbilityEntityDetail details = 1; +} + +message BattleAbilityEntityDetail { + uint64 client_ability_entity_id = 1; + uint64 source_id = 2; + Vector init_pos = 3; + Vector rotation = 4; +} + +message BattleSpawnCustomSummonActionRuntime { + repeated BattleSpawnCustomSummonDetail details = 1; +} + +message BattleSpawnCustomSummonDetail { + string summon_id = 1; + string summon_skill_id = 2; + uint64 client_ability_entity_id = 3; + Vector init_pos = 4; + Vector rotation = 5; + BattleBlackboard blackboard = 6; + uint64 source_id = 7; +} + +message BattleRefreshBuffAttrModifierValueActionRuntime { +} + +message BattleStoreAttributeValueActionRuntime { + float value = 1; +} + +message BattleSetBlackboardFromPresetRuntime { + string modified_value = 1; +} + +message EmptyBattleAction { +} + +enum BattleTriggerType { + BATTLE_TRIGGER_TYPE_EXECUTE = 0; + BATTLE_TRIGGER_TYPE_TICK = 1; + BATTLE_TRIGGER_TYPE_END = 2; +} + +enum BattleActionOwnerType { + BATTLE_ACTION_OWNER_TYPE_NONE = 0; + BATTLE_ACTION_OWNER_TYPE_BUFF = 1; + BATTLE_ACTION_OWNER_TYPE_SKILL = 2; +} + +message BattleUpdateHubOpData { + uint64 owner_id = 1; + uint64 inst_id = 2; + string template_id = 3; + repeated BattleHubItem hub_data = 4; + BattleActionOwnerType owner_type = 5; +} + +message BattleHubItem { + BattleHubKeyType key_type = 1; + repeated double numeric_values = 2; + repeated string string_values = 3; + repeated BattleTargetHandle target_handles = 4; +} + +enum BattleHubKeyType { + BATTLE_HUB_KEY_TYPE_NONE = 0; + DAMAGE_TYPE = 1; + DAMAGE_DECORATE_MASK = 2; + DAMAGE_IS_CRIT = 3; + ENTITY_NUM = 4; + SKILL_TYPE = 5; +} + +message BattleEntityDieOpData { + uint64 entity_inst_id = 1; + int32 scene_num_id = 2; + bool disable_anti_cheat = 3; +} + +message BattleEntityValueModifyData { + uint64 entity_inst_id = 1; + int32 scene_num_id = 2; + BattleInfo value = 3; + int32 source = 4; +} + +message BattleInfo { + double hp = 1; + float ultimatesp = 2; +} + +message BattleResetBattleDataOpData { +} + +message BattleUpdateDataVersionOpData { + string client_data_version = 1; +} + +message BattleActionJump { + int32 action_type = 1; + string jump_to_tag = 2; +} + +message BuffRes { + string buff_id = 1; + int32 life_type = 2; + repeated BattleAttrModifier attr_modifiers = 3; + repeated BuffDamageModifierRes damage_modifiers = 4; + repeated BuffHealModifierRes heal_modifiers = 5; + BattleBlackboard blackboard = 6; + map action_map = 7; + repeated int32 apply_tags = 8; + BuffStackingSettings stacking_settings = 9; + BattleBlackboardFloat duration = 10; + bool remove_on_repatriate = 11; + string stacking_id = 101; + int32 stacking_type = 102; + int32 max_stack_cnt = 103; + int32 priority = 104; +} + +message BattleAttrModifier { + int32 modify_attr_type = 1; + int32 attr_type = 2; + int32 formula_item = 3; + BattleBlackboardFloat param = 4; +} + +message BattleBlackboardFloat { + bool use_blackboard_key = 1; + string blackboard_key = 2; + double default_value = 3; +} + +message BuffDamageModifierRes { + int32 enable_side = 1; + int32 index = 2; + repeated BattleActionRes cond_actions = 3; + repeated BattleDamageProcessor damage_processors = 4; +} + +message BattleActionRes { + int32 action_id = 1; + ServerBattleActionType action_type = 2; + oneof inst_impl { + BattleDamageActionData damage_action = 3; + BattleCreateBuffActionData create_buff_action = 4; + BattleFinishBuffActionData finish_buff_action = 5; + BattleGainCostActionData gain_cost_action = 6; + BattleHealActionData heal_action = 7; + BattleSwitchModeActionData switch_mode_action = 8; + BattleModifyDynamicBlackboardActionData modify_dynamic_blackboard_action = 9; + BattleSpawnEnemyActionData spawn_enemy_action = 10; + BattleCheckDamageTypeActionData check_damage_type_action = 11; + BattleCheckDamageDecorateMaskActionData check_damage_decorate_mask_action = 12; + BattleCheckDistanceConditionActionData check_distance_condition_action = 13; + BattleCheckEntityNumActionData check_entity_num_action = 14; + BattleCheckHpActionData check_hp_action = 15; + BattleCheckIsCriticalDamageActionData check_is_critical_damage_action = 16; + BattleCheckMainCharacterActionData check_main_character_action = 17; + BattleCheckObjectTypeMatchActionData check_object_type_match_action = 18; + BattleCheckSkillTypeActionData check_skill_type_action = 19; + BattleCheckSquadInFightActionData check_squad_in_fight_action = 20; + BattleCheckTagMatchActionData check_tag_match_action = 21; + BattleCheckTargetAngleActionData check_target_angle_action = 22; + BattleCompareFloatActionData compare_float_action = 23; + BattleProbabilityActionData probability_action = 24; + BattleLaunchProjectileActionData launch_projectile_action = 25; + BattleSpawnAbilityEntityActionData spawn_ability_entity_action = 26; + BattleSpawnCustomSummonActionData spawn_custom_summon_action = 27; + BattleRefreshBuffAttrModifierValueActionData refresh_buff_attr_modifier_value_action = 28; + BattleStoreAttributeValueActionData store_attribute_value_action = 29; + BattleSetBlackboardFromPresetData set_blackboard_from_preset_action = 30; + BattleActionEmptyRes empty_res = 999; + } +} + +message BattleDamageActionData { + BattleActionTargetSetting target = 1; + int32 attacker_type = 2; + repeated BattleActionDamageUnit damage_unit = 3; +} + +message BattleActionTargetSetting { + int32 target_source = 1; + string target_group_key = 2; +} + +message BattleActionDamageUnit { + int32 damage_type = 1; + int32 damage_attribute_type = 2; + int32 damage_decorate_mask = 3; + bool simple_calculation = 4; + BattleBlackboardFloat atk_scale = 5; + BattleDamageAtkCalculation atk_calculation = 6; + repeated BattleDamageProcessor damage_processors = 7; + bool gain_cost = 8; + repeated SkillCostData cost_data = 9; + bool reduce_damage_for_guard = 10; + float reduce_damage_for_guard_ratio = 11; +} + +message BattleDamageAtkCalculation { + AtkCalculationType type = 1; + oneof calculation_impl { + AtkScaleCalculation atk_scale_calculation = 2; + DefiniteValueCalculation definite_value_calculation = 3; + MultiplyAttributeCalculation multiply_attribute_calculation = 4; + BreakingAttackCalculation breaking_attack_calculation = 5; + PrimaryAttrCalculation primary_attr_calculation = 6; + } +} + +enum AtkCalculationType { + ATK_SCALE = 0; + DEFINITE_VALUE = 1; + MULTIPLY_ATTRIBUTE = 2; + BREAKING_ATK_CALC = 3; + PRIMARY_ATTR_CALC = 4; +} + +message AtkScaleCalculation { + AtkCalculationType type = 1; + BattleBlackboardFloat atk_scale = 2; +} + +message DefiniteValueCalculation { + AtkCalculationType type = 1; + BattleBlackboardFloat definite_value = 2; + bool apply_scale = 3; + BattleBlackboardFloat value_scale = 4; +} + +message MultiplyAttributeCalculation { + AtkCalculationType type = 1; + int32 value_source = 2; + int32 attr_type = 3; + BattleBlackboardFloat multiplier = 4; + BattleBlackboardFloat add_value = 5; +} + +message BreakingAttackCalculation { + AtkCalculationType type = 1; + BattleBlackboardFloat atk_scale = 2; + BattleBlackboardFloat multiplier = 3; +} + +message PrimaryAttrCalculation { + int32 value_source = 1; + int32 attr_type = 2; + bool apply_scale = 3; + BattleBlackboardFloat value_scale = 4; +} + +message BattleDamageProcessor { + DamageProcessorType type = 1; + oneof processor_impl { + AttackerCritRateProcessor attacker_crit_rate_processor = 2; + AttackerAtkProcessor attacker_atk_processor = 3; + AttackerCritDamageProcessor attacker_crit_damage_processor = 4; + AttackerPenProcessor attacker_pen_processor = 5; + DamageScaleProcessor damage_scale_processor = 6; + DefenderDefProcessor defender_def_processor = 7; + ModifyCalculateResultProcessor modify_calulate_result_processor = 8; + InstantModifyAttributeProcessor instant_modify_attribute_processor = 9; + } +} + +enum DamageProcessorType { + ATTACKER_CRIT_RATE = 0; + ATTACKER_ATK = 1; + ATTACKER_CRIT_DAMAGE = 2; + ATTACKER_PEN = 3; + DAMAGE_SCALE = 4; + DEFENDER_DEF = 5; + MODIFY_CALCULATE_RESULT = 6; + INSTANT_MODIFY_ATTRIBUTE = 7; +} + +message AttackerCritRateProcessor { + DamageProcessorType type = 1; + BattleBlackboardFloat addition = 2; +} + +message AttackerAtkProcessor { + DamageProcessorType type = 1; + BattleBlackboardFloat scale = 2; +} + +message AttackerCritDamageProcessor { + DamageProcessorType type = 1; + BattleBlackboardFloat scale = 2; +} + +message AttackerPenProcessor { + DamageProcessorType type = 1; + BattleBlackboardFloat scale = 2; +} + +message DamageScaleProcessor { + DamageProcessorType type = 1; + int32 damage_scale_side = 2; + string zone_name = 3; + BattleBlackboardFloat addition = 4; +} + +message DefenderDefProcessor { + DamageProcessorType type = 1; + BattleBlackboardFloat multiplier = 2; +} + +message ModifyCalculateResultProcessor { + DamageProcessorType type = 1; + int32 cal_type = 2; + BattleBlackboardFloat base_multiplier = 3; + BattleBlackboardFloat multiplier_cnt = 4; +} + +message InstantModifyAttributeProcessor { + DamageProcessorType type = 1; + int32 target_side = 2; + BattleAttrModifier attr_modifier = 3; +} + +message SkillCostData { + SkillCostType cost_type = 1; + float cost_value = 2; +} + +enum SkillCostType { + SKILL_COST_ULT_SP = 0; + SKILL_COST_ATB = 1; +} + +message BattleCreateBuffActionData { + repeated BuffInput buff_input = 1; + BattleBlackboardFloat count = 2; + BattleActionTargetSetting target = 3; + int32 buff_source_type = 4; + bool auto_finish_by_action = 5; +} + +message BuffInput { + string buff_id = 1; + bool assign_blackboard = 2; + repeated BattleBlackboardAssignItem assigned_items = 3; + bool read_id_from_blackboard = 4; +} + +message BattleFinishBuffActionData { + BattleActionTargetSetting buff_owner = 1; + repeated string buff_ids = 2; + bool finish_all_buff = 3; + BattleBlackboardFloat finish_layer_cnt = 4; +} + +message BattleGainCostActionData { + SkillCostData cost_data = 2; +} + +message BattleHealActionData { + int32 heal_type = 1; + BattleDamageAtkCalculation heal_calculation = 2; +} + +message BattleSwitchModeActionData { + string mode_id = 1; + bool reset_on_end = 2; +} + +message BattleModifyDynamicBlackboardActionData { + string key = 1; + BattleBlackboardFloat value = 2; + int32 modify_type = 3; +} + +message BattleSpawnEnemyActionData { + string enemy_id = 1; + BattleBlackboardFloat hp_ratio = 2; +} + +message BattleCheckDamageTypeActionData { + int32 damage_type = 1; +} + +message BattleCheckDamageDecorateMaskActionData { + int32 damage_decorate_mask = 1; +} + +message BattleCheckDistanceConditionActionData { + float distance = 1; + bool less_than = 2; +} + +message BattleCheckEntityNumActionData { + bool zero_always_return_true = 1; + int32 min_num = 2; + int32 compare_type = 3; +} + +message BattleCheckHpActionData { + int32 compare_type = 1; + bool is_ratio = 2; + BattleBlackboardFloat value = 3; +} + +message BattleCheckIsCriticalDamageActionData { + bool is_inverse = 1; +} + +message BattleCheckMainCharacterActionData { +} + +message BattleCheckObjectTypeMatchActionData { + int32 object_type_mask = 1; +} + +message BattleCheckSkillTypeActionData { + int32 skill_type = 1; +} + +message BattleCheckSquadInFightActionData { + bool is_inverse = 1; +} + +message BattleCheckTagMatchActionData { + GameplayTagQuery query = 1; +} + +message GameplayTagQuery { + int32 query_type = 1; + repeated int32 tag_ids = 2; +} + +message BattleCheckTargetAngleActionData { + BattleBlackboardFloat angle = 1; +} + +message BattleCompareFloatActionData { + int32 compare_type = 1; + BattleBlackboardFloat value_a = 2; + BattleBlackboardFloat value_b = 3; +} + +message BattleProbabilityActionData { + BattleBlackboardFloat probability = 1; +} + +message BattleLaunchProjectileActionData { + string projectile_id = 1; + bool assign_blackboard = 3; +} + +message BattleSpawnAbilityEntityActionData { + string ability_entity_id = 1; + bool assign_blackboard = 3; + bool set_spawner_as_source = 4; +} + +message BattleSpawnCustomSummonActionData { +} + +message BattleRefreshBuffAttrModifierValueActionData { +} + +message BattleStoreAttributeValueActionData { + string key = 1; +} + +message BattleSetBlackboardFromPresetData { + repeated string valid_values = 1; + string key = 2; +} + +message BattleActionEmptyRes { +} + +message BuffHealModifierRes { + int32 enable_side = 1; + int32 index = 2; + repeated BattleActionRes cond_actions = 3; + repeated BattleHealProcessor heal_processors = 4; +} + +message BattleHealProcessor { + HealProcessorType type = 1; + oneof processor_impl { + HealProcessorEmpty heal_processor_empty = 2; + BattleModifyHealCalcResult heal_modify_calc_result = 3; + InstantModifyAttributeForHealProcessor instant_modify_attribute_for_heal_processor = 4; + } +} + +enum HealProcessorType { + HEAL_PROCESSOR_EMPTY_TYPE = 0; + HEAL_MODIFY_RESULT = 1; + HEAL_INSTANT_MODIFY_ATTRIBUTE = 2; +} + +message HealProcessorEmpty { +} + +message BattleModifyHealCalcResult { + int32 modify_type = 1; + BattleBlackboardFloat multiplier = 2; + BattleBlackboardFloat multiplier_cnt = 3; +} + +message InstantModifyAttributeForHealProcessor { + HealProcessorType type = 1; + int32 target_side = 2; + BattleAttrModifier attr_modifier = 3; +} + +message BuffStackingSettings { + int32 identifier_type = 1; + int32 stacking_type = 2; + string stacking_key = 3; + string priority_key = 4; + int32 priority = 5; + int32 max_stack_cnt = 6; +} + +message SkillRes { + string skill_id = 1; + SkillCostType cost_type = 2; + int32 skill_lv = 3; + float cost_value = 4; + repeated int32 tag_during_attach = 5; + BattleBlackboard blackboard = 6; + map action_map = 7; + bool is_passive = 8; + repeated BattleAttrModifier attr_modifiers = 9; +} + +message BattleBlackboardString { + bool use_blackboard_key = 1; + string blackboard_key = 2; + string default_value = 3; +} + +message BattleSequenceRes { + int32 sequence_id = 1; + repeated BattleActionRes actions = 2; +} + +message ServerBuff { + string buff_id = 1; + uint64 inst_id = 2; + BattleBlackboard blackboard = 3; +} + +message ServerSkill { + string skill_id = 1; + uint64 inst_id = 2; + int32 potential_lv = 3; + int32 level = 4; + BattleBlackboard blackboard = 5; + BattleSkillSource source = 6; + repeated string talent_node_ids = 7; +} + +message BattleMgrInfo { + repeated ServerBuff buff_list = 1; + repeated ServerSkill skill_list = 2; + uint32 msg_generation = 3; +} + +message DynamicParameter { + int32 value_type = 1; + int32 real_type = 2; + repeated bool value_bool_list = 3; + repeated int64 value_int_list = 4; + repeated float value_float_list = 5; + repeated string value_string_list = 6; +} + +message EquipAttr { + int32 attr_type = 1; + int32 modifier_type = 2; + double modifier_value = 3; + int32 modify_attribute_type = 4; +} + +message EquipData { + uint64 equipid = 1; + int32 templateid = 2; + uint64 equip_char_id = 3; + repeated EquipAttr attrs = 4; +} + +message GemData { + uint64 gem_id = 1; + int32 template_id = 2; + int32 total_cost = 3; + repeated GemTerm terms = 4; + uint64 weapon_id = 5; +} + +message GemTerm { + int32 term_num_id = 1; + int32 cost = 2; +} + +message ItemBundle { + string id = 1; + int32 count = 2; +} + +message WeaponData { + uint64 inst_id = 1; + int32 template_id = 2; + uint64 exp = 3; + uint64 weapon_lv = 4; + uint64 refine_lv = 5; + uint64 breakthrough_lv = 6; + uint64 equip_char_id = 7; + uint64 attach_gem_id = 8; +} + +message ItemInst { + uint64 inst_id = 1; + bool is_lock = 101; + bool is_new = 102; + oneof inst_impl { + EquipData equip = 2; + GemData gem = 3; + WeaponData weapon = 4; + ItemInstEmpty empty = 31; + } +} + +message ItemInstEmpty { +} + +message ScdItemGrid { + int32 grid_index = 1; + string id = 2; + int32 count = 3; + ItemInst inst = 4; +} + +message ScdItemGridV2 { + int32 grid_index = 1; + int32 id = 2; + int32 count = 3; + ItemInst inst = 4; +} + +message SubmitItem { + string item_id = 1; + uint32 count = 2; + bool is_inst = 3; + uint64 inst_id = 4; +} + +message SendMailDef { + MailContent mail_content = 1; + repeated RewardItem item_list = 2; + int64 send_time = 3; + int64 expire_time = 4; + int32 mail_type = 5; + int32 mail_sub_type = 6; + bool is_global = 7; + bool is_star = 8; +} + +message MailContent { + string template_id = 1; + string title = 2; + string content = 3; + string sender_name = 4; + string sender_icon = 5; + map params = 6; +} + +message RewardItem { + string id = 1; + int64 count = 2; + ItemInst inst = 3; +} + +message GameCondition { + string condition_id = 1; + int32 condition_type = 2; + repeated string params = 3; + int32 compare_operator = 4; + int32 progress_to_compare = 5; + repeated int32 sub_condition_id_logics = 6; + repeated GameCondition sub_conditions = 7; + int32 scope_mask = 8; + bool use_current_scope = 9; +} + +message SendQuestionnaireMailDef { + uint64 mail_id = 1; + GameCondition condition = 2; + repeated RewardItem completed_item_list = 3; + int64 expire_time = 4; + bool is_star = 5; + string unique_id = 6; +} + +message CostItemListDef { + repeated SubmitItem item_list = 1; +} + +message SkillLevelInfo { + string skill_id = 1; + int32 skill_level = 2; + int32 skill_max_level = 3; + int32 skill_enhanced_level = 4; +} + +message Talent { + string latest_break_node = 1; + repeated string attr_nodes = 2; + repeated string latest_passive_skill_nodes = 3; + repeated string latest_factory_skill_nodes = 4; +} + +message RoleBaseInfo { + uint64 leader_char_id = 1; + Vector leader_position = 2; + Vector leader_rotation = 3; + string scene_name = 4; + uint64 server_ts = 11; +} + +message FriendStrangerUserInfo { + uint64 role_id = 1; + string uid = 2; + string name = 3; + string short_id = 4; + int64 last_login_time = 5; +} + +message FriendFriendUserInfo { + uint64 role_id = 1; + string uid = 2; + string name = 3; + string short_id = 4; + int64 last_login_time = 5; +} + +message FriendFriendInfo { + FriendFriendUserInfo friend_user_info = 1; + int64 create_time = 2; +} + +message FriendRequestInfo { + FriendStrangerUserInfo stranger_user_info = 1; + int64 create_time = 2; +} + +message FriendFriendSInfo { + uint64 role_id = 1; + int64 create_time = 2; +} + +message FriendRequestSInfo { + uint64 role_id = 1; + int64 create_time = 2; +} + +message TempTeamCharSaveData { + TrialCharData trial_char_data = 1; + int32 hp = 2; + int32 ultimate_sp = 3; +} + +message TrialCharData { + int32 equip_medicine_num = 2; +} + +message TeamCharId { + TeamCharIdType id_type = 1; + oneof char_id { + uint64 obj_id = 2; + string preset_char_id = 3; + } +} + +enum TeamCharIdType { + obj_id = 0; + preset_char_id = 1; +} + +message PassThroughData { + repeated string str_args = 1; + repeated int64 int_args = 2; +} + +message SceneTrackPoint { + string inst_id = 1; +} + +message SceneStaticMapMark { + int32 index = 1; +} + +message CsAchieveComplete { + string achieve_id = 1; +} + +message ScAchieveComplete { + string achieve_id = 1; +} + +message CsAchieveTakeReward { + string achieve_id = 1; +} + +message ScActivitySync { + repeated ActivityInfo info = 1; +} + +message ActivityInfo { + uint64 version = 1; + bool is_enable = 2; + string id = 3; + string name = 4; + int64 start_time = 5; + int64 end_time = 6; + ActivityType typ = 7; + ActivityInfoSpecified data = 8; +} + +enum ActivityType { + ACTIVITY_TYPE_DEFAULT = 0; + ACTIVITY_TYPE_CHECKIN = 1; +} + +message ActivityInfoSpecified { + oneof data { + ActivityInfoSpecifiedCheckin checkin = 15; + } +} + +message ActivityInfoSpecifiedCheckin { + int32 login_days = 1; + int32 reward_days = 2; +} + +message ScActivityModify { + ActivityInfo info = 1; +} + +message CsDailyCheckin { + string id = 1; +} + +message ScDailyCheckin { + string id = 1; +} + +message CsAdventureTakeRewardAll { +} + +message ScAdventureLevelModify { + int32 level = 1; + int64 exp = 2; +} + +message ScAdventureSyncAll { + int32 level = 1; + int64 exp = 2; +} + +message AdventureTask { + string task_id = 1; + int32 progress = 2; + int32 state = 3; +} + +message ScAdventureBookSync { + int32 adventure_book_stage = 1; + repeated AdventureTask tasks = 2; + int32 daily_activation = 3; +} + +message ScDailyActivationModify { + int32 daily_activation = 1; +} + +message CsTakeAdventureTaskReward { + string task_id = 1; +} + +message CsTakeAllAdventureTaskReward { + int32 task_type = 1; +} + +message ScAdventureTaskModify { + repeated AdventureTask tasks = 1; +} + +message CsTakeAdventureBookStageReward { + int32 adventure_book_stage = 1; +} + +message ScAdventureBookStageModify { + int32 adventure_book_stage = 1; +} + +message ScResetDailyAdventureTask { +} + +message CsDevClearBattleInfo { +} + +message CsBattleOp { + BattleClientData client_data = 1; +} + +message ScSpawnEnemy { + uint32 client_key = 1; + repeated uint64 enemy_inst_ids = 2; +} + +message SpawnServerSummonData { + uint64 owner_inst_id = 1; + uint64 summon_inst_id = 2; +} + +message ScEntityPropertyChange { + uint64 inst_id = 1; + BattleInfo info = 2; +} + +message ScBattleDebugInfo { + string msg = 1; +} + +message ScBattleGenerationChange { + uint64 inst_id = 1; + uint32 generation = 2; +} + +message ScAttachServerSkill { + uint64 inst_id = 1; + repeated ServerSkill skills = 2; + uint32 generation = 3; +} + +message ScDetachServerSkill { + uint64 inst_id = 1; + repeated uint64 del_inst_ids = 2; + uint32 generation = 3; +} + +message ScAddServerBuff { + uint64 inst_id = 1; + repeated ServerBuff buffs = 2; + uint32 generation = 3; +} + +message ScRemoveServerBuff { + uint64 inst_id = 1; + repeated uint64 del_inst_ids = 2; + uint32 generation = 3; +} + +message ScSyncAllBitset { + repeated BitsetData bitset = 1; +} + +message BitsetData { + int32 type = 1; + repeated uint64 value = 2; +} + +message CsBitsetAdd { + int32 type = 1; + repeated uint32 value = 2; +} + +message CsBitsetRemoveAll { + int32 type = 1; +} + +message CsBitsetRemove { + int32 type = 1; + repeated uint32 value = 2; +} + +message ScBitsetAdd { + int32 type = 1; + repeated uint32 value = 2; + int32 source = 3; +} + +message ScBitsetRemove { + int32 type = 1; + repeated uint32 value = 2; + int32 source = 3; +} + +message ScBitsetRemoveAll { + int32 type = 1; + int32 source = 2; +} + +message BlocInfo { + string blocid = 1; + int32 level = 2; + int32 exp = 3; +} + +message ScSyncAllBloc { + repeated BlocInfo blocs = 1; + repeated ShopInfo shops = 2; +} + +message ShopInfo { + string shopid = 1; + int32 type = 2; + map already_sell_count = 3; + repeated DiscountInfo discount_info = 4; +} + +message DiscountInfo { + int32 posid = 1; + int32 discount = 2; +} + +message ScBlocSyncLevel { + string blocid = 1; + int32 level = 2; + int32 exp = 3; +} + +message CsBlocShopBuy { + string shopid = 1; + int32 posid = 2; + int32 count = 3; +} + +message ScBlocShopBuy { + string shopid = 2; + int32 posid = 3; + int32 count = 4; +} + +message ItemInfo { + string res_id = 1; + int32 res_count = 2; +} + +message CsCharLevelUp { + uint64 char_obj_i_d = 1; + repeated ItemInfo items = 2; +} + +message ScCharLevelUp { + uint64 char_obj_i_d = 1; +} + +message ScCharSyncLevelExp { + uint64 char_obj_i_d = 1; + int32 level = 2; + int32 exp = 3; +} + +message CsCharSetNormalSkill { + uint64 char_obj_i_d = 1; + string normal_skillid = 2; +} + +message ScCharSetNormalSkill { + uint64 char_obj_i_d = 1; + string normal_skillid = 2; +} + +message ScCharSetTeamSkill { + uint64 objid = 1; + int32 team_idx = 2; + string normal_skillid = 3; +} + +message ScCharUnlockSkill { + uint64 objid = 1; + SkillLevelInfo level_info = 2; +} + +message ScCharGainExpToast { + int32 exp = 1; + int32 exp_type = 2; +} + +message ScCharSyncStatus { + uint64 objid = 1; + bool is_dead = 2; + BattleInfo battle_info = 3; +} + +message CsCharPotentialUnlock { + uint64 char_obj_id = 1; + uint32 level = 2; + int32 item_id = 3; +} + +message ScCharPotentialUnlock { + uint64 char_obj_id = 1; + uint32 level = 2; +} + +message ScCharSkillInfos { + uint64 char_obj_id = 1; + repeated SkillLevelInfo level_infos = 2; +} + +message CsCharSkillLevelUp { + uint64 char_obj_id = 1; + string skill_id = 2; + int32 skill_type = 3; +} + +message ScCharSkillLevelUp { + uint64 char_obj_id = 1; + SkillLevelInfo level_info = 2; +} + +message CsCharUnlockTalentNode { + uint64 char_obj_id = 1; + string node_id = 2; +} + +message ScCharUnlockTalentNode { + uint64 char_obj_id = 1; + string node_id = 2; +} + +message CharInfo { + uint64 objid = 1; + string templateid = 2; + int32 level = 3; + int32 exp = 4; + map equip_col = 6; + string normal_skill = 7; + bool is_dead = 8; + BattleInfo battle_info = 9; + SkillInfo skill_info = 10; + map equip_suit = 11; + uint64 weapon_id = 12; + int64 own_time = 13; + int32 equip_medicine_id = 14; + uint32 potential_level = 15; + Talent talent = 16; + BattleMgrInfo battle_mgr_info = 17; + CharType char_type = 18; + TrialCharData trial_data = 19; +} + +message SkillInfo { + repeated SkillLevelInfo level_info = 1; + string normal_skill = 2; + string ultimate_skill = 3; + string combo_skill = 4; + string disp_normal_attack_skill = 5; +} + +enum CharType { + default_type = 0; + trial_type = 1; +} + +message CsCharBagSetTeam { + int32 team_index = 1; + repeated uint64 char_team = 2; + uint64 leader_id = 3; +} + +message CsCharBagSetCurrTeamIndex { + int32 team_index = 1; + uint64 leader_id = 2; +} + +message CsCharBagSetTeamName { + int32 team_index = 1; + string team_name = 2; +} + +message CsCharBagTeamChangeFinish { + uint64 team_change_token = 1; +} + +message CsCharBagSetTeamLeader { + CharBagTeamType team_type = 1; + int32 team_index = 2; + uint64 leaderid = 3; +} + +enum CharBagTeamType { + CHAR_BAG_TEAM_TYPE_MAIN = 0; + CHAR_BAG_TEAM_TYPE_TEMP = 1; +} + +message ScCharBagRemoveTrialCharacter { + int32 scope_name = 1; +} + +message ScCharBagSetTeam { + CharBagTeamType team_type = 1; + int32 team_index = 2; + uint64 leader_id = 5; + repeated uint64 char_team = 3; + int32 scope_name = 4; +} + +message CharTeamMemberInfo { + string normal_skillid = 1; +} + +message CharTeamInfo { + string team_name = 1; + repeated uint64 char_team = 2; + uint64 leaderid = 3; +} + +message ScSyncCharBagInfo { + repeated CharInfo char_info = 1; + repeated CharTeamInfo team_info = 2; + int32 curr_team_index = 3; + uint32 max_char_team_member_count = 4; + CharTeamInfo temp_team_info = 5; + int32 scope_name = 10; + bool is_scope_delete = 11; +} + +message ScCharBagAddChar { + CharInfo char = 1; + int32 scope_name = 2; +} + +message ScCharBagSetTeamName { + int32 team_index = 1; + string team_name = 2; + int32 scope_name = 3; +} + +message ScCharBagSetTeamLeader { + CharBagTeamType team_type = 1; + int32 team_index = 2; + uint64 leaderid = 3; + int32 scope_name = 4; +} + +message ScCharBagSetMaxTeamMemberCount { + uint32 max_char_team_member_count = 1; + int32 scope_name = 2; +} + +message ScCharBagTeamLeaderNotMatchNtf { + CharBagTeamType team_type = 1; + int32 team_index = 2; + uint64 leaderid = 3; + int32 scope_name = 4; +} + +message ScCharBagDelChar { + uint64 char_inst_id = 1; + int32 scope_name = 2; +} + +message ScCharBagAddCharWithConversionNotify { + string char_template_id = 1; + int32 scope_name = 2; + bool is_converted = 3; + string converted_item_id = 4; + string converted_reward_id = 5; + int32 source_reason = 6; +} + +message SceneCollection { + string scene_name = 1; + string prefab_id = 2; + int32 count = 3; +} + +message ScSceneCollectionSync { + repeated SceneCollection collection_list = 1; +} + +message ScSceneCollectionModify { + string scene_name = 1; + string prefab_id = 2; + int32 count = 3; +} + +message Dialog { + int32 dialog_id = 1; + repeated int32 option_ids = 2; + repeated int32 finish_nums = 3; +} + +message CsFinishDialog { + int32 dialog_id = 1; + repeated int32 option_ids = 2; + repeated int32 finish_nums = 3; +} + +message ScFinishDialog { + int32 dialog_id = 1; + repeated int32 option_ids = 2; + repeated int32 finish_nums = 3; +} + +message ScSyncAllDialog { + repeated Dialog dialog_list = 1; +} + +message CsEnterDungeon { + repeated TeamCharId char_team = 1; + string dungeon_id = 2; + EnterRacingDungeonParam racing_param = 10; +} + +message EnterRacingDungeonParam { + int32 level = 1; + string tactics_id = 2; +} + +message CsEnterTrainDungeon { + repeated TeamCharId char_team = 1; + string dungeon_id = 2; + EnterRacingDungeonParam racing_param = 10; +} + +message CsRestartDungeon { + string dungeon_id = 1; +} + +message CsLeaveDungeon { + string dungeon_id = 1; +} + +message CsDungeonRecoverAp { + repeated ItemBundle items = 1; + bool use_money = 2; +} + +message CsDungeonTouchEntrance { + string dungeon_series_id = 1; +} + +message ScEnterDungeon { + string dungeon_id = 3; + string scene_id = 4; +} + +message ScRestartDungeon { + string dungeon_id = 1; +} + +message ScLeaveDungeon { + string dungeon_id = 1; +} + +message ScSyncStamina { + uint32 cur_stamina = 1; + uint32 max_stamina = 2; + int64 next_recover_time = 3; + int32 delta = 4; +} + +message ScSyncFullDungeonStatus { + uint32 cur_stamina = 1; + uint32 max_stamina = 2; + int64 next_recover_time = 3; +} + +message CsEquipPuton { + uint64 charid = 1; + int32 slotid = 2; + uint64 equipid = 3; +} + +message ScEquipPuton { + uint64 charid = 1; + int32 slotid = 2; + uint64 equipid = 3; + map suitinfo = 4; + uint64 put_off_charid = 5; + map old_owner_suitinfo = 6; +} + +message CsEquipPutoff { + uint64 charid = 1; + int32 slotid = 2; +} + +message ScEquipPutoff { + uint64 charid = 1; + int32 slotid = 2; + map suitinfo = 3; +} + +message CsEquipMedicineModify { + uint64 char_id = 1; + int32 equip_medicine_id = 2; +} + +message ScEquipMedicineModify { + uint64 char_id = 1; + int32 equip_medicine_id = 2; +} + +message CsEquipRecycle { + repeated uint64 equip_instid_list = 1; + int32 scope_name = 2; +} + +message ScEquipRecycle { + repeated uint64 equip_instid_list = 1; + repeated string item_id = 2; + repeated int32 item_count = 3; + int32 scope_name = 4; +} + +message CsEquipEnhance { + uint64 equip_inst_id = 1; + uint64 ingredient_inst_id = 2; + uint32 attr_index = 3; +} + +message ScEquipEnhance { + uint64 equip_inst_id = 1; + repeated uint32 enhance = 2; + repeated EquipAttr enhance_attrs = 3; + EquipAttr base_attr = 4; +} + +message CsEquipProduce { + string formula_id = 1; +} + +message ScEquipProduce { + string formula_id = 1; + uint64 equip_instid = 2; +} + +message ScdFactorySttNode { + string id = 1; + int32 state = 2; + map values = 3; + map flags = 4; +} + +message ScdFactorySttPackage { + string id = 1; + int32 state = 2; + map values = 3; + map flags = 4; + bool hidden = 5; +} + +message ScdFactorySttLayer { + string id = 1; + int32 state = 2; +} + +message ScdFactorySyncStt { + repeated ScdFactorySttNode nodes = 1; + repeated ScdFactorySttPackage packages = 2; + repeated ScdFactorySttLayer layers = 3; +} + +message ScdFactorySyncFormulaMan { + repeated string unlocked = 1; + repeated string visible = 2; + map modes = 3; + repeated string level_up = 4; + repeated string product_manual = 5; +} + +message ScdFactorySyncFormulaMode { + repeated string building_ids = 1; +} + +message ScdFactorySyncQuickbar { + int32 type = 1; + repeated string list = 2; +} + +message ScFactorySync { + ScdFactorySyncFormulaMan formula_man = 1; + ScdFactorySyncStt stt = 2; +} + +message ScFactoryModifyFormulaMan { + repeated string new_unlocked = 1; + repeated string new_product_manual = 2; + repeated string new_level_up = 3; +} + +message ScFactoryModifyStt { + repeated ScdFactorySttNode nodes = 1; + repeated ScdFactorySttPackage packages = 2; + repeated ScdFactorySttLayer layers = 3; +} + +message FactoryFormulaVisiable { + repeated string formula_list = 1; + repeated string output_list = 2; + repeated string source = 3; + FactoryFormulaVisibleReason reason = 4; +} + +enum FactoryFormulaVisibleReason { + VISIBLE_REASON_GET_NEW_ITEM = 0; + VISIBLE_REASON_UNLOCK = 1; + VISIBLE_REASON_ITEM_VISIBLE = 2; + VISIBLE_REASON_NEW_BUILDING = 3; + VISIBLE_REASON_NEW_BUILDING_MODE = 4; + VISIBLE_REASON_NEW_FORMULA_DONE = 5; +} + +message ScFactoryModifyVisibleFormula { + FactoryFormulaVisiable new_visible = 1; +} + +message ScFactoryModifyFormulaMode { + string mode = 1; + repeated string new_building_ids = 2; +} + +message ScFactorySyncScope { + int32 scope_name = 1; + string current_chapter_id = 2; + repeated ScdFactorySyncQuickbar quickbars = 4; + ScdFactorySyncHubTransportRouteManager transport_route = 5; + ScdFactoryStatisticBookmark book_mark = 6; +} + +message ScdFactorySyncHubTransportRouteManager { + int64 update_ts = 1; + repeated ScdFactoryHubTransportRoute routes = 2; +} + +message ScdFactoryHubTransportRoute { + string chapter_id = 1; + int32 index = 2; + string target_chapter_id = 3; + string item_id = 4; + int32 item_num = 5; + int32 item_num_max = 6; + int32 status = 7; + int64 progress = 8; +} + +message ScdFactoryStatisticBookmark { + repeated string bookmark_item_ids = 1; +} + +message CsFactoryStatisticSetBookmarkItemIds { + repeated string item_ids = 1; + bool is_remove = 2; + int32 scope_name = 11; +} + +message ScFactoryModifyStatisticBookmark { + ScdFactoryStatisticBookmark book_mark = 1; + int32 scope_name = 11; +} + +message CsFactoryHubTransportRouteSet { + int32 scope_name = 1; + string chapter_id = 2; + int32 index = 3; + string target_chapter_id = 4; + string item_id = 5; + int32 item_num_max = 6; +} + +message CsFactoryHubTransportRouteReset { + int32 scope_name = 1; + string chapter_id = 2; + int32 index = 3; +} + +message CsFactoryHubTransportRouteRestart { + int32 scope_name = 1; + string chapter_id = 2; + int32 index = 3; +} + +message ScFactoryHubTransportRouteModify { + ScdFactorySyncHubTransportRouteManager transport_route_modified = 1; +} + +message ScFactoryReleaseScope { + int32 scope_name = 1; + repeated string delete_chapter_id_list = 11; +} + +message ScFactoryModifyScope { + int32 scope_name = 1; + string current_chapter_id = 2; + repeated string delete_chapter_id_list = 11; +} + +message ScFactoryModifyQuickbar { + int32 scope_name = 1; + repeated ScdFactorySyncQuickbar quickbars = 2; +} + +message ScFactorySoilReclaim { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + bool result = 4; +} + +message ScFactorySoilWater { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + bool result = 4; +} + +message ScFactorySoilHarvest { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + bool result = 4; +} + +message ScFactorySoilCancel { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + bool result = 4; +} + +message CsFactorySttUnlockLayer { + string layer_id = 1; +} + +message CsFactorySttUnlockNode { + string node_id = 1; +} + +message CsFactoryQuickbarSetOne { + int32 scope_name = 1; + int32 type = 2; + int32 index = 3; + string item_id = 4; +} + +message CsFactoryQuickbarMoveOne { + int32 scope_name = 1; + int32 type = 2; + int32 from_index = 3; + int32 to_index = 4; +} + +message CsFactorySoilReclaim { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + uint64 char_object_id = 4; +} + +message CsFactorySoilWater { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + uint64 char_object_id = 4; +} + +message CsFactorySoilHarvest { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; + uint64 char_object_id = 4; +} + +message CsFactorySoilCancel { + int32 scope_name = 1; + string chapter_id = 2; + uint32 node_id = 3; +} + +message CsFactorySoilFarmlandLevelUp { + int32 scope_name = 1; + string chapter_id = 2; + string scene_name = 3; + int32 index = 4; + int32 to_level = 5; +} + +message ScFactorySyncOfflineInfo { + int64 max_offline_calc_sec = 1; + int64 end_offline_calc_ts = 2; + int64 offline_sec = 3; + int64 miss_offline_sec = 4; +} + +message CsFactoryHubWorkshopMake { + int32 scope_name = 1; + uint32 node_id = 2; + string formula_id = 3; + int32 multi = 4; +} + +message ScFactoryHubWorkshopMake { + bool success = 1; +} + +message CsFactoryProductManualUnlock { + int32 scope_name = 1; + repeated string id_list = 2; +} + +message ScFactoryProductManualUnlock { + int32 scope_name = 1; + repeated string id_list = 2; +} + +message CsFactoryManuallyWorkExec { + int32 scope_name = 1; + string formula_id = 2; + int32 count = 3; +} + +message ScFactoryManuallyWorkExec { + int32 scope_name = 1; + string formula_id = 2; + int32 count = 3; +} + +message ScdVec3Int { + int32 x = 1; + int32 y = 2; + int32 z = 3; +} + +message ScdRectInt { + int32 x = 1; + int32 y = 2; + int32 z = 3; + int32 l = 4; + int32 w = 5; + int32 h = 6; +} + +message ScdFacSubPort { + ScdVec3Int position = 1; + ScdVec3Int direction = 2; +} + +message ScdFactorySyncItem { + string id = 1; + int32 count = 2; + int64 tms = 11; +} + +message ScdFacFluidReactionFormula { + string formula_id = 1; + int64 current_progress = 2; + bool in_block = 3; +} + +message ScdFactoryHsCt { + uint32 component_id = 1; + repeated uint32 item_in = 2; + repeated uint32 item_out = 3; + repeated int32 index_in = 4; + repeated int32 index_out = 5; +} + +message ScdFactoryHsFb { + uint32 component_id = 1; + oneof component_payload { + ScdFactoryHsFbCache cache = 2; + ScdFactoryHsFbProducer producer = 3; + ScdFactoryHsFbCollector collector = 4; + ScdFactoryHsFbBurnPower burn_power = 5; + ScdFactoryHsFbCacheTransport cache_transport = 6; + ScdFactoryHsFbGridBox grid_box = 7; + ScdFactoryHsFbBoxRouterM1 box_router_m1 = 8; + ScdFactoryHsFbBoxBridge box_bridge = 9; + ScdFactoryHsFbFluidBridge fluid_bridge = 12; + ScdFactoryHsFbFluidRouterM1 fluid_router_m1 = 13; + ScdFactoryHsFbFluidContainer fluid_container = 14; + ScdFactoryHsFbFluidPumpIn fluid_pump_in = 15; + ScdFactoryHsFbBattle battle = 16; + ScdFactoryHsFbBatteryBurn battery_burn = 17; + ScdFactoryHsFbFluidSpray fluid_spray = 18; + ScdFactoryHsFbFluidPumpOut fluid_pump_out = 19; + ScdFactoryHsFbFluidConsume fluid_consume = 20; + ScdFactoryHsFbFluidReaction fluid_reaction = 21; + ScdFactoryHsFbWaterCollector water_collector = 22; + } +} + +message ScdFactoryHsFbCache { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbProducer { + int64 progress_incr_per_ms = 1; + string formula_id = 2; + int64 current_progress = 3; +} + +message ScdFactoryHsFbCollector { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; +} + +message ScdFactoryHsFbBurnPower { + int64 progress_decr_per_ms = 1; + int64 current_least_progress = 2; +} + +message ScdFactoryHsFbCacheTransport { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; +} + +message ScdFactoryHsFbGridBox { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbBoxRouterM1 { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbBoxBridge { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbFluidBridge { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbFluidRouterM1 { + repeated uint32 items = 1; +} + +message ScdFactoryHsFbFluidContainer { + repeated uint32 items = 1; + bool infinite = 2; +} + +message ScdFactoryHsFbFluidPumpIn { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; +} + +message ScdFactoryHsFbBattle { + int32 energy_current = 1; + int32 energy_max = 2; + bool in_overloading = 3; +} + +message ScdFactoryHsFbBatteryBurn { + int32 energy_loaded = 1; + int32 energy_current = 2; +} + +message ScdFactoryHsFbFluidSpray { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; + int32 last_round_spray_count = 3; +} + +message ScdFactoryHsFbFluidPumpOut { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; + int32 last_round_pump_count = 3; +} + +message ScdFactoryHsFbFluidConsume { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; +} + +message ScdFactoryHsFbFluidReaction { + repeated ScdFacFluidReactionFormula formulas = 1; + int64 progress_incr_per_ms = 2; +} + +message ScdFactoryHsFbWaterCollector { + int64 progress_incr_per_ms = 1; + int64 current_progress = 2; +} + +message ScdFactoryHsCe { + ScdFactoryHsCeEventtype event_type = 1; + repeated uint32 event_param = 2; +} + +enum ScdFactoryHsCeEventtype { + SCD_FACTORY_HS_CE_None = 0; + SCD_FACTORY_HS_CE_InPowerUp = 1; + SCD_FACTORY_HS_CE_InPowerDown = 2; + SCD_FACTORY_HS_CE_FluidHeightChange = 3; + SCD_FACTORY_HS_CE_FluidContentChange = 4; + SCD_FACTORY_HS_CE_ProducerChangeFormula = 5; + SCD_FACTORY_HS_CE_BusLoaderChangeLastPutIn = 6; + SCD_FACTORY_HS_CE_BattleEnergyChange = 7; + SCD_FACTORY_HS_CE_JoinWorking = 8; + SCD_FACTORY_HS_CE_LeaveWorking = 9; + SCD_FACTORY_HS_CE_RegionPower = 10; + SCD_FACTORY_HS_CE_BlockComponent = 11; + SCD_FACTORY_HS_CE_UnBlockComponent = 12; + SCD_FACTORY_HS_CE_SubPortBlock = 21; + SCD_FACTORY_HS_CE_SubPortUnBlock = 22; + SCD_FACTORY_HS_CE_ChangeProduct = 31; +} + +message ScdFactoryHsBb { + ScdFactoryHsBbPower power = 1; +} + +message ScdFactoryHsBbPower { + bool is_stop_by_power = 1; + int64 power_cost_sum = 2; + int64 power_save_max = 3; + int64 power_save_current = 4; + int64 power_gen_last_sec = 5; +} + +message ScdFacCom { + uint32 component_id = 1; + int32 component_type = 2; + oneof component_payload { + ScdFacComPortManager port_manager = 9; + ScdFacComInventory inventory = 10; + ScdFacComCache cache = 11; + ScdFacComSelector selector = 12; + ScdFacComCollector collector = 13; + ScdFacComProducer producer = 14; + ScdFacComBoxConveyor box_conveyor = 15; + ScdFacComBoxRouterM1 box_router_m1 = 16; + ScdFacComBurnPower burn_power = 17; + ScdFacComCacheTransport cache_transport = 18; + ScdFacComStablePower stable_power = 19; + ScdFacComPowerPole power_pole = 20; + ScdFacComPowerSave power_save = 22; + ScdFacComBusLoader bus_loader = 23; + ScdFacComTravelPole travel_pole = 24; + ScdFacComGridBox grid_box = 25; + ScdFacComBoxBridge box_bridge = 26; + ScdFacComBattle battle = 27; + ScdFacComFluidConveyor fluid_conveyor = 28; + ScdFacComFluidBridge fluid_bridge = 29; + ScdFacComFluidRouterM1 fluid_router_m1 = 30; + ScdFacComFormulaMan formula_man = 31; + ScdFacComFluidContainer fluid_container = 32; + ScdFacComFluidPumpIn fluid_pump_in = 33; + ScdFacComBatteryBurn battery_burn = 34; + ScdFacComSubHub sub_hub = 35; + ScdFacComWaterCollector water_collector = 36; + ScdFacComSoil soil = 37; + ScdFacComFluidSpray fluid_spray = 38; + ScdFacComFluidPumpOut fluid_pump_out = 39; + ScdFacComFluidConsume fluid_consume = 40; + ScdFacComFluidReaction fluid_reaction = 41; + } +} + +message ScdFacComPortManager { + repeated ScdFacComSubPort ports = 1; +} + +message ScdFacComSubPort { + int32 index = 1; + uint32 owner_com_id = 2; + uint32 touch_com_id = 3; + bool in_block = 4; +} + +message ScdFacComInventory { + map items = 1; +} + +message ScdFacComCache { + repeated ScdFactorySyncItem items = 1; + int32 size = 2; +} + +message ScdFacComSelector { + string selected_item_id = 1; +} + +message ScdFacComCollector { + repeated ScdFactorySyncItem items_round = 1; + int64 current_progress = 2; + bool in_block = 4; +} + +message ScdFacComProducer { + string formula_id = 1; + int64 current_progress = 2; + bool in_block = 4; + bool in_produce = 5; + string last_formula_id = 11; +} + +message ScdFacComBoxConveyor { + int64 last_pop_tms = 1; + repeated ScdFactorySyncItem items = 2; +} + +message ScdFacComBoxRouterM1 { + ScdFactorySyncItem hold_item = 1; + bool m_in = 2; +} + +message ScdFacComBurnPower { + int64 current_least_progress = 1; + string current_burn_item_id = 2; + int64 power_gen_per_sec = 3; +} + +message ScdFacComCacheTransport { + int64 current_progress = 1; + int64 total_progress = 2; + bool auto_transport = 3; + bool in_use = 5; +} + +message ScdFacComStablePower { + int64 power_gen_per_sec = 3; +} + +message ScdFacComPowerPole { +} + +message ScdFacComPowerSave { + int64 power_save = 1; +} + +message ScdFacComBusLoader { + string last_putin_item_id = 1; +} + +message ScdFacComTravelPole { + uint32 default_next = 11; +} + +message ScdFacComGridBox { + repeated ScdFactorySyncItem items = 1; +} + +message ScdFacComBoxBridge { + ScdFactorySyncItem hold_item = 1; +} + +message ScdFacComBattle { + int32 energy_current = 1; + int32 energy_max = 2; + bool in_overloading = 3; +} + +message ScdFacComFluidConveyor { + string item_id = 1; + int32 fluid_height = 2; + repeated int64 box_tms_list = 3; +} + +message ScdFacComFluidBridge { + ScdFactorySyncItem hold_item = 1; +} + +message ScdFacComFluidRouterM1 { + ScdFactorySyncItem hold_item = 1; + bool m_in = 2; +} + +message ScdFacComFormulaMan { + repeated string formula_ids = 1; + string locked_formula_id = 2; + string current_mode = 11; + string current_group = 12; +} + +message ScdFacComFluidContainer { + ScdFactorySyncItem hold_item = 1; + bool infinite = 2; +} + +message ScdFacComFluidPumpIn { + ScdFactorySyncItem item_round = 1; + int64 current_progress = 2; + string source_inst_key = 3; + bool in_block = 4; + bool in_produce = 5; +} + +message ScdFacComBatteryBurn { + int32 energy_loaded = 1; + int32 energy_current = 2; +} + +message ScdFacComSubHub { + int32 level = 1; +} + +message ScdFacComWaterCollector { + repeated ScdFactorySyncItem items_round = 1; + int64 current_progress = 2; + bool in_block = 4; + bool in_produce = 5; +} + +message ScdFacComSoil { + int32 step_cursor = 1; + int32 water_got = 2; + int64 in_grow_tms = 3; +} + +message ScdFacComFluidSpray { + int64 current_progress = 1; + bool in_produce = 2; + int32 last_round_spray_count = 3; + bool in_block = 11; +} + +message ScdFacComFluidPumpOut { + int32 round_count = 1; + int64 current_progress = 2; + string target_inst_key = 3; + bool in_block = 4; + bool in_produce = 5; +} + +message ScdFacComFluidConsume { + int32 round_count = 1; + int64 current_progress = 2; + bool in_block = 3; + bool in_produce = 4; + string latest_item_id = 5; +} + +message ScdFacComFluidReaction { + repeated ScdFacFluidReactionFormula formulas = 1; + bool in_block = 2; + bool in_produce = 3; +} + +message ScdFacNode { + uint32 node_id = 1; + int32 node_type = 2; + string template_id = 3; + ScdFacTransform transform = 4; + bool is_deactive = 5; + ScdFacInteractiveObject interactive_object = 6; + ScdFacDynamicProperty dynamic_property = 7; + ScdFacNodePower power = 8; + string inst_key = 9; + uint32 flag = 10; + map component_pos = 11; + repeated ScdFacCom components = 12; + uint64 stable_id = 13; +} + +message ScdFacTransform { + ScdVec3Int position = 1; + ScdVec3Int direction = 2; + ScdFacMesh mesh = 3; + int32 map_id = 4; + Vector world_position = 9; + Vector world_rotation = 10; + ScdFacSubPort bc_port_in = 11; + ScdFacSubPort bc_port_out = 12; +} + +message ScdFacMesh { + int32 mesh_type = 1; + repeated ScdVec3Int points = 2; +} + +message ScdFacInteractiveObject { + uint64 object_id = 1; +} + +message ScdFacDynamicProperty { + map values = 1; +} + +message ScdFacDynamicPropertyValue { + oneof value { + bool bool_value = 1; + int64 int_value = 2; + uint64 uint_value = 3; + double double_value = 4; + string string_value = 5; + } +} + +message ScdFacNodePower { + bool in_power = 1; + int64 power_cost = 2; + bool need_in_power = 11; + int64 power_cost_show = 12; +} + +message ScdFactorySyncScene { + int32 scene_id = 1; + ScdFactorySyncSceneBandwidth bandwidth = 5; + repeated ScdFactorySyncScenePanel panels = 6; + repeated ScdFactorySyncScenePanel soil_panels = 7; + map settlements = 10; +} + +message ScdFactorySyncSceneBandwidth { + int32 current = 1; + int32 max = 2; + int32 travel_pole_current = 3; + int32 travel_pole_max = 4; + int32 battle_current = 5; + int32 battle_max = 6; + int32 sp_current = 11; + int32 sp_max = 12; +} + +message ScdFactorySyncScenePanel { + int32 index = 1; + int32 level = 2; + repeated ScdRectInt main_mesh = 3; +} + +message ScdFactorySyncMap { + int32 map_id = 1; + repeated ScdFactorySyncMapWire wires = 2; +} + +message ScdFactorySyncMapWire { + uint64 index = 1; + uint64 from_com_id = 2; + uint64 to_com_id = 3; +} + +message ScdFactorySyncBlackboard { + uint32 inventory_node_id = 1; + ScdFactorySyncBlackboardPower power = 11; +} + +message ScdFactorySyncBlackboardPower { + int64 power_cost = 1; + int64 power_gen = 2; + int64 power_save_max = 3; + int64 power_save_current = 4; + bool is_stop_by_power = 5; +} + +message ScdFactoryStatisticLastday { + repeated ScdFactoryStatisticLastdayDay days = 1; +} + +message ScdFactoryStatisticLastdayDay { + int64 day_ts = 1; + map from_productivity = 2; +} + +message ScdFactoryStatisticOther { + int32 power_net_length_sum = 1; + int32 in_power_building = 2; + float power_net_coverage = 3; +} + +message ScdFactoryStatisticRecord { + int32 rank = 1; + repeated int64 points_gen = 2; + repeated int64 points_cost = 3; +} + +message ScdFactorySyncPinBoard { + repeated ScdFactoryPinCard cards = 1; +} + +message ScdFactoryPinCard { + int32 pos = 1; + string str_id = 2; + uint64 num_id = 3; +} + +message ScFactorySyncChapter { + int64 tms = 1; + string chapter_id = 2; + repeated ScdFacNode nodes = 3; + repeated ScdFactorySyncScene scenes = 4; + ScdFactorySyncBlackboard blackboard = 5; + ScdFactorySyncPinBoard pin_board = 6; + repeated ScdFactorySyncMap maps = 7; + ScdFactorySyncStatistic statistic = 9; +} + +message ScdFactorySyncStatistic { + ScdFactoryStatisticOther other = 3; + ScdFactoryStatisticLastday last_day = 4; +} + +message ScFactoryModifyChapterNodes { + int64 tms = 1; + string chapter_id = 2; + repeated ScdFacNode nodes = 3; + repeated uint32 remove_nodes = 4; +} + +message ScFactoryModifyChapterComponents { + int64 tms = 1; + string chapter_id = 2; + repeated ScdFacCom components = 3; +} + +message ScFactoryModifyChapterMap { + int64 tms = 1; + string chapter_id = 2; + int32 map_id = 3; + repeated ScdFactorySyncMapWire wires = 11; + repeated uint64 remove_wires = 12; +} + +message ScFactoryModifyChapterScene { + int64 tms = 1; + string chapter_id = 2; + int32 scene_id = 3; + ScdFactorySyncSceneBandwidth bandwidth = 13; + repeated ScdFactorySyncScenePanel panels = 14; + repeated ScdFactorySyncScenePanel soil_panels = 15; + map settlements = 20; +} + +message ScFactoryModifyChapterBlackboard { + int64 tms = 1; + string chapter_id = 2; + ScdFactorySyncBlackboard blackboard = 3; +} + +message ScFactoryModifyChapterPinBoard { + int64 tms = 1; + string chapter_id = 2; + repeated ScdFactoryPinCard modified = 3; + repeated int32 release_pos = 4; +} + +message ScFactoryHs { + int64 tms = 1; + repeated ScdFactoryHsCt ct_list = 2; + repeated ScdFactoryHsFb fb_list = 3; + repeated ScdFactoryHsCe ce_list = 4; + ScdFactoryHsBb blackboard = 5; + string chapter_id = 11; +} + +message ScFactoryHsSync { + int64 tms = 1; + repeated ScdFacCom cc_list = 2; + repeated ScdFactoryHsFb fb_list = 3; + ScdFactorySyncBlackboard blackboard = 4; + string chapter_id = 11; +} + +message ScFactoryModifyStatistic { + string chapter_id = 1; + ScdFactoryStatisticOther other = 3; + ScdFactoryStatisticLastday last_day = 4; +} + +message ScFactoryStatisticRequire { + string chapter = 1; + ScdFactoryStatisticRecord power = 2; + map productivity = 3; +} + +message CsFactoryHsFb { + string chapter_id = 1; + repeated uint32 node_id_list = 21; + bool undo = 3; +} + +message CsFactoryStatisticRequire { + int32 rank_power = 1; + int32 rank_productivity = 2; + repeated string productivity_item_ids = 3; + bool all_productivity = 4; + string chapter_id = 12; +} + +message CsFactoryPinSet { + int32 scope_name = 1; + int32 pos = 3; + string str_id = 4; + uint64 num_id = 5; + bool release = 11; +} + +message CsFactoryObserverOp { + string index = 1; + string chapter_id = 2; + int32 map_id = 3; + uint32 node_id = 4; + uint64 node_stable_id = 5; + uint32 component_id = 6; + string op_type = 11; + oneof op_payload { + CsdFactoryObserverPayloadOpCheckoutRelationBoard checkout_relation_board = 21; + CsdFactoryObserverPayloadOpCheckoutPowerConnectionMap checkout_power_connection_map = 22; + CsdFactoryObserverPayloadOpCheckoutOutsideResource checkout_outside_resource = 23; + } +} + +message CsdFactoryObserverPayloadOpCheckoutRelationBoard { +} + +message CsdFactoryObserverPayloadOpCheckoutPowerConnectionMap { +} + +message CsdFactoryObserverPayloadOpCheckoutOutsideResource { +} + +message ScFactoryObserverRet { + string op_index = 1; + bool success = 2; + string err_message = 3; + string chapter_id = 4; + string ret_type = 11; + oneof ret_payload { + ScdFactoryObserverPayloadRetCheckoutRelationBoard checkout_relation_board = 21; + ScdFactoryObserverPayloadRetCheckoutPowerConnectionMap checkout_power_connection_map = 22; + ScdFactoryObserverPayloadRetCheckoutOutsideResource checkout_outside_resource = 23; + } +} + +message ScdFactoryObserverPayloadRetCheckoutRelationBoard { + repeated ScdFactoryObserverPayloadRetCheckoutRelationBoardConveyorElem conveyor_elems = 1; +} + +message ScdFactoryObserverPayloadRetCheckoutRelationBoardConveyorElem { + uint32 conveyor_com_id = 1; + uint32 conveyor_node_id = 2; + uint32 from_com_id = 11; + uint32 from_node_id = 12; + uint64 from_node_stable_id = 13; + string from_node_template_id = 14; + uint32 to_com_id = 21; + uint32 to_node_id = 22; + uint64 to_node_stable_id = 23; + string to_node_template_id = 24; +} + +message ScdFactoryObserverPayloadRetCheckoutPowerConnectionMap { + repeated ScdFactoryObserverPayloadRetCheckoutPowerConnectionMapConnection connections = 1; + repeated ScdFactoryObserverPayloadRetCheckoutPowerConnectionMapNodeElem node_elems = 2; +} + +message ScdFactoryObserverPayloadRetCheckoutPowerConnectionMapConnection { + uint64 index = 1; + uint32 from_com_id = 11; + uint32 from_node_id = 12; + uint64 from_node_stable_id = 13; + string from_node_template_id = 14; + uint32 to_com_id = 21; + uint32 to_node_id = 22; + uint64 to_node_stable_id = 23; + string to_node_template_id = 24; +} + +message ScdFactoryObserverPayloadRetCheckoutPowerConnectionMapNodeElem { + uint32 node_id = 1; + uint64 node_stable_id = 2; + string node_template_id = 3; + uint32 com_id = 4; + uint64 logic_id = 7; + int32 distance = 11; + repeated uint32 neighbors = 12; +} + +message ScdFactoryObserverPayloadRetCheckoutOutsideResource { + map place_bandwidth = 1; + map place_bandwidth_use = 2; + repeated ScdFactoryObserverPayloadRetCheckoutOutsideResourceNodeUse place_bandwidth_node_uses = 3; + map place_bandwidth_sp = 11; + map place_bandwidth_sp_use = 12; + repeated ScdFactoryObserverPayloadRetCheckoutOutsideResourceNodeUse place_bandwidth_sp_node_uses = 13; +} + +message ScdFactoryObserverPayloadRetCheckoutOutsideResourceNodeUse { + uint32 node_id = 1; + string scene_name = 2; + int32 use = 3; +} + +message CsFactoryOp { + string index = 1; + FactoryOpType op_type = 2; + string chapter_id = 3; + oneof op_payload { + CsdFactoryOpPlace place = 11; + CsdFactoryOpPlaceConveyor place_conveyor = 12; + CsdFactoryOpDismantle dismantle = 13; + CsdFactoryOpSetSelectTarget set_select_target = 15; + CsdFactoryOpEnableNode enable_node = 16; + CsdFactoryOpMoveNode move_node = 17; + CsdFactoryOpDismantleBoxConveyor dismantle_box_conveyor = 18; + CsdFactoryOpRepairNode repair_node = 19; + CsdFactoryOpMoveItemCacheToCache move_item_cache_to_cache = 20; + CsdFactoryOpMoveItemBagToCache move_item_bag_to_cache = 21; + CsdFactoryOpMoveItemCacheToBag move_item_cache_to_bag = 22; + CsdFactoryOpMoveItemDepotToCache move_item_depot_to_cache = 23; + CsdFactoryOpMoveItemCacheToDepot move_item_cache_to_depot = 24; + CsdFactoryOpMoveItemConveyorToBag move_item_conveyor_to_bag = 25; + CsdFactoryOpCacheTransportTransfer cache_transport_transfer = 26; + CsdFactoryOpCacheTransportEnable cache_transport_enable = 27; + CsdFactoryOpSetTravelPoleDefaultNext set_travel_pole_default_next = 28; + CsdFactoryOpUseHealTowerPoint use_heal_tower_point = 29; + CsdFactoryOpBattleRepair battle_repair = 30; + CsdFactoryOpAddConnection add_connection = 31; + CsdFactoryOpDelConnection del_connection = 32; + CsdFactoryOpGridBoxInnerMove grid_box_inner_move = 41; + CsdFactoryOpGridBoxInnerSplit grid_box_inner_split = 42; + CsdFactoryOpMoveItemBagToGridBox move_item_bag_to_grid_box = 43; + CsdFactoryOpMoveItemGridBoxToBag move_item_grid_box_to_bag = 44; + CsdFactoryOpMoveItemDepotToGridBox move_item_depot_to_grid_box = 45; + CsdFactoryOpMoveItemGridBoxToDepot move_item_grid_box_to_depot = 46; + CsdFactoryOpMoveAllCacheOutItemToBag move_all_cache_out_item_to_bag = 47; + CsdFactoryOpQuickPutBattery quick_put_battery = 48; + CsdFactoryOpChangeProducerMode change_producer_mode = 51; + CsdFactoryOpReverseFluidConveyorDirection reverse_fluid_conveyor_direction = 52; + CsdFactoryOpDismantleBatch dismantle_batch = 53; + CsdFactoryOpTakeOutFluidFromLiquidBody take_out_fluid_from_liquid_body = 61; + CsdFactoryOpPutInFluidToLiquidBody put_in_fluid_to_liquid_body = 62; + CsdFactoryOpFillingFluidComWithBag filling_fluid_com_with_bag = 63; + CsdFactoryOpFillingFluidComWithDepot filling_fluid_com_with_depot = 64; + } +} + +enum FactoryOpType { + NONE = 0; + PLACE = 1; + PLACE_CONVEYOR = 2; + DISMANTLE = 3; + SET_SELECT_TARGET = 5; + ENABLE_NODE = 6; + MOVE_NODE = 7; + DISMANTLE_BOX_CONVEYOR = 8; + REPAIR_NODE = 9; + MOVE_ITEM_CACHE_TO_CACHE = 10; + MOVE_ITEM_BAG_TO_CACHE = 11; + MOVE_ITEM_CACHE_TO_BAG = 12; + MOVE_ITEM_DEPOT_TO_CACHE = 13; + MOVE_ITEM_CACHE_TO_DEPOT = 14; + MOVE_ITEM_CONVEYOR_TO_BAG = 15; + CACHE_TRANSPORT_TRANSFER = 16; + CACHE_TRANSPORT_ENABLE = 17; + SET_TRAVEL_POLE_DEFAULT_NEXT = 18; + USE_HEAL_TOWER_POINT = 19; + BATTLE_REPAIR = 20; + ADD_CONNECTION = 21; + DEL_CONNECTION = 22; + GRID_BOX_INNER_MOVE = 31; + GRID_BOX_INNER_SPLIT = 32; + MOVE_ITEM_BAG_TO_GRID_BOX = 33; + MOVE_ITEM_GRID_BOX_TO_BAG = 34; + MOVE_ITEM_DEPOT_TO_GRID_BOX = 35; + MOVE_ITEM_GRID_BOX_TO_DEPOT = 36; + MOVE_ALL_CACHE_OUT_ITEM_TO_BAG = 37; + QUICK_PUT_BATTERY = 38; + CHANGE_PRODUCER_MODE = 41; + REVERSE_FLUID_CONVEYOR_DIRECTION = 42; + DISMANTLE_BATCH = 43; + TAKE_OUT_FLUID_FROM_LIQUID_BODY = 51; + PUT_IN_FLUID_TO_LIQUID_BODY = 52; + FILLING_FLUID_COM_WITH_BAG = 53; + FILLING_FLUID_COM_WITH_DEPOT = 54; +} + +message CsdFactoryOpPlace { + string template_id = 1; + ScdVec3Int position = 2; + ScdVec3Int direction = 3; + int32 map_id = 4; + CsdFactoryInteractiveParam interactive_param = 5; +} + +message CsdFactoryInteractiveParam { + Vector position = 1; + Vector rotation = 2; + map properties = 3; +} + +message CsdFactoryOpPlaceConveyor { + string template_id = 1; + ScdVec3Int direction_in = 2; + ScdVec3Int direction_out = 3; + repeated ScdVec3Int points = 4; + int32 map_id = 5; +} + +message CsdFactoryOpDismantle { + uint32 node_id = 1; +} + +message CsdFactoryOpSetSelectTarget { + uint32 component_id = 1; + string item_id = 2; +} + +message CsdFactoryOpEnableNode { + uint32 node_id = 1; + bool enable = 2; +} + +message CsdFactoryOpMoveNode { + uint32 node_id = 1; + ScdVec3Int position = 2; + ScdVec3Int direction = 3; + CsdFactoryInteractiveParam interactive_param = 5; +} + +message CsdFactoryOpDismantleBoxConveyor { + uint32 node_id = 1; + repeated int32 index_list = 2; +} + +message CsdFactoryOpRepairNode { + uint32 node_id = 1; +} + +message CsdFactoryOpMoveItemCacheToCache { + uint32 from_component_id = 1; + uint32 to_component_id = 2; + string item_id = 3; +} + +message CsdFactoryOpMoveItemBagToCache { + int32 grid_index = 1; + uint32 component_id = 2; + int32 cache_grid_index = 3; +} + +message CsdFactoryOpMoveItemCacheToBag { + uint32 component_id = 1; + string item_id = 2; + bool all = 3; + int32 cache_grid_index = 4; + int32 grid_index = 5; +} + +message CsdFactoryOpMoveItemDepotToCache { + string item_id = 1; + uint32 component_id = 2; + int32 cache_grid_index = 3; +} + +message CsdFactoryOpMoveItemCacheToDepot { + uint32 component_id = 1; + string item_id = 2; + bool all = 3; + int32 cache_grid_index = 4; +} + +message CsdFactoryOpMoveItemConveyorToBag { + uint32 component_id = 1; + int32 index = 2; + bool all = 3; +} + +message CsdFactoryOpCacheTransportTransfer { + uint32 component_id = 1; +} + +message CsdFactoryOpCacheTransportEnable { + uint32 component_id = 1; + bool enable = 2; +} + +message CsdFactoryOpSetTravelPoleDefaultNext { + uint32 component_id = 1; + uint32 default_next = 2; +} + +message CsdFactoryOpUseHealTowerPoint { + uint32 component_id = 1; + uint32 use_count = 2; +} + +message CsdFactoryOpBattleRepair { + uint32 node_id = 1; +} + +message CsdFactoryOpAddConnection { + int32 map_id = 1; + uint64 from_com_id = 4; + uint64 to_com_id = 5; +} + +message CsdFactoryOpDelConnection { + int32 map_id = 1; + uint64 index = 2; +} + +message CsdFactoryOpGridBoxInnerMove { + uint32 component_id = 1; + int32 from_index = 2; + int32 to_index = 3; +} + +message CsdFactoryOpGridBoxInnerSplit { + uint32 component_id = 1; + int32 from_index = 2; + int32 to_index = 3; + int32 count = 4; +} + +message CsdFactoryOpMoveItemBagToGridBox { + int32 bag_grid_index = 1; + uint32 component_id = 2; + int32 grid_box_index = 3; +} + +message CsdFactoryOpMoveItemGridBoxToBag { + uint32 component_id = 1; + int32 grid_box_index = 2; + int32 bag_grid_index = 3; +} + +message CsdFactoryOpMoveItemDepotToGridBox { + string item_id = 1; + uint32 component_id = 2; + int32 grid_box_index = 3; +} + +message CsdFactoryOpMoveItemGridBoxToDepot { + uint32 component_id = 1; + int32 grid_box_index = 2; +} + +message CsdFactoryOpMoveAllCacheOutItemToBag { + uint32 node_id = 1; +} + +message CsdFactoryOpQuickPutBattery { + uint32 com_id = 1; +} + +message CsdFactoryOpChangeProducerMode { + uint32 node_id = 1; + string to_mode = 2; +} + +message CsdFactoryOpReverseFluidConveyorDirection { + uint32 node_id = 1; +} + +message CsdFactoryOpDismantleBatch { + repeated CsdFactoryOpDismantle dismantles = 1; + repeated CsdFactoryOpDismantleBoxConveyor dismantle_conveyors = 2; +} + +message CsdFactoryOpTakeOutFluidFromLiquidBody { + string liquid_body_inst_key = 1; + repeated ItemBundle bottle_items = 4; +} + +message CsdFactoryOpPutInFluidToLiquidBody { + string liquid_body_inst_key = 1; + repeated ItemBundle bottle_water_items = 4; +} + +message CsdFactoryOpFillingFluidComWithBag { + uint32 component_id = 1; + int32 bag_grid_index = 2; +} + +message CsdFactoryOpFillingFluidComWithDepot { + uint32 component_id = 1; + string item_id = 2; +} + +message ScFactoryOpRet { + string index = 1; + FactoryOpRetCode ret_code = 2; + FactoryOpType op_type = 3; + string err_message = 4; + oneof op_payload { + ScdFactoryOpRetPlace place = 11; + ScdFactoryOpRetPlaceConveyor place_conveyor = 12; + ScdFactoryOpRetDismantle dismantle = 13; + ScdFactoryOpRetSetSelectTarget set_select_target = 15; + ScdFactoryOpRetEnableNode enable_node = 16; + ScdFactoryOpRetMoveNode move_node = 17; + ScdFactoryOpRetDismantleBoxConveyor dismantle_box_conveyor = 18; + ScdFactoryOpRetRepairNode repair_node = 19; + ScdFactoryOpRetMoveItemCacheToCache move_item_cache_to_cache = 20; + ScdFactoryOpRetMoveItemBagToCache move_item_bag_to_cache = 21; + ScdFactoryOpRetMoveItemCacheToBag move_item_cache_to_bag = 22; + ScdFactoryOpRetMoveItemDepotToCache move_item_depot_to_cache = 23; + ScdFactoryOpRetMoveItemCacheToDepot move_item_cache_to_depot = 24; + ScdFactoryOpRetMoveItemConveyorToBag move_item_conveyor_to_bag = 25; + ScdFactoryOpRetCacheTransportTransfer cache_transport_transfer = 26; + ScdFactoryOpRetCacheTransportEnable cache_transport_enable = 27; + ScdFactoryOpRetSetTravelPoleDefaultNext set_travel_pole_default_next = 28; + ScdFactoryOpRetUseHealTowerPoint use_heal_tower_point = 29; + ScdFactoryOpRetBattleRepair battle_repair = 30; + ScdFactoryOpRetAddConnection add_connection = 31; + ScdFactoryOpRetDelConnection del_connection = 32; + ScdFactoryOpRetGridBoxInnerMove grid_box_inner_move = 41; + ScdFactoryOpRetGridBoxInnerSplit grid_box_inner_split = 42; + ScdFactoryOpRetMoveItemBagToGridBox move_item_bag_to_grid_box = 43; + ScdFactoryOpRetMoveItemGridBoxToBag move_item_grid_box_to_bag = 44; + ScdFactoryOpRetMoveItemDepotToGridBox move_item_depot_to_grid_box = 45; + ScdFactoryOpRetMoveItemGridBoxToDepot move_item_grid_box_to_depot = 46; + ScdFactoryOpRetMoveAllCacheOutItemToBag move_all_cache_out_item_to_bag = 47; + ScdFactoryOpRetQuickPutBattery quick_put_battery = 48; + ScdFactoryOpRetChangeProducerMode change_producer_mode = 51; + ScdFactoryOpRetReverseFluidConveyorDirection reverse_fluid_conveyor_direction = 52; + ScdFactoryOpRetDismantleBatch dismantle_batch = 53; + ScdFactoryOpRetTakeOutFluidFromLiquidBody take_out_fluid_from_liquid_body = 61; + ScdFactoryOpRetPutInFluidToLiquidBody put_in_fluid_to_liquid_body = 62; + ScdFactoryOpRetFillingFluidComWithBag filling_fluid_com_with_bag = 63; + ScdFactoryOpRetFillingFluidComWithDepot filling_fluid_com_with_depot = 64; + } +} + +enum FactoryOpRetCode { + OK = 0; + FAIL = 1; + UNKNOWN_OP_TYPE = 2; + MESH_CONFLICT = 3; + MUST_IN_MAIN = 4; + NO_BUILDING_ITEM = 5; +} + +message ScdFactoryOpRetPlace { + uint32 node_id = 1; +} + +message ScdFactoryOpRetPlaceConveyor { + repeated uint32 node_id = 1; +} + +message ScdFactoryOpRetDismantle { +} + +message ScdFactoryOpRetSetSelectTarget { +} + +message ScdFactoryOpRetEnableNode { +} + +message ScdFactoryOpRetMoveNode { +} + +message ScdFactoryOpRetDismantleBoxConveyor { + repeated uint32 node_id = 1; +} + +message ScdFactoryOpRetRepairNode { +} + +message ScdFactoryOpRetMoveItemCacheToCache { +} + +message ScdFactoryOpRetMoveItemBagToCache { +} + +message ScdFactoryOpRetMoveItemCacheToBag { +} + +message ScdFactoryOpRetMoveItemDepotToCache { +} + +message ScdFactoryOpRetMoveItemCacheToDepot { +} + +message ScdFactoryOpRetMoveItemConveyorToBag { +} + +message ScdFactoryOpRetCacheTransportTransfer { + bool success = 1; +} + +message ScdFactoryOpRetCacheTransportEnable { +} + +message ScdFactoryOpRetSetTravelPoleDefaultNext { +} + +message ScdFactoryOpRetUseHealTowerPoint { + uint32 used_count = 1; +} + +message ScdFactoryOpRetBattleRepair { +} + +message ScdFactoryOpRetAddConnection { + uint64 index = 1; +} + +message ScdFactoryOpRetDelConnection { +} + +message ScdFactoryOpRetGridBoxInnerMove { +} + +message ScdFactoryOpRetGridBoxInnerSplit { +} + +message ScdFactoryOpRetMoveItemBagToGridBox { +} + +message ScdFactoryOpRetMoveItemGridBoxToBag { +} + +message ScdFactoryOpRetMoveItemDepotToGridBox { +} + +message ScdFactoryOpRetMoveItemGridBoxToDepot { + bool not_all_success = 1; +} + +message ScdFactoryOpRetMoveAllCacheOutItemToBag { +} + +message ScdFactoryOpRetQuickPutBattery { + repeated ItemBundle cost_items = 1; +} + +message ScdFactoryOpRetChangeProducerMode { +} + +message ScdFactoryOpRetReverseFluidConveyorDirection { +} + +message ScdFactoryOpRetDismantleBatch { +} + +message ScdFactoryOpRetTakeOutFluidFromLiquidBody { + repeated ItemBundle cost_bottle_items = 1; + repeated ItemBundle gain_bottle_water_items = 2; + int32 cost_liquid = 3; + RetFluidWithLiquidBody ret = 4; +} + +enum RetFluidWithLiquidBody { + RET_FLUID_WITH_LIQUID_BODY_OK = 0; + RET_FLUID_WITH_LIQUID_BODY_None = 1; + RET_FLUID_WITH_LIQUID_BODY_PartialByBag = 2; + RET_FLUID_WITH_LIQUID_BODY_PartialByLiquidBody = 3; +} + +message ScdFactoryOpRetPutInFluidToLiquidBody { + repeated ItemBundle cost_bottle_water_items = 1; + repeated ItemBundle gain_bottle_items = 2; + int32 gain_liquid = 3; + RetFluidWithLiquidBody ret = 4; +} + +message ScdFactoryOpRetFillingFluidComWithBag { +} + +message ScdFactoryOpRetFillingFluidComWithDepot { +} + +message CsFriendListSync { +} + +message CsFriendRequestListSync { +} + +message CsFriendSearchName { + string name = 1; +} + +message CsFriendRequestAccept { + uint64 role_id = 1; +} + +message CsFriendRequestReject { + uint64 role_id = 1; +} + +message CsFriendDelete { + uint64 role_id = 1; +} + +message CsFriendRequestSubmit { + uint64 role_id = 1; +} + +message ScFriendListSync { + repeated FriendFriendInfo friend_list = 1; +} + +message ScFriendRequestListSync { + repeated FriendRequestInfo friend_request_list = 1; +} + +message ScFriendSearchName { + repeated FriendStrangerUserInfo stranger_list = 1; +} + +message ScFriendRequestAccept { + uint64 role_id = 1; +} + +message ScFriendRequestReject { + uint64 role_id = 1; +} + +message ScFriendDelete { + uint64 role_id = 1; +} + +message ScFriendRequestSubmit { + uint64 role_id = 1; +} + +message ScFriendRequestAddNotify { + FriendRequestInfo friend_request_info = 1; +} + +message ScFriendAddNotify { + FriendFriendInfo friend_info = 1; +} + +message CsGachaSinglePullReq { + int32 gacha_type = 1; + string gacha_pool_id = 2; + map pull_costs = 3; +} + +message CsGachaTenPullReq { + int32 gacha_type = 1; + string gacha_pool_id = 2; + map pull_costs = 3; +} + +message ScdGachaPoolInfo { + string gacha_pool_id = 1; + int64 open_time = 2; + int64 close_time = 3; + bool is_closed = 4; + int32 public_close_reason = 5; +} + +message ScdGachaPoolRoleData { + string gacha_pool_id = 1; + bool is_closed = 2; + int32 personal_close_reason = 3; + int32 total_pull_count = 4; + int32 hard_guarantee_progress = 5; + int32 soft_guarantee_progress = 6; + int32 star5_soft_guarantee_progress = 7; + int32 up_got_count = 8; +} + +message ScdGachaPoolCategoryRoleData { + int32 gacha_pool_type = 1; + int32 total_pull_count = 2; + int32 soft_guarantee_progress = 3; + int32 star5_soft_guarantee_progress = 4; +} + +message ScdGachaPoolMgr { + repeated ScdGachaPoolInfo gacha_pool_infos = 1; + repeated ScdGachaPoolRoleData gacha_pool_role_datas = 2; + repeated ScdGachaPoolCategoryRoleData gacha_pool_category_role_datas = 3; +} + +message ScGachaSync { + ScdGachaPoolMgr char_gacha_pool = 1; + ScdGachaPoolMgr weapon_gacha_pool = 2; +} + +message ScGachaModifyPoolInfo { + repeated ScdGachaPoolInfo char_gacha_pools = 1; + repeated ScdGachaPoolInfo weapon_gacha_pools = 2; +} + +message ScdGachaFinalResult { + string item_id = 1; + string reward_item_id = 2; + repeated string reward_ids = 3; + bool is_new = 4; +} + +message ScGachaSyncPullResult { + int32 gacha_type = 1; + string gacha_pool_id = 2; + repeated string ori_result_ids = 3; + repeated ScdGachaFinalResult final_results = 4; + int32 up_got_count = 5; + int32 star6_got_count = 6; + int32 star5_got_count = 7; +} + +message ScGachaModifyPoolRoleData { + int32 gacha_type = 1; + string gacha_pool_id = 2; + ScdGachaPoolRoleData gacha_pool_role_data = 3; + ScdGachaPoolCategoryRoleData gacha_pool_category_role_data = 4; +} + +message CsGameMechanicsReqActive { + string game_id = 1; +} + +message CsGameMechanicsReqReward { + string game_id = 1; +} + +message CsGameMechanicsNtfInstPrepareFinish { + string game_id = 1; +} + +message ScdGameMechanicsRecord { + string game_id = 1; + int64 last_enter_game_t_s = 2; + int32 best_pass_time = 3; + int64 best_pass_t_s = 4; + bool is_pass = 5; + bool is_challenged = 6; + bool is_active = 7; + bool once_reward_got = 8; + repeated int32 rewarded_id_list = 9; +} + +message ScdGameMechanicsUnlockConditions { + string id = 1; + int32 unlock_state = 2; + map unlock_condition_values = 3; + map unlock_condition_flags = 4; +} + +message ScGameMechanicsSync { + repeated ScdGameMechanicsUnlockConditions game_unlock_conditions = 1; + repeated ScdGameMechanicsRecord game_records = 2; +} + +message ScGameMechanicsSyncUnlockCondition { + ScdGameMechanicsUnlockConditions game_unlock_condition = 1; +} + +message ScGameMechanicsModifyRecords { + repeated ScdGameMechanicsRecord game_records = 1; +} + +message ScGameMechanicsSyncChallengeStart { + string game_id = 1; + int64 challenge_start_ts = 2; + int64 challenge_expire_ts = 3; + int32 prepare_challenge_seconds = 4; +} + +message ScGameMechanicsSyncChallengeComplete { + string game_id = 1; + bool is_pass = 2; + int64 force_leave_ts = 3; + int32 pass_time = 4; +} + +message ScGameMechanicsSyncCompletionReward { + string game_id = 1; + bool is_pass = 2; + int64 force_leave_ts = 3; +} + +message ScGameMechanicsSyncEnterGameInst { + string game_id = 1; +} + +message ScGameMechanicsSyncLeaveGameInst { + string game_id = 1; +} + +message ScGameMechanicsSyncRestartGameInst { + string game_id = 1; +} + +message ScdGameMechanicsInstTimeFreeze { + int32 time_key = 1; + int64 total_freeze_time_in_ms = 2; +} + +message ScGameMechanicsModifyInstTimeFreeze { + string game_id = 1; + repeated ScdGameMechanicsInstTimeFreeze time_freeze_infos = 2; +} + +message ScSyncGameMode { + string mode_id = 1; +} + +message ScSyncAllGameVar { + map server_vars = 1; + map client_vars = 2; +} + +message CsUpdateClientGameVar { + int32 key = 1; + int64 value = 2; +} + +message ScUpdateGameVar { + int32 key = 1; + int64 value = 2; + int32 type = 3; +} + +message CsGemRecast { + string formula_id = 1; + int32 count = 2; + repeated uint64 cost_gem_inst_ids = 3; +} + +message ScGemRecast { + string formula_id = 1; + int32 count = 2; + repeated uint64 gem_inst_ids = 3; +} + +message GuideGroupInfo { + string guide_group_id = 1; + int32 guide_state = 2; +} + +message CsCompleteGuideGroupKeyStep { + string guide_group_id = 1; +} + +message CsCompleteGuideGroup { + string guide_group_id = 1; + bool not_auto_accept = 2; + bool skip_key_step = 3; +} + +message ScSyncAllGuide { + repeated GuideGroupInfo guide_group_list = 1; + repeated string completed_repeat_accept_guide_group_list = 2; +} + +message ScAcceptGuideGroup { + string guide_group_id = 1; +} + +message ScCompleteGuideGroupKeyStep { + string guide_group_id = 1; +} + +message ScCompleteGuideGroup { + string guide_group_id = 1; +} + +message ScdItemBag { + int32 grid_limit = 1; + repeated ScdItemGrid grids = 2; +} + +message ScdItemDepot { + map stackable_items = 1; + repeated ScdItemGrid inst_list = 2; +} + +message ScdItemLostAndFound { + map stackable_items = 1; + repeated ScdItemGrid inst_list = 2; +} + +message ScdItemBagModify { + int32 grid_limit = 1; + repeated ScdItemGrid grids = 2; + repeated int32 del_list = 3; +} + +message ScdItemDepotModify { + map items = 1; + repeated ScdItemGrid inst_list = 2; + repeated uint64 del_inst_list = 3; + map infinite_items = 4; +} + +message ScdItemLostAndFoundModify { + map items = 1; + repeated ScdItemGrid inst_list = 2; + repeated uint64 del_inst_list = 3; +} + +message CsItemBagTidyInBag { + int32 scope_name = 11; +} + +message CsItemBagMoveInBag { + int32 from_grid = 1; + int32 to_grid = 2; + int32 scope_name = 11; +} + +message CsItemBagSplitInBag { + int32 from_grid = 1; + int32 to_grid = 2; + int32 move_count = 3; + int32 scope_name = 11; +} + +message CsItemBagFactoryDepotToBag { + map items = 1; + repeated uint64 inst_id_list = 2; + int32 scope_name = 11; + string chapter_id = 12; +} + +message CsItemBagBagToFactoryDepot { + repeated int32 grid_list = 1; + int32 scope_name = 11; + string chapter_id = 12; +} + +message CsItemBagFactoryDepotToBagGrid { + int32 grid_index = 1; + string id = 2; + int32 count = 3; + int32 scope_name = 11; + string chapter_id = 12; +} + +message CsItemBagUseItem { + int32 grid_index = 1; + int32 count = 2; + repeated uint64 char_inst_id_list = 3; + uint64 equip_medicine_char_inst_id = 4; + repeated string item_use_args = 5; + int32 scope_name = 11; + ItemBagUseType use_type = 12; +} + +enum ItemBagUseType { + item_bag_use_type_default = 0; + item_bag_use_type_equip_medicine = 1; + item_bag_use_type_bomb = 2; +} + +message CsItemBagSetQuickBar { + repeated string item_id = 1; + int32 scope_name = 11; +} + +message CsItemBagSetQuickBarPos { + int32 pos = 1; + int32 scope_name = 11; +} + +message CsItemBagSetItemLock { + repeated ItemInstLockInfo lock_info_list = 1; + int32 scope_name = 11; +} + +message ItemInstLockInfo { + string item_id = 1; + uint64 inst_id = 2; + bool is_lock = 3; +} + +message CsItemBagAbandonInBag { + map grid_cut = 1; + uint64 target_object_id = 2; + int32 scope_name = 11; +} + +message CsItemBagDestroyInDepot { + int32 depot = 1; + map items = 2; + repeated uint64 inst_id_list = 3; + int32 scope_name = 11; +} + +message CsItemBagDestroyInFactoryDepot { + map items = 1; + int32 scope_name = 11; + string chapter_id = 12; +} + +message CsItemBagDumpBottleInBag { + int32 grid_index = 1; + int32 count = 2; + int32 scope_name = 11; +} + +message CsItemBagDumpBottleInFactoryDepot { + string item_id = 1; + int32 count = 2; + int32 scope_name = 11; + string chapter_id = 12; +} + +message CsItemBagTakeoutLostAndFound { + bool all = 1; + map items = 2; + repeated uint64 inst_id_list = 3; +} + +message CsItemBagUseItemCase { + string id = 1; + int32 count = 2; + repeated string select_rewards = 3; +} + +message CsItemBagChgSpaceshipChapter { + string spaceship_chapter_id = 1; +} + +message ScdItemBagSyncQuickBar { + repeated string item_id = 1; + int32 pos = 2; +} + +message ScItemBagCommonSync { + ScdItemLostAndFound lost_and_found = 1; +} + +message ScItemBagCommonModify { + ScdItemLostAndFoundModify lost_and_found = 1; +} + +message ScItemBagScopeSync { + ScdItemBag bag = 1; + map factory_depot = 2; + map depot = 3; + ScdItemBagSyncQuickBar quick_bar = 4; + ScdItemBagScopeAssistant assistant = 5; + int32 scope_name = 11; + string current_chapter_id = 12; + string spaceship_chapter_id = 13; +} + +message ScdItemBagScopeAssistant { + map last_use_time = 1; + map cannot_destroy = 2; +} + +message ScTrialCharacterEquipMedicineModify { + uint64 trial_obj_id = 1; + int32 count = 2; +} + +message ScItemBagTrialCharDepotModify { + int32 scope_name = 1; + ScdItemDepotModify trial_char_depot = 2; +} + +message ScItemBagTrialCharDepotClear { + int32 scope_name = 1; +} + +message ScItemBagScopeModify { + ScdItemBagModify bag = 1; + map factory_depot = 2; + map depot = 3; + ScdItemBagSyncQuickBar quick_bar = 4; + ScdItemBagScopeAssistantModify assistant = 5; + int32 scope_name = 11; + string current_chapter_id = 12; + bool is_scope_delete = 14; +} + +message ScdItemBagScopeAssistantModify { + map last_use_time = 1; + map cannot_destroy = 2; +} + +message ScItemBagUseItem { + EUseItemResult result = 1; + ScdItemGrid used_item = 2; + repeated uint64 char_inst_id_list = 3; + uint64 equip_medicine_char_inst_id = 4; + int32 scope_name = 11; +} + +enum EUseItemResult { + E_USE_ITEM_RESULT_OK = 0; + E_USE_ITEM_RESULT_UnknownFail = 1; + E_USE_ITEM_RESULT_CondiitonFail = 2; +} + +message ScItemBagSetQuickBar { + repeated string item_id = 1; + int32 scope_name = 11; +} + +message ScItemBagSetQuickBarPos { + int32 pos = 1; + int32 scope_name = 11; +} + +message ScItemBagSetItemLock { + repeated ItemInstLockInfo lock_info_list = 1; + int32 scope_name = 11; +} + +message ScItemBagAbandonInBag { +} + +message ScItemBagBagToFactoryDepot { + bool not_all_success = 1; + int32 scope_name = 21; +} + +message ScItemBagTakeoutLostAndFound { + bool nothing_got = 1; +} + +message ScItemBagGotItemToast { + map items = 1; +} + +message ScRewardToastBegin { + int32 reward_source_type = 1; + uint64 reward_toast_inst_id = 2; +} + +message ScRewardToastEnd { + repeated RewardItem reward_virtual_list = 1; + uint64 reward_toast_inst_id = 2; +} + +message ScRewardDropSpItemToast { + string item_id = 1; + int64 count = 2; + Vector pos = 3; + int32 reward_source_type = 4; + uint64 reward_toast_inst_id = 5; +} + +message ScItemBagUseItemCase { + string id = 1; + int32 count = 2; +} + +message ScItemBagChgSpaceshipChapter { + string spaceship_chapter_id = 1; +} + +message CsLogin { + string uid = 1; + string token = 2; + string channel = 3; + int32 server_group = 4; + uint64 last_recv_down_seqid = 5; + string client_version = 6; + string client_res_version = 7; + bytes client_public_key = 8; + ClientPlatformType platform_id = 9; + AreaType area = 10; + EnvType env = 11; + int32 pay_platform = 12; + string login_token = 13; +} + +enum ClientPlatformType { + DEFAULT = 0; + ANDRIOD = 1; + IOS = 2; + WINDOWS = 3; + PLAYSTATION = 4; +} + +enum AreaType { + Default = 0; + China = 1; + Oversea = 2; + ChinaPre = 10; + OverseaPre = 11; +} + +enum EnvType { + DEV = 0; + STABLE = 1; + PROD = 2; +} + +message ScLogin { + string uid = 1; + bool is_first_login = 2; + bytes server_public_key = 3; + bytes server_encryp_nonce = 4; + uint64 last_recv_up_seqid = 5; + bool is_reconnect = 6; + bool is_enc = 7; + bool is_client_reconnect = 8; + int64 server_time = 9; + int32 server_time_zone = 10; + string login_token = 11; +} + +message CsCreateRole { + string role_name = 1; + Gender gender = 2; +} + +enum Gender { + GEN_INVALID = 0; + GEN_MALE = 1; + GEN_FEMALE = 2; + GEN_TOTAL = 3; +} + +message ScSyncBaseData { + uint64 roleid = 1; + string role_name = 2; + uint32 level = 3; + uint32 exp = 4; + string short_id = 7; + Gender gender = 8; +} + +message ScNtfErrorCode { + int32 error_code = 1; + string details = 2; +} + +message ScNtfCode { + int32 code = 1; + string details = 2; +} + +message CsLogout { +} + +message CsGmCommand { + string command = 1; +} + +message ScdGmGachaStat { + string gacha_pool_id = 1; + int32 gacha_type = 2; + int32 total_pull_count = 3; + map up_got_pull_count_map = 4; + int32 up_got_count = 5; + map star6_got_pull_count_map = 6; + int32 star6_got_count = 7; + int32 star6_ge2_got_count = 8; + map star5_got_pull_count_map = 9; + int32 star5_got_count = 10; + int32 star5_ge2_got_count = 11; + map up_item_count_map = 12; + map star6_item_count_map = 13; + map star5_item_count_map = 14; + map starother_item_count_map = 15; +} + +message ScGmCommand { + string result = 1; +} + +message CsPing { + uint64 client_ts = 1; +} + +message ScPing { + uint64 client_ts = 1; + uint64 server_ts = 2; +} + +message ScReconnectIncr { + bool is_client_reconnect = 1; +} + +message ScReconnectFull { + bool is_client_reconnect = 1; +} + +message CsFlushSync { + uint64 client_ts = 1; +} + +message ScFlushSync { + uint64 client_ts = 1; + uint64 server_ts = 2; +} + +message CsSetName { + string name = 1; +} + +message ScSetName { + string name = 1; + string short_id = 2; +} + +message CsSetGender { + Gender gender = 1; +} + +message ScSetGender { + Gender gender = 1; +} + +message CsCheckName { + string name = 1; +} + +message ScCheckName { + string name = 1; + bool pass = 2; +} + +message ScSyncFullDataEnd { +} + +message CsMailDef { + int32 mail_type = 1; + uint64 mail_id = 2; + int64 expire_time = 3; + bool is_read = 4; + bool is_attachment_got = 5; + int64 send_time = 6; + MailContent mail_content = 7; + repeated RewardItem item_list = 8; + bool is_star = 9; + int32 mail_sub_type = 10; +} + +message CsGetMail { + repeated uint64 mail_id_list = 1; +} + +message CsReadMail { + uint64 mail_id = 1; +} + +message CsDeleteMail { + uint64 mail_id = 1; +} + +message CsDeleteAllMail { +} + +message CsGetMailAttachment { + uint64 mail_id = 1; +} + +message CsGetAllMailAttachment { +} + +message CsMarkStarMail { + uint64 mail_id = 1; + bool is_star = 2; +} + +message ScSyncAllMail { + repeated uint64 mail_id_list = 1; + bool new_mail_tag = 2; + bool new_questionnaire_tag = 3; +} + +message ScReadMail { + uint64 mail_id = 1; +} + +message ScGetMail { + repeated CsMailDef mail_list = 1; +} + +message ScGetMailAttachment { + repeated uint64 success_mail_id_list = 1; + repeated uint64 failed_mail_id_list = 2; +} + +message ScDelMailNotify { + repeated uint64 mail_id_list = 1; +} + +message ScNewMailNotify { + repeated uint64 mail_id_list = 1; + bool new_questionnaire_tag = 2; +} + +message ScMarkStarMail { + uint64 mail_id = 1; + bool is_star = 2; +} + +message CsdSceneStaticMapMarkUpdate { + SceneStaticMapMark mark = 1; + bool is_add = 2; +} + +message CsSceneStaticMapMarkUpdate { + repeated CsdSceneStaticMapMarkUpdate ops = 1; +} + +message CsSceneSetTrackPoint { + SceneTrackPoint track_point = 1; +} + +message ScSceneMapMarkSync { + repeated SceneStaticMapMark scene_static_map_mark_list = 1; + SceneTrackPoint track_point = 2; +} + +message ScSceneStaticMapMarkModify { + repeated SceneStaticMapMark added_list = 1; + repeated int32 deleted_list = 2; +} + +message ScSceneSetTrackPoint { + SceneTrackPoint track_point = 1; +} + +message MiniGameInfo { + string mini_game_id = 1; + int32 completed_count = 2; +} + +message ScSyncAllMiniGame { + repeated MiniGameInfo completed_mini_game = 1; +} + +message CsCompleteMiniGame { + string mini_game_id = 2; +} + +message ScCompleteMiniGame { + string mini_game_id = 2; + int32 completed_count = 3; +} + +message AttrInfo { + int32 attr_type = 1; + double basic_value = 2; + double value = 3; +} + +message ScSyncAttr { + uint64 obj_i_d = 1; + repeated AttrInfo attr_list = 2; +} + +message ScNewNoticeNotify { +} + +message QuestObjectiveDetail { + map hash_value = 2; +} + +message QuestObjective { + string condition_id = 1; + map extra_details = 2; + map values = 4; + bool is_complete = 3; +} + +message Quest { + string quest_id = 1; + int32 quest_state = 2; + repeated QuestObjective quest_objectives = 4; +} + +message Mission { + string mission_id = 1; + int32 mission_state = 2; + int32 succeed_id = 3; + map properties = 4; +} + +message ObjectiveValueOp { + string condition_id = 1; + int32 value = 2; + bool is_add = 3; +} + +message CsAcceptMission { + string mission_id = 1; +} + +message CsFailMission { + string mission_id = 1; +} + +message CsTrackMission { + string mission_id = 1; +} + +message CsStopTrackingMission { +} + +message CsMissionEventTrigger { + string mission_id = 1; + string event_name = 2; + map properties = 3; +} + +message ScMissionEventTrigger { + string mission_id = 1; + string event_name = 2; +} + +message CsUpdateQuestObjective { + string quest_id = 1; + repeated ObjectiveValueOp objective_value_ops = 2; +} + +message ScUpdateMissionProperty { + string mission_id = 1; + map properties = 2; +} + +message CsMissionClientTriggerDone { + string mission_id = 1; + string scene_name = 2; + string area_id = 3; +} + +message CsSetNewMissionTagDone { + repeated NewMissionTag new_mission_tags = 5; +} + +message NewMissionTag { + string mission_id = 1; + string quest_id = 2; +} + +message ScSyncAllMission { + string track_mission_id = 1; + map missions = 2; + map cur_quests = 3; + string daily_mission_id = 4; + repeated NewMissionTag new_mission_tags = 5; +} + +message ScDailyMissionInfoUpdate { + string daily_mission_id = 1; +} + +message ScQuestStateUpdate { + string quest_id = 1; + int32 quest_state = 2; + bool b_rollback = 3; + RoleBaseInfo role_base_info = 10; +} + +message ScMissionStateUpdate { + string mission_id = 1; + int32 mission_state = 2; + int32 succeed_id = 3; + map properties = 4; + RoleBaseInfo role_base_info = 10; +} + +message ScQuestFailed { + string quest_id = 1; +} + +message ScMissionFailed { + string mission_id = 1; +} + +message ScMissionDeleted { + string mission_id = 1; +} + +message ScTrackMissionChange { + string mission_id = 1; +} + +message ScQuestObjectivesUpdate { + string quest_id = 1; + repeated QuestObjective quest_objectives = 4; +} + +message ScQuestRollback { + string quest_id = 1; +} + +message ScSceneTriggerClientMissionEvent { + string mission_id = 1; + string event_name = 2; +} + +message CsRollBlocMission { + string bloc_id = 1; +} + +message ScRollBlocMission { + string bloc_id = 1; + string mission_id = 2; + int64 roll_count = 3; + int64 next_refresh_tine = 4; +} + +message ScSyncBlocMissionInfo { + map bloc_missions = 1; + bool reward_got = 2; + int64 roll_count = 3; + int64 next_refresh_tine = 4; + int32 completed_num = 5; +} + +message ScBlocCompletedMissionNumUpdate { + int32 completed_num = 1; +} + +message ScSceneMonsterSpawnerStart { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + repeated string enabled_hidden_wave_key_list = 3; +} + +message ScSceneMonsterSpawnerStop { + int32 scene_num_id = 1; + uint64 spawner_id = 2; +} + +message ScSceneMonsterSpawnerComplete { + int32 scene_num_id = 1; + uint64 spawner_id = 2; +} + +message CsSceneMonsterSpawnerBeginWave { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + int32 wave_id = 3; + double client_timestamp = 4; +} + +message ScSceneMonsterSpawnerWaveComplete { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + int32 wave_id = 3; +} + +message ScSceneMonsterSpawnerBeginWave { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + int32 wave_id = 3; +} + +message ScSceneMonsterSpawnerObjectDataBegin { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + int32 wave_id = 3; + int32 group_id = 4; +} + +message ScSceneMonsterSpawnerObjectDataEnd { + int32 scene_num_id = 1; + uint64 spawner_id = 2; + int32 wave_id = 3; + int32 group_id = 4; + repeated SpawnerDetail details = 5; +} + +message SpawnerDetail { + uint64 obj_id = 1; + int32 action_id = 2; + int32 spawn_idx = 3; +} + +message CsCreateOrder { + string product_code = 1; +} + +message ScCreateOrder { + string sign_param = 1; + string product_code = 2; +} + +message ScOrderMsg { + string product_code = 1; +} + +message CSHead { + int32 msgid = 1; + uint64 up_seqid = 2; + uint64 down_seqid = 3; + uint32 total_pack_count = 4; + uint32 current_pack_index = 5; + bool is_compress = 6; +} + +message CsMergeMsg { + bytes msg = 1; +} + +message CsPrtsMarkRead { + string prts_id = 1; +} + +message CsPrtsMarkTerminalRead { + string terminal_content_id = 1; +} + +message CsPrtsRichContentRead { + string id = 1; +} + +message CsPrtsFinishInvestigate { + string id = 1; +} + +message ScSyncRacingDungeonPassedLevel { + map max_passed_level = 1; +} + +message ScRacingDungeonEnter { + string dungeon_id = 1; + int32 level = 2; + string tactics_id = 3; + repeated uint64 char_team = 4; +} + +message ScSyncRacingDungeonSettlement { + string dungeon_id = 1; + int32 level = 2; + bool is_passed = 3; + int64 total_playtime = 4; + float score = 5; + int32 battle_pass_exp = 6; + repeated int64 completed_room_list = 7; +} + +message ScSyncRacingDungeonReconnect { + string dungeon_id = 1; + int32 level = 2; + int64 total_playtime = 3; + repeated string buff_list = 4; + string tactics_id = 5; + int32 kill_monster_counter = 6; + bool paused = 7; + repeated int64 completed_room_list = 8; +} + +message CsRacingDungeonGetBattlePass { + string dungeon_id = 1; +} + +message ScRacingDungeonGetBattlePass { + string dungeon_id = 1; + int32 battle_pass_exp = 2; + repeated int32 received_node_id = 3; + repeated int32 unlock_node_id = 4; +} + +message CsRacingDungeonBattlePassReceiveReward { + string dungeon_id = 1; + bool receive_all = 2; + int32 received_node_id = 3; +} + +message ScRacingDungeonBattlePassReceiveReward { + string dungeon_id = 1; + int32 battle_pass_exp = 2; + repeated string receive_rewards = 3; + repeated int32 received_node_id = 4; +} + +message CsRacingDungeonGetAchievement { + string dungeon_id = 1; +} + +message ScRacingDungeonGetAchievement { + string dungeon_id = 1; + repeated RacingDungeonAchievement achievements = 2; +} + +message RacingDungeonAchievement { + int32 node_id = 1; + RacingAchievementStatus status = 2; + int32 condition_counter = 3; +} + +enum RacingAchievementStatus { + Racing_Status_None = 0; + Racing_Status_Active = 1; + Racing_Status_Completed = 2; + Racing_Status_Received = 3; +} + +message CsRacingDungeonAchievementReceiveReward { + string dungeon_id = 1; + bool receive_all = 2; + int32 received_achievement = 3; +} + +message ScRacingDungeonAchievementReceiveReward { + string dungeon_id = 1; + repeated string receive_rewards = 2; + repeated RacingDungeonAchievement achievements = 3; +} + +message CsRacingDungeonLeave { +} + +message ScSyncRacingDungeonBuffModify { + repeated string buff_list = 1; + string add_buff_id = 2; +} + +message CsRacingDungeonUpdateBattleInfo { + int32 kill_monster_counter = 1; +} + +message ScSyncRacingDungeonAchievementModify { + int32 achievement_id = 1; +} + +message ScSyncRacingTimerPause { + bool paused = 1; + int64 server_timestamp = 2; + int64 total_playtime = 3; +} + +message ScSyncRacingDungeonCompleteRoom { + int64 room_id = 1; +} + +message ScSyncRacingDungeonCountdownEvent { + string debuff_id = 1; +} + +message RemoveItemNewData { + int32 depot_type = 1; + repeated uint64 inst_ids = 2; +} + +message CsRemoveItemNewTags { + repeated uint32 item_ids = 1; + repeated RemoveItemNewData inst_data = 2; +} + +message ScRemoveItemNewTags { +} + +message CsRedDotReadFormula { + repeated uint32 formula_ids = 1; +} + +message CsRedDotReadCharDoc { + uint32 id = 1; + repeated uint32 ids = 2; +} + +message CsRedDotReadCharVoice { + uint32 id = 1; + repeated uint32 ids = 2; +} + +message CsRedDotReadEquipFormula { + uint32 id = 1; +} + +message CsRpgDungeonBuy { + string dungeon_id = 1; + string equip_item_id = 2; + repeated uint64 cost_equip_inst_ids = 3; +} + +message ScRpgDungeonBuy { + string equip_item_id = 1; + uint64 equip_inst_id = 2; +} + +message CsRpgDungeonSell { + uint64 equip_inst_id = 1; +} + +message ScRpgDungeonSell { + uint64 equip_inst_id = 1; +} + +message CsRpgDungeonEquipPuton { + int32 slotid = 1; + uint64 equip_inst_id = 2; +} + +message ScRpgDungeonEquipPuton { + int32 slotid = 1; + uint64 equip_inst_id = 2; +} + +message CsRpgDungeonEquipPutoff { + int32 slotid = 1; +} + +message ScRpgDungeonEquipPutoff { + int32 slotid = 1; +} + +message ScSyncRpgDungeonBuffList { + repeated string buff_list = 1; +} + +message ScSyncRpgEquipColumn { + map equip_column = 1; +} + +message ScSyncRpgTeamLevel { + int32 team_level = 1; + int32 team_exp = 2; + int32 next_level_exp = 3; +} + +message ScSyncRpgDungeonAbility { + repeated RpgDungeonAbilityInfo fixed_abilitys = 1; + repeated RpgDungeonAbilityInfo random_abilitys = 2; +} + +message RpgDungeonAbilityInfo { + string ability_id = 1; +} + +message ScSyncRpgLevelUp { + int32 lv_up_level = 1; + repeated string fixed_ability = 2; + repeated string random_ability = 3; +} + +message CsRpgDungeonPickLvAbility { + int32 level = 1; + string random_ability = 2; +} + +message ScRpgDungeonPickLvAbility { + int32 cur_team_level = 1; + repeated string total_fixed_ability = 2; + map total_random_ability = 3; +} + +message CsRpgDungeonTimeStop { + bool on_time_resume = 1; +} + +message ScSyncRpgDungeonTimeInfo { + bool on_time_stop = 1; + int64 wave_end_time = 2; +} + +message CsRpgDungeonAbilityChange { + string ability_id = 1; + int64 duration = 2; +} + +message CsEnterScene { + int32 scene_num_id = 1; + Vector position = 2; + Vector rotation = 3; +} + +message CsSceneLeavePlane { + Vector position = 1; + Vector rotation = 2; +} + +message SceneObjectCommonInfo { + uint64 id = 1; + int32 type = 2; + string templateid = 3; + Vector position = 4; + Vector rotation = 5; + uint64 belong_level_script_id = 6; + int32 scene_num_id = 7; + double hp = 8; +} + +message SceneCharacter { + SceneObjectCommonInfo common_info = 1; + int32 level = 2; + string name = 3; + repeated AttrInfo attrs = 4; + BattleMgrInfo battle_info = 5; +} + +message SceneMonster { + SceneObjectCommonInfo common_info = 1; + uint64 origin_id = 2; + int32 level = 3; + repeated AttrInfo attrs = 4; + BattleMgrInfo battle_info = 5; +} + +message SceneInteractive { + SceneObjectCommonInfo common_info = 1; + uint64 origin_id = 2; + map properties = 4; + int32 meta = 5; + BattleMgrInfo battle_info = 6; +} + +message SceneSummonSkill { + string skill_id = 1; + BattleBlackboard assigned_items = 2; +} + +message SceneSummon { + SceneObjectCommonInfo common_info = 1; + map skills = 2; + repeated AttrInfo attrs = 3; + BattleMgrInfo battle_info = 4; + string cast_skill_id = 5; + BattleBlackboard blackboard = 6; +} + +message SceneNpc { + SceneObjectCommonInfo common_info = 1; +} + +message SceneObjectDetailContainer { + CharBagTeamType team_type = 11; + int32 team_index = 6; + uint64 team_change_token = 7; + repeated SceneCharacter char_list = 1; + repeated SceneMonster monster_list = 2; + repeated SceneInteractive interactive_list = 3; + repeated SceneNpc npc_list = 4; + repeated SceneSummon summon_list = 5; +} + +message CsSceneSetLevelScriptActive { + int32 scene_num_id = 1; + uint64 script_id = 2; + bool is_active = 3; + Vector leader_pos = 4; +} + +message CsSceneSetLevelScriptStart { + int32 scene_num_id = 1; + uint64 script_id = 2; + bool is_start = 3; + Vector leader_pos = 4; +} + +message CsSceneLevelScriptEventTrigger { + int32 scene_num_id = 1; + uint64 script_id = 2; + string event_name = 3; + map properties = 4; +} + +message CsSceneCommitLevelScriptCacheStep { + int32 scene_num_id = 1; + uint64 script_id = 2; +} + +message LevelScriptInfo { + uint64 script_id = 1; + int32 state = 2; + map properties = 3; + bool is_done = 4; +} + +message ScSceneUpdateLevelScriptProperty { + int32 scene_num_id = 1; + uint64 script_id = 2; + map properties = 3; + bool client_operate = 4; +} + +message ScSceneLevelScriptStateNotify { + int32 scene_num_id = 1; + uint64 script_id = 2; + int32 state = 3; +} + +message ScSceneLevelScriptResetBegin { + int32 scene_num_id = 1; + uint64 script_id = 2; +} + +message ScSceneLevelScriptResetEnd { + int32 scene_num_id = 1; + uint64 script_id = 2; +} + +message ScSceneLevelScriptTaskStateUpdate { + int32 scene_num_id = 1; + uint64 script_id = 2; + string task_id = 3; + int32 task_state = 4; +} + +message ScSceneLevelScriptTaskProgressUpdate { + int32 scene_num_id = 1; + uint64 script_id = 2; + string task_id = 3; + map condition_completed_map = 4; +} + +message ScSceneLevelScriptTaskStartFinish { + int32 scene_num_id = 1; + uint64 script_id = 2; + string task_id = 3; +} + +message ScSceneTriggerClientLevelScriptEvent { + int32 scene_num_id = 1; + uint64 script_id = 2; + string event_name = 3; +} + +message ScSceneTriggerClientInteractiveEvent { + int32 scene_num_id = 1; + uint64 id = 2; + string event_name = 3; +} + +message ScdSceneTeamInfo { + CharBagTeamType team_type = 1; + int32 team_index = 2; + uint64 team_change_token = 3; + uint64 cur_leader_id = 4; +} + +message ScSelfSceneInfo { + int32 scene_num_id = 1; + uint64 scene_id = 2; + SceneObjectDetailContainer detail = 3; + repeated uint64 revive_chars = 7; + repeated LevelScriptInfo level_scripts = 8; + int32 self_info_reason = 9; + repeated string unlock_area = 10; + repeated SceneDrop drop_list = 14; + int32 scene_grade = 15; + ScdSceneTeamInfo team_info = 16; + oneof scene_impl { + SceneImplDungeon dungeon = 11; + SceneImplEmpty empty = 12; + } +} + +message SceneDrop { + uint64 drop_id = 1; + map stackable_items = 2; + repeated ScdItemGrid inst_list = 3; +} + +message SceneImplDungeon { + string dungeon_id = 1; + int64 challenge_expire_ts = 2; + int64 leave_dungeon_ts = 3; + bool is_reward = 4; + bool is_calc = 5; + bool is_pass = 6; +} + +message SceneImplEmpty { +} + +message ScSceneResetEntity { + int32 scene_num_id = 1; + uint64 id = 2; +} + +message ScObjectEnterView { + SceneObjectDetailContainer detail = 1; + bool has_extra_object = 2; +} + +message LeaveObjectInfo { + int32 obj_type = 1; + uint64 obj_id = 2; +} + +message ScObjectLeaveView { + repeated LeaveObjectInfo obj_list = 1; +} + +message MotionInfo { + Vector position = 1; + Vector rotation = 2; + Vector speed = 3; + MotionState state = 4; +} + +enum MotionState { + MOTION_NONE = 0; + MOTION_STANDBY = 1; + MOTION_STANDBY_MOVE = 2; + MOTION_WALK = 3; + MOTION_RUN = 4; + MOTION_CLIMB = 5; + MOTION_CLIMB_JUMP = 6; +} + +message MoveObjectMoveInfo { + uint64 objid = 1; + MotionInfo motion_info = 2; + uint32 server_time = 3; + int32 scene_num_id = 4; +} + +message CsMoveObjectMove { + repeated MoveObjectMoveInfo move_info = 1; + int32 leader_move_tag_mask = 2; + int32 leader_index = 3; +} + +message ScMoveObjectMove { + repeated MoveObjectMoveInfo move_info = 1; + bool server_notify = 2; +} + +message ScEnterSceneNotify { + uint64 role_id = 1; + int32 scene_num_id = 2; + uint64 scene_id = 3; + Vector position = 4; + PassThroughData pass_through_data = 5; +} + +message ScLeaveSceneNotify { + uint64 role_id = 1; + int32 scene_num_id = 2; + uint64 scene_id = 3; +} + +message ScSeamlessSceneDestroyNotify { + uint64 role_id = 1; + int32 scene_num_id = 2; + uint64 scene_id = 3; +} + +message CsSceneLoadFinish { + int32 scene_num_id = 1; +} + +message CsSceneSetLastRecordCampid { + uint64 last_camp_id = 1; + Vector position = 2; + Vector rotation = 3; + int32 scene_num_id = 4; +} + +message ScSceneSetLastRecordCampid { + uint64 last_camp_id = 1; + int32 scene_num_id = 2; +} + +message CsSceneInteractiveEventTrigger { + int32 scene_num_id = 1; + uint64 id = 2; + string event_name = 3; + map properties = 4; +} + +message ScSceneUpdateInteractiveProperty { + int32 scene_num_id = 1; + uint64 id = 2; + map properties = 3; + bool client_operate = 4; +} + +message CsSceneSetVar { + string key = 1; + string value = 2; + int32 scene_num_id = 3; +} + +message ScSceneSetVar { + string key = 1; + string value = 2; + int32 scene_num_id = 3; +} + +message CsSceneRest { +} + +message EntityInfo { + EntityOpType entity_op_type = 2; + uint64 id = 3; + int32 type = 4; +} + +enum EntityOpType { + ENTITY_OP_TYPE_NONE = 0; + ENTITY_OP_TYPE_ID = 2; +} + +message ScSceneCreateEntity { + int32 scene_num_id = 1; + uint64 id = 2; +} + +message ScSceneDestroyEntity { + int32 scene_num_id = 1; + uint64 id = 2; + int32 reason = 3; +} + +message ScSceneCrossSceneStatus { + uint64 obj_id = 1; + int32 scene_num_id = 2; +} + +message CsSceneRevival { +} + +message ScSceneRevival { +} + +message CsSceneSetStorySafeZone { + bool in_zone = 1; +} + +message ScSceneSetStorySafeZone { + bool in_zone = 1; +} + +message CsSceneSetSafeZone { + bool in_zone = 1; + uint64 id = 2; +} + +message ScSceneSetSafeZone { + bool in_zone = 1; + uint64 id = 2; +} + +message CsSceneQueryEntityExist { + int32 scene_num_id = 1; + uint64 id = 2; +} + +message ScSceneQueryEntityExist { + bool is_exist = 1; +} + +message CsSceneQueryInteractiveProperty { + int32 scene_num_id = 1; + uint64 id = 2; + int32 key = 3; +} + +message ScSceneQueryInteractiveProperty { + int32 scene_num_id = 1; + uint64 id = 2; + int32 key = 3; + DynamicParameter value = 4; +} + +message CsSceneSpawnSummon { + string summon_id = 1; + Vector position = 2; + Vector rotation = 3; + string skill_id = 4; + BattleBlackboard blackboard = 5; +} + +message ScSceneUnlockArea { + int32 scene_num_id = 1; + string area_id = 2; +} + +message CsSceneInteractTree { + string tree_type_id = 1; + Vector position = 2; + bool is_breaked = 3; +} + +message CsSceneTeleport { + int32 scene_num_id = 1; + Vector position = 2; + Vector rotation = 3; + int32 teleport_reason = 4; + PassThroughData pass_through_data = 5; +} + +message ScSceneTeleport { + repeated uint64 obj_id_list = 1; + int32 scene_num_id = 2; + Vector position = 3; + Vector rotation = 4; + uint32 server_time = 5; + int32 teleport_reason = 6; + uint64 tp_uuid = 7; + PassThroughData pass_through_data = 8; +} + +message CsSceneTeleportFinish { + uint64 tp_uuid = 1; +} + +message CsSceneMoveStateSet { + bool move_record_tag = 1; +} + +message CsSceneSubmitEther { +} + +message ScSceneSubmitEther { + int32 level = 1; + int32 count = 2; +} + +message AreaUnlockInfo { + string scene_id = 1; + repeated string unlock_area_id = 2; +} + +message ScSyncAllRoleScene { + int32 submit_ether_level = 1; + int32 submit_ether_count = 2; + repeated AreaUnlockInfo unlock_area_info = 3; + repeated SceneGradeInfo scene_grade_info = 4; +} + +message SceneGradeInfo { + int32 scene_num_id = 1; + int32 grade = 2; + int64 last_down_ts = 3; +} + +message CsSceneSetLastSafeZone { + int32 scene_num_id = 1; + Vector position = 2; + Vector rotation = 3; + int32 reason = 4; + uint64 source_script_id = 5; +} + +message CsSceneRepatriate { + int32 scene_num_id = 1; + int32 repatriate_source = 2; + PassThroughData pass_through_data = 3; +} + +message ScSceneRepatriate { + int32 scene_num_id = 1; + int32 repatriate_source = 2; +} + +message CsSceneSetBattle { + bool in_battle = 1; +} + +message CsSceneGradeModify { + int32 scene_num_id = 1; + int32 grade = 2; +} + +message ScSceneSetBattle { + bool in_battle = 1; +} + +message ScRewardToSceneBegin { + int32 reward_source_type = 1; + string source_template_id = 2; +} + +message ScRewardToSceneEnd { +} + +message ScSceneLevelScriptEventTrigger { +} + +message ScSceneLevelScriptSetDone { + int32 scene_num_id = 1; + uint64 script_id = 2; +} + +message ScSceneInteractiveEventTrigger { +} + +message ScSceneDropCreate { + SceneDrop drop_data = 1; +} + +message ScSceneDropDelete { + uint64 drop_id = 1; +} + +message ScSceneDropModify { + uint64 drop_id = 1; + map items = 2; + repeated ScdItemGrid inst_list = 3; + repeated uint64 del_inst_list = 4; +} + +message ScSceneGradeChangeNotify { + int32 scene_num_id = 1; + int32 grade = 2; + int64 ts = 3; +} + +message ScSceneClientIdInfo { + uint32 role_idx = 1; + uint64 last_max_idx = 2; +} + +message ScSceneUpdateInteractiveMeta { + int32 scene_num_id = 1; + uint64 id = 2; + int32 meta = 3; +} + +message CsSceneUpdateScriptTaskProgress { + int32 scene_num_id = 1; + uint64 script_id = 2; + string task_id = 3; + repeated ScriptTaskObjectiveValueOp objective_value_ops = 4; +} + +message ScriptTaskObjectiveValueOp { + string condition_id = 1; + int32 value = 2; + bool is_add = 3; +} + +message CsCheckSensitive { + string content = 1; +} + +message ScCheckSensitive { +} + +message CsSettlementSelectRequire { + string settlement_id = 1; + string settlement_require_id = 2; +} + +message ScSettlementSelectRequire { + string settlement_id = 1; + string settlement_require_id = 2; +} + +message Settlement { + string settlement_id = 1; + int32 level = 2; + int64 exp = 3; + string require_id = 4; + string officer_char_template_id = 5; + map reports = 6; + int64 unlock_ts = 7; + bool auto_submit = 8; + int64 last_manual_submit_time = 9; +} + +message SettlementDayReport { + map consume = 1; + map output = 2; + int64 exp = 3; + int32 level_up_count = 4; +} + +message ScSettlementSyncAll { + repeated Settlement settlements = 1; + int64 last_tick_time = 2; +} + +message ScSettlementSyncModify { + repeated Settlement settlements_modify = 1; + int64 last_tick_time = 2; +} + +message CsSettlementSetOfficer { + string settlement_id = 1; + string officer_template_id = 2; +} + +message ScSettlementSetOfficer { + string settlement_id = 1; + string officer_template_id = 2; +} + +message ScSettlementFinishRequires { + int64 next_finish_time = 1; +} + +message CsSettlementSetSubmitMode { + string settlement_id = 1; + bool auto_submit = 2; +} + +message ScSettlementSetSubmitMode { + string settlement_id = 1; + bool auto_submit = 2; +} + +message CsSettlementSubmitRequire { + string settlement_id = 1; +} + +message CsShopBuy { + string shop_id = 1; + string goods_id = 2; + int32 count = 3; +} + +message CsShopSwapMoney { + string source_money_id = 1; + string target_money_id = 2; + int64 swap_source_money_num = 3; +} + +message ScdShopDynamicGoods { + string goods_id = 1; + string goods_template_id = 2; +} + +message ScdShopRandomRefresh { + repeated ScdShopDynamicGoods dynamic_goods = 1; +} + +message ScdShopDiscount { + string goods_id = 1; + float discount = 2; +} + +message ScdShopUnlockConditions { + string id = 1; + map unlock_condition_values = 2; + map unlock_condition_flags = 3; +} + +message ScdShop { + string shop_id = 1; + int32 shop_refresh_type = 2; + map unlock_condition_values = 3; + map unlock_condition_flags = 4; + repeated ScdShopDiscount discounts = 5; + repeated ScdShopUnlockConditions goods_unlock_conditions = 6; + bool is_dynamic_good = 7; + bool is_dynamic_discount = 8; + oneof refresh_data { + ScdShopRandomRefresh random_refresh = 21; + } +} + +message ScdShopFrequencyLimit { + string frequency_limit_id = 1; + int32 count = 2; +} + +message ScShopSync { + repeated ScdShopUnlockConditions shop_group_conditions = 1; + repeated ScdShop shops = 2; + repeated ScdShopFrequencyLimit frequency_limits = 3; +} + +message ScShopSyncShopGroupCondition { + ScdShopUnlockConditions shop_group_conditions = 1; +} + +message ScShopModifyShop { + repeated ScdShop shops = 1; +} + +message ScShopSyncShopCondition { + ScdShopUnlockConditions shop_conditions = 1; +} + +message ScShopSyncGoodsCondition { + ScdShopUnlockConditions goods_conditions = 1; +} + +message ScShopModifyFrequencyLimit { + repeated ScdShopFrequencyLimit frequency_limits = 1; +} + +message ScShopDeleteFrequencyLimit { + repeated string frequency_limits = 1; +} + +message ScShopBuyResp { + string shop_id = 1; + string goods_id = 2; + int32 count = 3; +} + +message ScShopSwapMoney { + string source_money_id = 1; + string target_money_id = 2; + int64 cost_source_money_num = 3; + int64 get_target_money_num = 4; +} + +message CsCastSkill { + uint64 skill_seraial_id = 1; + uint64 attacker_obj_id = 2; + string skill_id = 3; + Vector attacker_position = 4; + Vector attacker_rotation = 5; + int64 time_stamp = 6; + int64 scaled_time_stamp = 7; + repeated uint64 target_obj_id_list = 8; +} + +message CsCastSkillEnd { + uint64 skill_seraial_id = 1; + uint64 attacker_obj_id = 2; +} + +message CsCastSkillEffect { + uint64 skill_seraial_id = 1; + uint64 skill_stage_idx = 2; + uint64 attacker_obj_id = 3; + int64 time_stamp = 4; + int64 scaled_time_stamp = 5; +} + +message ScCastSkill { + uint64 skill_seraial_id = 1; + uint64 attacker_obj_id = 2; + int64 time_stamp = 6; + int64 scaled_time_stamp = 7; +} + +message ScSyncHp { + uint64 obj_id = 1; + int32 hp = 2; +} + +message ScSyncPoise { + uint64 obj_id = 1; + int32 poise = 2; +} + +message ScSyncUltimateSpCellCnt { + uint64 obj_id = 1; + int32 ultimate_sp_cell_cnt = 2; +} + +message SnsMoment { + string moment_id = 1; + int64 timestamp = 2; + bool read = 3; + repeated int32 option = 4; + bool like = 5; +} + +message SnsChatInfo { + string chat_id = 1; + int32 chat_type = 2; + int64 timestamp = 3; + int32 member_num = 4; + repeated SnsDialogInfo dialogs = 5; + string signature_id = 6; +} + +message SnsDialogInfo { + string dialog_id = 1; + int64 timestamp = 2; + string cur_content_id = 3; + string chat_id = 5; + repeated int32 options = 4; + int32 dialog_type = 6; + bool is_end = 7; + bool is_read = 8; +} + +message CsSnsGetList { + SnsGetType sns_type = 1; +} + +enum SnsGetType { + All = 0; + Moment = 1; + Chat = 2; +} + +message ScSnsGetMomentList { + repeated SnsMoment moment_list = 1; +} + +message ScSnsGetChatList { + repeated SnsChatInfo chat_list = 1; +} + +message ScSyncSnsChatModify { + string chat_id = 1; + int32 chat_type = 2; + int32 member_num = 3; + string signature_id = 4; +} + +message CsSnsMomentRead { + repeated string moment_id = 1; +} + +message ScSnsMomentRead { + repeated string moment_id = 1; +} + +message ScSyncSnsAddDialog { + string chat_id = 1; + int32 chat_type = 2; + int64 timestamp = 3; + SnsDialogInfo dialog_info = 4; + int32 member_num = 5; + string signature_id = 6; +} + +message ScSyncSnsAddMoment { + SnsMoment moment_info = 1; +} + +message CsSnsMomentOption { + string moment_id = 1; + repeated int32 option = 2; + bool like = 3; + SnsMomentOption option_type = 4; +} + +enum SnsMomentOption { + Invalid = 0; + Like = 1; + Reply = 2; +} + +message ScSnsMomentOption { + string moment_id = 1; + repeated int32 option = 2; + bool like = 3; + SnsMomentOption option_type = 4; +} + +message CsSnsChatDialogOption { + string chat_id = 1; + string dialog_id = 2; + string cur_content_id = 3; + string jump_content_id = 4; + int32 option = 5; +} + +message ScSyncSnsDialogModify { + string chat_id = 1; + SnsDialogInfo dialog_info = 2; + bool set_option = 3; +} + +message CsSnsFinishDialog { + string chat_id = 1; + string dialog_id = 2; +} + +message CsSnsReadDialog { + string chat_id = 1; + string dialog_id = 2; +} + +message ScSnsReadDialog { + string chat_id = 1; + string dialog_id = 2; +} + +message ScdSpaceshipControlCenter { + map reports = 1; +} + +message ScdSpaceshipReport { + repeated int32 char_work_record = 1; + map output = 2; +} + +message ScdSpaceshipManufacturingStation { + SpaceshipManufacturingOrder remain_produce_order = 1; + map product_map = 2; + map reports = 3; +} + +message SpaceshipManufacturingOrder { + string formula_id = 1; + int32 remain_produce_count = 2; + int32 current_progress = 3; +} + +message ScdSpaceshipRoomAttrSource { + string char_id = 1; + int32 index = 2; + string skill_id = 3; + int32 source_type = 4; +} + +message ScdSpaceshipRoomAttrUnit { + int32 type = 1; + float value = 2; + bool is_not_working = 3; + ScdSpaceshipRoomAttrSource source = 4; +} + +message ScdSpaceshipRoomAttr { + float value = 1; + float theoretical_value = 2; + repeated ScdSpaceshipRoomAttrUnit base_attrs = 3; + repeated ScdSpaceshipRoomAttrUnit percent_attrs = 4; + repeated ScdSpaceshipRoomAttrUnit abs_addition_attrs = 5; +} + +message ScdSpaceshipRoom { + string id = 1; + int32 type = 2; + int32 level = 3; + map level_up_conditon_values = 4; + map level_up_condition_flags = 5; + repeated string stationed_char_list = 6; + map attrs_map = 7; + bool has_char_working = 8; + oneof room_data { + ScdSpaceshipControlCenter control_center = 21; + ScdSpaceshipManufacturingStation manufacturing_station = 22; + ScdSpaceshipGrowCabin grow_cabin = 23; + } +} + +message ScdSpaceshipGrowCabin { + repeated ScdSpaceshipGrowBox boxes = 1; + map reports = 2; +} + +message ScdSpaceshipGrowBox { + int32 box_id = 1; + string recipe_id = 2; + string preview_recipe_id = 3; + float progress = 4; + bool is_ready = 5; +} + +message ScdSpaceshipRoomLevelUp { + string id = 1; + int32 type = 2; + int32 level = 3; + map level_up_conditon_values = 4; + map level_up_condition_flags = 5; +} + +message ScdSpaceshipRoomStation { + string id = 1; + int32 type = 2; + repeated string stationed_char_list = 3; + map attrs_map = 4; + bool has_char_working = 5; + oneof produce_status { + ScdSpaceshipManufacturingStationProduceStatus manufacturing_station_produce_status = 21; + ScdSpaceshipGrowCabinProduceStatus grow_cabin_produce_status = 22; + } +} + +message ScdSpaceshipManufacturingStationProduceStatus { + SpaceshipManufacturingOrder remain_produce_order = 1; +} + +message ScdSpaceshipGrowCabinProduceStatus { + repeated ScdSpaceshipGrowBox boxes = 1; +} + +message ScdSpaceshipCharSkill { + int32 index = 1; + string skill_id = 2; +} + +message ScdSpaceshipChar { + string char_id = 1; + float physical_strength = 2; + int32 favorability = 3; + string stationed_room_id = 4; + bool is_working = 5; + repeated ScdSpaceshipCharSkill skills = 6; + bool is_presented = 7; + int32 recv_gift_cnt = 8; + string temp_reward_id = 9; +} + +message ScdSpaceshipCharSkillList { + string char_id = 1; + repeated ScdSpaceshipCharSkill skills = 2; +} + +message ScdSpaceshipCharStation { + string char_id = 1; + string stationed_room_id = 2; + bool is_working = 3; + float physical_strength = 4; +} + +message ScSpaceshipSync { + repeated ScdSpaceshipRoom rooms = 1; + repeated ScdSpaceshipChar chars = 2; +} + +message ScSpaceshipModifyRoom { + repeated ScdSpaceshipRoom rooms = 1; +} + +message ScSpaceshipSyncRoomLevelUp { + repeated ScdSpaceshipRoomLevelUp room_level_up_infos = 1; +} + +message ScSpaceshipModifyChar { + repeated ScdSpaceshipChar chars = 1; +} + +message ScSpaceshipSyncCharSkill { + repeated ScdSpaceshipCharSkillList char_skills = 1; +} + +message ScSpaceshipSyncRoomStation { + repeated ScdSpaceshipRoomStation rooms = 1; + repeated ScdSpaceshipCharStation chars = 2; +} + +message CharPresentGiftInfo { + string char_id = 1; + string reward_id = 2; +} + +message ScSpaceshipPresentCharInfo { + repeated CharPresentGiftInfo gift_infos = 1; +} + +message SpaceshipCharFavorabilityChangeInfo { + string char_id = 1; + int32 cur_fav = 2; +} + +message ScSpaceshipCharFavorabilityChange { + repeated SpaceshipCharFavorabilityChangeInfo change_infos = 1; +} + +message ScSpaceshipRecvGiftFromChar { + string char_id = 1; +} + +message ScSpaceshipPresentGiftToChar { + string char_id = 1; + int32 cur_fav = 2; + int32 recv_gift_cnt = 3; +} + +message ScSpaceshipManufacturingStationSync { + string room_id = 1; + SpaceshipManufacturingOrder remain_produce_order = 2; + map product_map = 3; +} + +message ScSpaceshipManufacturingStationCancel { + string room_id = 1; +} + +message ScSpaceshipManufacturingStationCollect { + string room_id = 1; +} + +message ScSpaceshipModifyGrowCabin { + string id = 1; + repeated ScdSpaceshipGrowBox boxes = 2; +} + +message ScSpaceshipGrowCabinBreed { + repeated ItemBundle items = 1; +} + +message ScSpaceshipGrowCabinSow { +} + +message ScSpaceshipGrowCabinHarvest { + repeated ItemBundle items = 1; +} + +message ScSpaceshipGrowCabinCancel { +} + +message ScSpaceshipReportCharWorkModify { + repeated ScdSpaceshipRoomReportCharWorkModify room_char_work_record = 1; +} + +message ScdSpaceshipRoomReportCharWorkModify { + string room_id = 1; + int64 ts = 2; + repeated int32 char_work_record = 3; +} + +message ScSpaceshipReportOutputModify { + string room_id = 1; + map output_report = 2; +} + +message ScdSpaceshipRoomReportOutput { + map output = 1; +} + +message ScSpaceshipManufacturingStationStart { + string room_id = 1; + SpaceshipManufacturingOrder remain_produce_order = 2; +} + +message CsSpaceshipBuildRoom { + string room_id = 1; +} + +message CsSpaceshipLevelUpRoom { + string room_id = 1; +} + +message CsSpaceshipStationChar { + string room_id = 1; + repeated string stationed_char_list = 2; +} + +message CsSpaceshipStationCharChangeWorkState { + string char_id = 1; + bool go_to_work = 2; +} + +message CsSpaceshipPresentGiftToChar { + string char_id = 1; + repeated ItemBundle gifts = 2; +} + +message CsSpaceshipRecvGiftFromChar { + string char_id = 1; +} + +message CsSpaceshipManufacturingStationCollect { + string room_id = 1; +} + +message CsSpaceshipManufacturingStationStart { + string room_id = 1; + string formula_id = 2; + int32 count = 3; +} + +message CsSpaceshipManufacturingStationCancel { + string room_id = 1; +} + +message CsSpaceshipManufacturingStationChangeOrder { + string room_id = 1; + string formula_id = 2; + int32 count = 3; +} + +message CsSpaceshipGrowCabinBreed { + string room_id = 1; + string recipe_id = 3; + int32 multi = 4; +} + +message CsSpaceshipGrowCabinSow { + string room_id = 1; + repeated CsdSpaceshipGrowCabinSow boxes = 2; +} + +message CsdSpaceshipGrowCabinSow { + string recipe_id = 1; + int32 box_id = 2; +} + +message CsSpaceshipGrowCabinClearPreviewRecipe { + string room_id = 1; + int32 box_id = 2; +} + +message CsSpaceshipGrowCabinHarvest { + string room_id = 1; + repeated int32 box_id_list = 2; + bool all = 3; +} + +message CsSpaceshipGrowCabinCancel { + string room_id = 1; + int32 box_id = 2; +} + +message CsSceneInteractSpInteractive { + uint64 obj_id = 1; + SpInteractiveOpType op_type = 2; + oneof op_payload { + CsdSpInteractiveDoodadCommonPick doodad_common_pick = 10; + CsdSpInteractiveDoodadCommonBreak doodad_common_break = 11; + CsdSpInteractiveCommonActive common_active = 12; + } +} + +enum SpInteractiveOpType { + SP_INTERACTIVE_OP_TYPE_NONE = 0; + DOODAD_COMMON_PICK = 1; + DOODAD_COMMON_BREAK = 2; + COMMON_ACTIVE = 3; + SP_INTERACTIVE_OP_TYPE_MAX = 4; +} + +message CsdSpInteractiveDoodadCommonPick { +} + +message CsdSpInteractiveDoodadCommonBreak { + int64 new_hp_ratio = 1; +} + +message CsdSpInteractiveCommonActive { +} + +message ScSceneInteractSpInteractive { + uint64 obj_id = 1; +} + +message StatInfo { + int32 type = 1; + uint32 value = 2; + int32 param = 3; +} + +message ScSyncAllStat { + repeated StatInfo stats_info = 1; +} + +message ScSyncStat { + StatInfo stat_info = 1; +} + +message SubmitSourceParamMission { + string quest_id = 1; +} + +message SubmitSourceParamInteractive { + uint64 obj_id = 2; +} + +message SubmitTerm { + repeated SubmitItem submit_item_list = 1; +} + +message CsSceneSubmitItem { + string submit_id = 1; + repeated SubmitTerm submit_item_term_list = 6; + SubmitSourceType source_type = 3; + oneof submit_source_param { + SubmitSourceParamMission mission = 4; + SubmitSourceParamInteractive interactive = 5; + } +} + +enum SubmitSourceType { + SUBMIT_SOURCE_TYPE_NONE = 0; + SUBMIT_SOURCE_TYPE_Mission = 1; + SUBMIT_SOURCE_TYPE_INTERACTIVE = 2; +} + +message ScSceneSubmitItem { + string submit_id = 1; + bool ret = 2; +} + +message CsSceneSubmitRecycle { + repeated SubmitItem submit_item_list = 1; +} + +message ScSceneSubmitRecycle { + bool ret = 1; +} + +message ScSyncTdSettlement { + string td_id = 1; + TdSettlementType settlement_type = 2; + string reward_id = 3; + int32 extra_bandwidth = 4; + int32 extra_battle_building_limit = 5; + int32 extra_travel_pole_limit = 6; +} + +enum TdSettlementType { + TD_Settlement_None = 0; + TD_Settlement_Passed = 1; + TD_Settlement_Leave = 2; + TD_Settlement_Defeat = 3; +} + +message CsTdGetTdList { + string stronghold_id = 1; +} + +message ScTdGetTdList { + string stronghold_id = 1; + repeated string unlock_td_list = 2; + repeated string completed_td_list = 3; + repeated string closed_td_list = 4; +} + +message ScSyncTdFullStatus { + repeated ScTdGetTdList full_data = 1; +} + +message CsTdStart { + string td_id = 1; + bool is_restart = 2; +} + +message ScTdStart { + string td_id = 1; + bool is_restart = 2; + int32 max_building_num = 3; +} + +message CsTdLeave { + string td_id = 1; +} + +message ScTdLeave { + string td_id = 1; +} + +message CsTdBuyBuilding { + string td_id = 1; + string building_id = 2; + int32 num = 3; +} + +message ScTdBuyBuilding { + string td_id = 1; + string building_id = 2; + int32 num = 3; +} + +message ScSyncTdDropItem { + uint32 drop_id = 1; + string item_id = 2; + uint32 num = 3; + Vector position = 4; + uint32 duration = 5; +} + +message CsTdPickDropItem { + repeated uint32 drop_id_list = 1; +} + +message ScTdPickDropItem { + repeated uint32 drop_id_list = 1; +} + +message CsTdDropExpired { + repeated uint32 drop_id_list = 1; +} + +message CsGameTimeFreezeStartReq { + int32 reason = 1; +} + +message CsGameTimeFreezeEndReq { + int32 reason = 1; +} + +message ScGameTimeFreezeStartRsp { + int32 reason = 1; + bool in_time_freeze = 2; +} + +message ScGameTimeFreezeEndRsp { + int32 reason = 1; + bool in_time_freeze = 2; +} + +message ScSyncAllUnlock { + repeated int32 unlock_systems = 1; +} + +message ScUnlockSystem { + int32 unlock_system_type = 1; +} + +message MoneyInfo { + string id = 1; + uint64 amount = 2; +} + +message CsMoneyChange { + string money_from_id = 1; + string money_to_id = 2; + uint64 money_from_count = 3; +} + +message ScSyncWallet { + repeated MoneyInfo money_list = 1; +} + +message ScWalletSyncMoney { + string id = 1; + uint64 amount = 2; + int64 op_amount = 3; +} + +message ScRewardDropMoneyToast { + string id = 1; + int64 amount = 2; + Vector pos = 3; +} + +message CsWeaponPuton { + uint64 charid = 1; + uint64 weaponid = 2; +} + +message ScWeaponPuton { + uint64 charid = 1; + uint64 weaponid = 2; + uint64 offweaponid = 3; + uint64 put_off_charid = 4; +} + +message CsWeaponBreakthrough { + uint64 weaponid = 1; +} + +message ScWeaponBreakthrough { + uint64 weaponid = 1; + uint64 breakthrough_lv = 2; +} + +message CsWeaponRefineUpgrade { + uint64 weaponid = 1; + uint64 upgrade_refine_lv = 2; + repeated uint64 cost_weapon_ids = 3; +} + +message ScWeaponRefineUpgrade { + uint64 weaponid = 1; + uint64 refine_lv = 2; +} + +message CsWeaponAddExp { + uint64 weaponid = 1; + map cost_item_id2_count = 2; + repeated uint64 cost_weapon_ids = 3; +} + +message ScWeaponAddExp { + uint64 weaponid = 1; + uint64 new_exp = 2; + uint64 weapon_lv = 3; +} + +message CsWeaponAttachGem { + uint64 weaponid = 1; + uint64 gemid = 2; +} + +message ScWeaponAttachGem { + uint64 weaponid = 1; + uint64 gemid = 2; + uint64 detach_gemid = 3; + uint64 detach_gem_weaponid = 4; +} + +message CsWeaponDetachGem { + uint64 weaponid = 1; +} + +message ScWeaponDetachGem { + uint64 weaponid = 1; + uint64 detach_gemid = 2; +} + +message ScSyncAllWiki { + repeated uint32 latest_unlock = 1; +} + +message CsUnlockWiki { + uint32 wiki_id = 1; +} + +message CsMarkWikiRead { + repeated uint32 wiki_ids = 1; +} + +message Opts { + optional bool unique = 1; +} + diff --git a/Campofinale/Network/Packet.cs b/Campofinale/Network/Packet.cs index 2e0437c..f9f4515 100644 --- a/Campofinale/Network/Packet.cs +++ b/Campofinale/Network/Packet.cs @@ -165,6 +165,7 @@ namespace Campofinale.Network PutUInt16(data, (ushort)body.Length, 1); PutByteArray(data, head.ToByteArray(), 3); PutByteArray(data, body, 3 + head.ToByteArray().Length); + if(Server.config!=null) if (Server.config.logOptions.packets && !Server.scMessageToHide.Contains((ScMsgId)msgId)) Logger.Print($"Sending Packet: {((ScMsgId)msgId).ToString().Pastel(Color.LightBlue)} Id: {msgId} with {data.Length} Bytes"); @@ -193,5 +194,27 @@ namespace Campofinale.Network seqNext = csHead_.UpSeqid; return new Packet() { csHead = csHead_, finishedBody = BodyBytes,cmdId=csHead_.Msgid }; } + /// + /// Read the byteArray as a valid packet + /// + /// + /// The decoded packet + public static Packet Read(byte[] byteArray) + { + byte headLength = GetByte(byteArray, 0); + ushort bodyLength = GetUInt16(byteArray, 1); + + byte[] csHeadBytes = new byte[headLength]; + byte[] BodyBytes = new byte[bodyLength]; + Array.Copy(byteArray, 3, csHeadBytes, 0, headLength); + Array.Copy(byteArray, 3 + headLength, BodyBytes, 0, bodyLength); + CSHead csHead_ = CSHead.Parser.ParseFrom(csHeadBytes); + /*if (Server.config.logOptions.packets && !Server.csMessageToHide.Contains((CsMsgId)csHead_.Msgid)) + { + Logger.Print(csHead_.ToString()); + }*/ + seqNext = csHead_.UpSeqid; + return new Packet() { csHead = csHead_, finishedBody = BodyBytes, cmdId = csHead_.Msgid }; + } } } diff --git a/Campofinale/Program.cs b/Campofinale/Program.cs index 2663065..8ae113c 100644 --- a/Campofinale/Program.cs +++ b/Campofinale/Program.cs @@ -1,13 +1,80 @@ using Campofinale; using Newtonsoft.Json; +using System.Net.Sockets; +using System.Net; +using Campofinale.Network; +using Campofinale.Protocol; +using Google.Protobuf; +using Pastel; +using System.Drawing; class Program { static void Main(string[] args) { StartServer(args); + //FakeClientTester(); } + public static byte[] ConcatenateByteArrays(byte[] array1, byte[] array2) + { + return array1.Concat(array2).ToArray(); + } + private static void FakeClientTester() + { + string serverIp = "beyond-ric.gryphline.com"; + int serverPort = 30000; + Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IPAddress[] addresses = Dns.GetHostAddresses(serverIp); + + IPAddress ipAddress = addresses[0]; + + socket.Connect(new IPEndPoint(ipAddress, serverPort)); + + socket.Send(Packet.EncodePacket((int)CsMsgId.CsLogin,new CsLogin() { ClientVersion="0.5.5",Uid= "", Token= "", Env=EnvType.Prod,PlatformId=ClientPlatformType.Windows,Area=AreaType.Oversea,ClientResVersion="", LoginToken= "" }.ToByteArray())); + + while (true) + { + byte[] buffer = new byte[3]; + int length = socket.Receive(buffer); + if (length == 3) + { + Packet packet = null; + byte headLength = Packet.GetByte(buffer, 0); + ushort bodyLength = Packet.GetUInt16(buffer, 1); + byte[] moreData = new byte[bodyLength + headLength]; + while (socket.Available < moreData.Length) + { + + } + int mLength = socket.Receive(moreData); + if (mLength == moreData.Length) + { + buffer = ConcatenateByteArrays(buffer, moreData); + packet = Packet.Read(buffer); + + switch ((ScMsgId)packet.cmdId) + { + case ScMsgId.ScLogin: + ScLogin p1 = ScLogin.Parser.ParseFrom(packet.finishedBody); + Console.WriteLine(JsonConvert.SerializeObject(p1)); + break; + case ScMsgId.ScNtfErrorCode: + ScNtfErrorCode p2 = ScNtfErrorCode.Parser.ParseFrom(packet.finishedBody); + Console.WriteLine(JsonConvert.SerializeObject(p2)); + break; + default: + string base64 = Convert.ToBase64String(packet.finishedBody); + Console.WriteLine($"{(ScMsgId)packet.cmdId}: {base64}"); + break; + } + + + + } + } + } + } private static void StartServer(string[] args) { Console.Title = "Initializing..."; From 35f8fbb2b26e3add8497655d9d6b5d6c596cda34 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 18 Jul 2025 14:49:33 +0200 Subject: [PATCH 17/27] another try to improve entity spawning and fix loading but still loading issues --- Campofinale/Game/SceneManager.cs | 65 +++++++++---------- .../Packets/Cs/HandleCsSceneMoveStateSet.cs | 2 +- .../Packets/Cs/HandleCsSceneTeleport.cs | 6 ++ Campofinale/Resource/ResourceManager.cs | 28 ++++++++ Campofinale/Utils/SnowflakeIdGenerator.cs | 56 ++++++++++++++++ 5 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 Campofinale/Utils/SnowflakeIdGenerator.cs diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 35a1ada..ff9e569 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -4,10 +4,12 @@ using Campofinale.Packets.Sc; using Campofinale.Resource; using Campofinale.Resource.Dynamic; using MongoDB.Bson.Serialization.Attributes; +using System; using System.Text.Json.Serialization; using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; +using static Campofinale.Resource.ResourceManager.LevelScene.LevelData.LevelFunctionAreaData; namespace Campofinale.Game { @@ -235,7 +237,6 @@ namespace Campofinale.Game { if (scene != null) { - scene.alreadyLoaded = false; scene.Unload(); } } @@ -256,11 +257,11 @@ namespace Campofinale.Game [BsonIgnore,JsonIgnore] public List entities = new(); [BsonIgnore, JsonIgnore] - public bool alreadyLoaded = false; - [BsonIgnore, JsonIgnore] public List activeScripts = new(); public List scripts = new(); + [BsonIgnore, JsonIgnore] + private LevelFunctionRangeData currentAreaRange = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -367,17 +368,12 @@ namespace Campofinale.Game entities.Add(entity); }); - - - UpdateShowEntities(); } public void SpawnEntity(Entity en,bool spawnedCheck=true) { - en.spawned = true; - GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en })); } public bool GetActiveScript(ulong id) @@ -392,10 +388,22 @@ namespace Campofinale.Game return true; } } + + private void UpdateArea() + { + LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); + lv_scene.levelData.functionArea.ranges.ForEach(range => + { + if (range.IsObjectInside(GetOwner().position)) + { + currentAreaRange=range; + } + }); + } //Bug on scene 101: spawning entities in this way make the game break if you try to load another scene from scene 101 public async void UpdateShowEntities() { - + UpdateArea(); List toSpawn = new(); List toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false); toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position))); @@ -404,6 +412,7 @@ namespace Campofinale.Game if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { + if(currentAreaRange.IsObjectInside(e.Position)) if (!e.defaultHide) { toSpawn.Add(e); @@ -423,34 +432,18 @@ namespace Campofinale.Game GetOwner().Send(new PacketScObjectEnterView(GetOwner(), chunk)); } } + List toDespawn=new(); + foreach(Entity en in GetEntityExcludingChar().FindAll(e=> e.spawned==true)) + { + if (!currentAreaRange.IsObjectInside(en.Position)) + { + toDespawn.Add(en.guid); + en.spawned = false; + } - /* foreach(Entity en in GetEntityExcludingChar()) - { - float minDis = 100; - - //todo new system - if (en.Position.DistanceXZ(GetOwner().position) < minDis) - { - if (!en.spawned) - { - SpawnEntity(en); - - - } - } - else - { - - /*if (en.spawned) - { - - en.spawned = false; - GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), new List() { en.guid })); - en.Position=en.BornPos; - en.Rotation = en.Rotation; - } - } - }*/ + } + if(toDespawn.Count > 0) + GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), toDespawn)); } public Player GetOwner() diff --git a/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs b/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs index 21c3f0c..5a7f8e8 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneMoveStateSet.cs @@ -11,7 +11,7 @@ namespace Campofinale.Packets.Cs { CsSceneMoveStateSet req = packet.DecodeBody(); //req. - + } } diff --git a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs index 06a9ded..b4c77b6 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs @@ -1,5 +1,6 @@ using Campofinale.Network; using Campofinale.Protocol; +using Campofinale.Utils; namespace Campofinale.Packets.Cs { @@ -26,6 +27,9 @@ namespace Campofinale.Packets.Cs } else { + uint unixTimestamp = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + var generator = new SnowflakeIdGenerator(machineId: 1); + long id = generator.GenerateId(); ScSceneTeleport t = new() { TeleportReason = req.TeleportReason, @@ -33,6 +37,8 @@ namespace Campofinale.Packets.Cs Position = req.Position, Rotation = req.Rotation, SceneNumId = req.SceneNumId, + ServerTime = unixTimestamp, + TpUuid= (ulong)id }; session.curSceneNumId = t.SceneNumId; session.Send(ScMsgId.ScSceneTeleport, t); diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 63ec522..448d3a5 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -2,6 +2,8 @@ using Campofinale.Resource.Json; using Campofinale.Resource.Table; using Newtonsoft.Json; +using System.Numerics; +using System; using static Campofinale.Resource.ResourceManager.LevelScene; namespace Campofinale.Resource @@ -549,6 +551,7 @@ namespace Campofinale.Resource public List worldWayPointSets = new(); public List factoryRegions = new(); public List spawners = new(); + public LevelFunctionAreaData functionArea = new(); public void Merge(LevelData other) { this.sceneId = other.sceneId; @@ -560,6 +563,7 @@ namespace Campofinale.Resource this.worldWayPointSets.AddRange(other.worldWayPointSets); this.factoryRegions.AddRange(other.factoryRegions); this.spawners.AddRange(other.spawners); + this.functionArea.ranges.AddRange(other.functionArea.ranges); } public class WorldWayPointSets @@ -567,6 +571,26 @@ namespace Campofinale.Resource public int id; public Dictionary pointIdToIndex = new(); } + + public class LevelFunctionAreaData + { + public List ranges = new(); + + public class LevelFunctionRangeData + { + public Vector3f m_center = new(); + public Vector3f m_size = new(); + + public bool IsObjectInside(Vector3f position) + { + Vector3f halfSize = m_size * 0.5f; + + return Math.Abs(position.x - m_center.x) <= halfSize.x && + Math.Abs(position.y - m_center.y) <= halfSize.y && + Math.Abs(position.z - m_center.z) <= halfSize.z; + } + } + } public class LevelSpawnerData { public ulong spawnerId; @@ -949,6 +973,10 @@ namespace Campofinale.Resource public Vector3f() { + } + public static Vector3f operator *(Vector3f v, float scalar) + { + return new Vector3f(v.x * scalar, v.y * scalar, v.z * scalar); } public Vector3f(float x, float y, float z) { diff --git a/Campofinale/Utils/SnowflakeIdGenerator.cs b/Campofinale/Utils/SnowflakeIdGenerator.cs new file mode 100644 index 0000000..8568db4 --- /dev/null +++ b/Campofinale/Utils/SnowflakeIdGenerator.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Utils +{ + public class SnowflakeIdGenerator + { + private static readonly DateTime Epoch = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private readonly int _machineId; // es. 0–31 (5 bit) + private int _sequence = 0; + private long _lastTimestamp = -1L; + + private readonly object _lock = new object(); + + public SnowflakeIdGenerator(int machineId) + { + _machineId = machineId & 0x1F; // 5 bit + } + + public long GenerateId() + { + lock (_lock) + { + long timestamp = GetCurrentTimestamp(); + + if (timestamp == _lastTimestamp) + { + _sequence = (_sequence + 1) & 0xFFF; // 12 bit + if (_sequence == 0) + { + // Attendi il prossimo millisecondo + while ((timestamp = GetCurrentTimestamp()) <= _lastTimestamp) ; + } + } + else + { + _sequence = 0; + } + + _lastTimestamp = timestamp; + + return ((timestamp << 22) | ((long)_machineId << 12) | (long)_sequence); + } + } + + private long GetCurrentTimestamp() + { + return (long)(DateTime.UtcNow - Epoch).TotalMilliseconds; + } + } + +} From 67d3acea545be2a90ff29089c91bd98f2db47851 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Tue, 22 Jul 2025 23:54:55 +0200 Subject: [PATCH 18/27] AdventureBookManager --- Campofinale/Campofinale.csproj | 3 + Campofinale/Commands/Handlers/CommandAdd.cs | 2 +- .../Commands/Handlers/CommandCharInfo.cs | 2 +- Campofinale/Commands/Handlers/CommandLevel.cs | 2 +- .../Commands/Handlers/CommandRemove.cs | 2 +- Campofinale/Data/Conditions.json | 19 ++ Campofinale/Database/Database.cs | 31 ++- .../Game/Adventure/AdventureBookManager.cs | 252 ++++++++++++++++++ .../Game/{Character => Char}/Character.cs | 8 +- Campofinale/Game/Entities/EntityCharacter.cs | 2 +- .../Game/Inventory/InventoryManager.cs | 8 +- Campofinale/Game/SceneManager.cs | 2 +- Campofinale/Http/Dispatch.cs | 2 +- .../Cs/HandleCsAdventureTakeRewardAll.cs | 19 ++ Campofinale/Packets/Cs/HandleCsBattleOp.cs | 2 +- Campofinale/Packets/Cs/HandleCsCharLevelUp.cs | 2 +- .../Packets/Cs/HandleCsCharPotentialUnlock.cs | 2 +- .../Cs/HandleCsCharUnlockTalentNode.cs | 2 +- Campofinale/Packets/Cs/HandleCsEquipPutoff.cs | 2 +- Campofinale/Packets/Cs/HandleCsEquipPuton.cs | 2 +- Campofinale/Packets/Cs/HandleCsLogin.cs | 8 +- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 2 +- .../Cs/HandleCsTakeAdventureTaskReward.cs | 19 ++ .../Cs/HandleCsTakeAllAdventureTaskReward.cs | 20 ++ Campofinale/Packets/Cs/HandleCsWeaponPuton.cs | 2 +- .../Packets/Sc/PacketScAdventureBookSync.cs | 17 +- .../Packets/Sc/PacketScCharBagAddChar.cs | 2 +- .../Packets/Sc/PacketScCharBagDelChar.cs | 2 +- .../Sc/PacketScCharUnlockTalentNode.cs | 2 +- Campofinale/Player.cs | 17 +- Campofinale/Program.cs | 3 +- Campofinale/Resource/GameEnums.cs | 192 ++++++++++++- Campofinale/Resource/Json/ConditionData.cs | 24 ++ Campofinale/Resource/ResourceManager.cs | 5 +- Campofinale/Resource/ServerEnums.cs | 14 + Campofinale/Server.cs | 11 + 36 files changed, 648 insertions(+), 58 deletions(-) create mode 100644 Campofinale/Data/Conditions.json create mode 100644 Campofinale/Game/Adventure/AdventureBookManager.cs rename Campofinale/Game/{Character => Char}/Character.cs (97%) create mode 100644 Campofinale/Packets/Cs/HandleCsAdventureTakeRewardAll.cs create mode 100644 Campofinale/Packets/Cs/HandleCsTakeAdventureTaskReward.cs create mode 100644 Campofinale/Packets/Cs/HandleCsTakeAllAdventureTaskReward.cs create mode 100644 Campofinale/Resource/Json/ConditionData.cs create mode 100644 Campofinale/Resource/ServerEnums.cs diff --git a/Campofinale/Campofinale.csproj b/Campofinale/Campofinale.csproj index c3242e2..5cc10f4 100644 --- a/Campofinale/Campofinale.csproj +++ b/Campofinale/Campofinale.csproj @@ -50,6 +50,9 @@ Always + + Always + Always diff --git a/Campofinale/Commands/Handlers/CommandAdd.cs b/Campofinale/Commands/Handlers/CommandAdd.cs index fd88b2b..1082a7b 100644 --- a/Campofinale/Commands/Handlers/CommandAdd.cs +++ b/Campofinale/Commands/Handlers/CommandAdd.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Game.Inventory; using Campofinale.Packets.Sc; diff --git a/Campofinale/Commands/Handlers/CommandCharInfo.cs b/Campofinale/Commands/Handlers/CommandCharInfo.cs index 6dc08ef..fa7bacb 100644 --- a/Campofinale/Commands/Handlers/CommandCharInfo.cs +++ b/Campofinale/Commands/Handlers/CommandCharInfo.cs @@ -1,5 +1,5 @@ using static Campofinale.Resource.ResourceManager; -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Database; using Campofinale.Game.Inventory; diff --git a/Campofinale/Commands/Handlers/CommandLevel.cs b/Campofinale/Commands/Handlers/CommandLevel.cs index 757fe87..768bb67 100644 --- a/Campofinale/Commands/Handlers/CommandLevel.cs +++ b/Campofinale/Commands/Handlers/CommandLevel.cs @@ -2,7 +2,7 @@ using Campofinale.Packets.Sc; using Campofinale.Resource; -namespace Campofinale.Game.Character +namespace Campofinale.Game.Char { public static class CharacterManager { diff --git a/Campofinale/Commands/Handlers/CommandRemove.cs b/Campofinale/Commands/Handlers/CommandRemove.cs index fcec4a7..eca0184 100644 --- a/Campofinale/Commands/Handlers/CommandRemove.cs +++ b/Campofinale/Commands/Handlers/CommandRemove.cs @@ -1,5 +1,5 @@ using Campofinale.Database; -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Packets.Sc; namespace Campofinale.Commands.Handlers; diff --git a/Campofinale/Data/Conditions.json b/Campofinale/Data/Conditions.json new file mode 100644 index 0000000..272d0c0 --- /dev/null +++ b/Campofinale/Data/Conditions.json @@ -0,0 +1,19 @@ +{ + "cond_ab_01_01": + { + "args": [ + "10" + ] + }, + "cond_daily_001":{ + "args":[ + "DailyLogin" + ] + }, + "cond_daily_005": + { + "args":[ + "DailyCharLevelUp" + ] + } +} \ No newline at end of file diff --git a/Campofinale/Database/Database.cs b/Campofinale/Database/Database.cs index 84af0ee..d174064 100644 --- a/Campofinale/Database/Database.cs +++ b/Campofinale/Database/Database.cs @@ -1,5 +1,6 @@ using Campofinale.Game; -using Campofinale.Game.Character; +using Campofinale.Game.Adventure; +using Campofinale.Game.Char; using Campofinale.Game.Gacha; using Campofinale.Game.Inventory; using Campofinale.Game.MissionSys; @@ -9,6 +10,7 @@ using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; using System.Security.Cryptography; using System.Text; +using static Campofinale.Game.Adventure.AdventureBookManager; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Database @@ -33,6 +35,7 @@ namespace Campofinale.Database public long maxDashEnergy = 250; public uint curStamina; public long nextRecoverTime; + public long nextDailyReset; public List scenes = new(); public Dictionary> bitsets = new(); public PlayerSafeZoneInfo savedSafeZone = new(); @@ -84,6 +87,10 @@ namespace Campofinale.Database { return _database.GetCollection("missionsData").Find(c => c.roleId == roleId).FirstOrDefault(); } + public AdventureBookData LoadAdventureBookData(ulong roleId) + { + return _database.GetCollection("adventureBookData").Find(c => c.roleId == roleId).FirstOrDefault(); + } public List LoadCharacters(ulong roleId) { return _database.GetCollection("avatars").Find(c=>c.owner== roleId).ToList(); @@ -152,7 +159,8 @@ namespace Campofinale.Database bitsets=player.bitsetManager.bitsets, savedSafeZone = player.savedSaveZone, gender=player.gender, - bag=player.inventoryManager.items.bag + bag=player.inventoryManager.items.bag, + nextDailyReset = player.nextDailyReset, }; UpsertPlayerData(data); } @@ -256,6 +264,23 @@ namespace Campofinale.Database new ReplaceOptions { IsUpsert = true } ); } + public void UpsertAdventureBookData(AdventureBookManager.AdventureBookData data) + { + if (data._id == ObjectId.Empty) + { + data._id = ObjectId.GenerateNewId(); + } + var collection = _database.GetCollection("adventureBookData"); + + var filter = + Builders.Filter.Eq(c => c.roleId, data.roleId); + + var result = collection.ReplaceOne( + filter, + data, + new ReplaceOptions { IsUpsert = true } + ); + } public void UpsertCharacter(Character character) { if (character._id == ObjectId.Empty) @@ -402,6 +427,6 @@ namespace Campofinale.Database } } - + } } diff --git a/Campofinale/Game/Adventure/AdventureBookManager.cs b/Campofinale/Game/Adventure/AdventureBookManager.cs new file mode 100644 index 0000000..719673f --- /dev/null +++ b/Campofinale/Game/Adventure/AdventureBookManager.cs @@ -0,0 +1,252 @@ +using Campofinale.Database; +using Campofinale.Game.Factory; +using Campofinale.Game.Spaceship; +using Campofinale.Resource; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static Campofinale.Resource.ResourceManager; +using MongoDB.Bson.Serialization.IdGenerators; +using Campofinale.Game.Char; +using Campofinale.Resource.Json; +using Campofinale.Protocol; + +namespace Campofinale.Game.Adventure +{ + public class AdventureBookManager + { + public Player player; + public AdventureBookData data = new(); + + public AdventureBookManager(Player player) + { + this.player = player; + } + public void Load() + { + AdventureBookData toLoad= DatabaseManager.db.LoadAdventureBookData(player.roleId); + if (toLoad != null) + { + data = toLoad; + } + else + { + data.roleId = player.roleId; + } + if (data.adventureBookStage == 0) + { + InitNextStage(); + } + } + + public void DailyReset() + { + data.tasks.RemoveAll(t => t.GetTaskTable().taskType == AdventureTaskType.Daily); + data.dailyActivation = 0; + data.dailyCharLevelUp = 0; + data.dailyLogin = 0; + ResourceManager.adventureTaskTable.Values.ToList().ForEach(task => + { + if (task.taskType == AdventureTaskType.Daily) + { + data.tasks.Add(new GameAdventureTask() + { + adventureTaskId = task.adventureTaskId, + claimed = false + }); + } + }); + } + public void Save() + { + DatabaseManager.db.UpsertAdventureBookData(data); + } + public void TaskUpdate(ConditionType condType, object obj=null) + { + List toUpdate = new(); + data.tasks.FindAll(t=>t.GetTaskTable().conditionType==condType).ForEach(task => + { + if(task.TaskUpdate(this.player, obj)) + { + toUpdate.Add(task); + } + }); + if (toUpdate.Count > 0) + { + ScAdventureTaskModify modify = new ScAdventureTaskModify() + { + + }; + toUpdate.ForEach(t => + { + modify.Tasks.Add(t.ToProto()); + }); + player.Send(ScMsgId.ScAdventureTaskModify, modify); + } + } + public void InitNextStage(bool notify=false) + { + data.adventureBookStage++; + data.tasks.RemoveAll(t => t.GetTaskTable().taskType == AdventureTaskType.AdventureBook); + ResourceManager.adventureTaskTable.Values.ToList().ForEach(task => + { + if(task.adventureBookStage == data.adventureBookStage) + { + data.tasks.Add(new GameAdventureTask() + { + adventureTaskId = task.adventureTaskId, + claimed=false + }); + } + }); + //TODO Update everything + } + + public void ClaimTask(string taskId) + { + data.tasks.ForEach(t => + { + if (t.adventureTaskId == taskId && t.GetState() == AdventureTaskState.Completed) + { + t.ClaimRewards(player); + } + }); + } + + public void ClaimTasks(AdventureTaskType taskType) + { + data.tasks.ForEach(t => + { + if (t.GetTaskTable().taskType==taskType && t.GetState() == AdventureTaskState.Completed) + { + t.ClaimRewards(player); + } + }); + } + + public class GameAdventureTask + { + public string adventureTaskId; + public int progress; + public bool claimed; + + public void ClaimRewards(Player player) + { + player.inventoryManager.AddRewards(GetTaskTable().rewardId, player.position, 0); + claimed= true; + ScAdventureTaskModify modify = new() + { + Tasks = + { + ToProto() + } + }; + player.Send(ScMsgId.ScAdventureTaskModify, modify); + } + public AdventureTaskState GetState() + { + if(progress < GetTaskTable().progressToCompare) + { + return AdventureTaskState.Processing; + }else if (!claimed) + { + return AdventureTaskState.Completed; + } + else + { + return AdventureTaskState.Rewarded; + } + } + public bool TaskUpdate(Player owner, object obj) + { + ConditionType condType = GetTaskTable().conditionType; + ConditionData cond; + if(ResourceManager.conditions.TryGetValue(GetTaskTable().conditionId, out cond)) + { + int count = 0; + switch (condType) + { + case ConditionType.CheckStatisticVal: + switch (Enum.Parse(typeof(StatType), cond.Get(0))) + { + case StatType.DailyCharLevelUp: + count = owner.adventureBookManager.data.dailyCharLevelUp; + break; + case StatType.DailyLogin: + count = owner.adventureBookManager.data.dailyLogin; + break; + default: + break; + } + if (count > progress) + { + progress = count; + return true; + } + else + { + return false; + } + case ConditionType.CheckGreaterCharLevelNum: + count = 0; + owner.chars.ForEach(c => + { + if(c.level >= cond.ToInt(0)) + { + count++; + } + }); + if (count > progress) + { + progress = count; + return true; + } + else + { + return false; + } + default: + return false; + } + } + else + { + return false; + } + + } + public AdventureTaskTable GetTaskTable() + { + return ResourceManager.adventureTaskTable.Values.ToList().Find(a => a.adventureTaskId == adventureTaskId); + } + + public AdventureTask ToProto() + { + return new AdventureTask() + { + Progress = progress, + State = (int)GetState(), + TaskId = adventureTaskId, + }; + } + } + public class AdventureBookData + { + [BsonId(IdGenerator = typeof(ObjectIdGenerator))] + public ObjectId _id { get; set; } + public ulong roleId; + public int adventureBookStage = 0; + public int dailyActivation = 0; + public List tasks = new(); + public int dailyCharLevelUp = 0; + public int dailyLogin = 0; + + } + } + +} diff --git a/Campofinale/Game/Character/Character.cs b/Campofinale/Game/Char/Character.cs similarity index 97% rename from Campofinale/Game/Character/Character.cs rename to Campofinale/Game/Char/Character.cs index 86b8414..7004c11 100644 --- a/Campofinale/Game/Character/Character.cs +++ b/Campofinale/Game/Char/Character.cs @@ -10,7 +10,7 @@ using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.CharGrowthTable; using static Campofinale.Resource.ResourceManager.WeaponUpgradeTemplateTable; -namespace Campofinale.Game.Character +namespace Campofinale.Game.Char { public class Character { @@ -459,8 +459,6 @@ namespace Campofinale.Game.Character ScCharLevelUp levelUp = new() { CharObjID = guid, - - }; ScCharSyncLevelExp synclevel = new() { @@ -471,6 +469,10 @@ namespace Campofinale.Game.Character GetOwner().Send(ScMsgId.ScCharSyncLevelExp, synclevel); GetOwner().Send(ScMsgId.ScCharLevelUp, levelUp); GetOwner().Send(new PacketScSyncWallet(GetOwner())); + GetOwner().adventureBookManager.TaskUpdate(ConditionType.CheckGreaterCharLevelNum); + GetOwner().adventureBookManager.TaskUpdate(ConditionType.CharMaxLevel); + GetOwner().adventureBookManager.data.dailyCharLevelUp++; + GetOwner().adventureBookManager.TaskUpdate(ConditionType.CheckStatisticVal); } } } diff --git a/Campofinale/Game/Entities/EntityCharacter.cs b/Campofinale/Game/Entities/EntityCharacter.cs index 806f932..ffc9689 100644 --- a/Campofinale/Game/Entities/EntityCharacter.cs +++ b/Campofinale/Game/Entities/EntityCharacter.cs @@ -98,7 +98,7 @@ namespace Campofinale.Game.Entities GetOwner().Send(ScMsgId.ScCharSyncStatus, state); GetOwner().Send(ScMsgId.ScEntityPropertyChange, prop); } - public Character.Character GetChar() + public Char.Character GetChar() { return GetOwner().chars.Find(c => c.guid == guid); } diff --git a/Campofinale/Game/Inventory/InventoryManager.cs b/Campofinale/Game/Inventory/InventoryManager.cs index fa7b733..fdf4620 100644 --- a/Campofinale/Game/Inventory/InventoryManager.cs +++ b/Campofinale/Game/Inventory/InventoryManager.cs @@ -63,8 +63,12 @@ namespace Campofinale.Game.Inventory { id=bundle.id }; - - if (!item.InstanceType()) + if(bundle.id == "item_daily_activation") + { + owner.adventureBookManager.data.dailyActivation += bundle.count; + continue; + } + if (!item.InstanceType() || sourceType == 0) { item = AddItem(bundle.id, bundle.count); end.RewardVirtualList.Add(new RewardItem() diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index ff9e569..3602800 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -46,7 +46,7 @@ namespace Campofinale.Game public void LoadCurrentTeamEntities() { globalEntities.RemoveAll(e => e is EntityCharacter); - foreach (Character.Character chara in player.GetCurTeam()) + foreach (Char.Character chara in player.GetCurTeam()) { EntityCharacter ch = new(chara.guid, player.roleId); globalEntities.Add(ch); diff --git a/Campofinale/Http/Dispatch.cs b/Campofinale/Http/Dispatch.cs index 24d56be..17a271f 100644 --- a/Campofinale/Http/Dispatch.cs +++ b/Campofinale/Http/Dispatch.cs @@ -156,7 +156,7 @@ namespace Campofinale.Http string appCode = ctx.Request.Query.Elements["appCode"]; - string resp = "{\"data\":{\"agreementUrl\":{\"register\":\"https://user.gryphline.com/{language}/protocol/plain/terms_of_service\",\"privacy\":\"https://user.gryphline.com/{language}/protocol/plain/privacy_policy\",\"unbind\":\"https://user.gryphline.com/{language}/protocol/plain/endfield/privacy_policy\",\"account\":\"https://user.gryphline.com/{language}/protocol/plain/terms_of_service\",\"game\":\"https://user.gryphline.com/{language}/protocol/plain/endfield/privacy_policy\"},\"app\":{\"googleAndroidClientId\":\"\",\"googleIosClientId\":\"\",\"enableAutoLogin\":true,\"enablePayment\":true,\"enableGuestRegister\":false,\"needShowName\":true,\"displayName\":{\"en-us\":\"Arknights: Endfield\",\"ja-jp\":\"アークナイツ:エンドフィールド\",\"ko-kr\":\"명일방주:엔드필드\",\"zh-cn\":\"明日方舟:终末地\",\"zh-tw\":\"明日方舟:終末地\"},\"unbindAgreement\":[],\"unbindLimitedDays\":30,\"unbindCoolDownDays\":14,\"customerServiceUrl\":\"https://gryphline.helpshift.com/hc/{language}/4-arknights-endfield\",\"enableUnbindGrant\":false},\"customerServiceUrl\":\"https://gryphline.helpshift.com/hc/{language}/4-arknights-endfield\",\"thirdPartyRedirectUrl\":\"https://web-api.gryphline.com/callback/thirdPartyAuth.html\",\"scanUrl\":{\"login\":\"yj://scan_login\"},\"loginChannels\":[],\"userCenterUrl\":\"https://user.gryphline.com/pcSdk/userInfo?language={language}\"},\"msg\":\"OK\",\"status\":0,\"type\":\"A\"}"; + string resp = "{\"data\":{\"agreementUrl\":{\"register\":\"https://user.gryphline.com/{language}/protocol/plain/terms_of_service\",\"privacy\":\"https://user.gryphline.com/{language}/protocol/plain/privacy_policy\",\"unbind\":\"https://user.gryphline.com/{language}/protocol/plain/endfield/privacy_policy\",\"account\":\"https://user.gryphline.com/{language}/protocol/plain/terms_of_service\",\"game\":\"https://user.gryphline.com/{language}/protocol/plain/endfield/privacy_policy\"},\"app\":{\"googleAndroidClientId\":\"\",\"googleIosClientId\":\"\",\"enableAutoLogin\":true,\"enablePayment\":true,\"enableGuestRegister\":true,\"needShowName\":true,\"displayName\":{\"en-us\":\"Arknights: Endfield\",\"ja-jp\":\"アークナイツ:エンドフィールド\",\"ko-kr\":\"명일방주:엔드필드\",\"zh-cn\":\"明日方舟:终末地\",\"zh-tw\":\"明日方舟:終末地\"},\"unbindAgreement\":[],\"unbindLimitedDays\":30,\"unbindCoolDownDays\":14,\"customerServiceUrl\":\"https://gryphline.helpshift.com/hc/{language}/4-arknights-endfield\",\"enableUnbindGrant\":false},\"customerServiceUrl\":\"https://gryphline.helpshift.com/hc/{language}/4-arknights-endfield\",\"thirdPartyRedirectUrl\":\"https://web-api.gryphline.com/callback/thirdPartyAuth.html\",\"scanUrl\":{\"login\":\"yj://scan_login\"},\"loginChannels\":[],\"userCenterUrl\":\"https://user.gryphline.com/pcSdk/userInfo?language={language}\"},\"msg\":\"OK\",\"status\":0,\"type\":\"A\"}"; if(appCode == "a65356244d22261b") { diff --git a/Campofinale/Packets/Cs/HandleCsAdventureTakeRewardAll.cs b/Campofinale/Packets/Cs/HandleCsAdventureTakeRewardAll.cs new file mode 100644 index 0000000..f7fabac --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsAdventureTakeRewardAll.cs @@ -0,0 +1,19 @@ +using Campofinale.Network; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsAdventureTakeRewardAll + { + + [Server.Handler(CsMsgId.CsAdventureTakeRewardAll)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsAdventureTakeRewardAll req = packet.DecodeBody(); + //TODO + + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsBattleOp.cs b/Campofinale/Packets/Cs/HandleCsBattleOp.cs index 8446e08..d68c292 100644 --- a/Campofinale/Packets/Cs/HandleCsBattleOp.cs +++ b/Campofinale/Packets/Cs/HandleCsBattleOp.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Game.Entities; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsCharLevelUp.cs b/Campofinale/Packets/Cs/HandleCsCharLevelUp.cs index a4d0714..4010de0 100644 --- a/Campofinale/Packets/Cs/HandleCsCharLevelUp.cs +++ b/Campofinale/Packets/Cs/HandleCsCharLevelUp.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs index bf2b64b..6ca8531 100644 --- a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs +++ b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs b/Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs index 0d2ea8a..6754d21 100644 --- a/Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs +++ b/Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsEquipPutoff.cs b/Campofinale/Packets/Cs/HandleCsEquipPutoff.cs index 3cbc030..037a180 100644 --- a/Campofinale/Packets/Cs/HandleCsEquipPutoff.cs +++ b/Campofinale/Packets/Cs/HandleCsEquipPutoff.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsEquipPuton.cs b/Campofinale/Packets/Cs/HandleCsEquipPuton.cs index 0c719b4..4d6c007 100644 --- a/Campofinale/Packets/Cs/HandleCsEquipPuton.cs +++ b/Campofinale/Packets/Cs/HandleCsEquipPuton.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index c79efbd..412ee09 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -1,7 +1,7 @@ using BeyondTools.VFS.Crypto; using Campofinale.Database; using Campofinale.Game; -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Packets.Sc; using Campofinale.Protocol; @@ -211,8 +211,10 @@ namespace Campofinale.Packets.Cs session.EnterScene(); session.Initialized = true; session.Update(); - - + session.adventureBookManager.data.dailyLogin++; + session.adventureBookManager.TaskUpdate(ConditionType.CheckStatisticVal, null); + + } static byte[] GenerateRandomBytes(int length) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 76ff9e7..851433f 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Game.Entities; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Cs/HandleCsTakeAdventureTaskReward.cs b/Campofinale/Packets/Cs/HandleCsTakeAdventureTaskReward.cs new file mode 100644 index 0000000..a27dfe9 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsTakeAdventureTaskReward.cs @@ -0,0 +1,19 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsTakeAdventureTaskReward + { + + [Server.Handler(CsMsgId.CsTakeAdventureTaskReward)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsTakeAdventureTaskReward req = packet.DecodeBody(); + session.adventureBookManager.ClaimTask(req.TaskId); + session.Send(new PacketScAdventureBookSync(session), packet.csHead.UpSeqid); + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsTakeAllAdventureTaskReward.cs b/Campofinale/Packets/Cs/HandleCsTakeAllAdventureTaskReward.cs new file mode 100644 index 0000000..c404d6a --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsTakeAllAdventureTaskReward.cs @@ -0,0 +1,20 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsTakeAllAdventureTaskReward + { + + [Server.Handler(CsMsgId.CsTakeAllAdventureTaskReward)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsTakeAllAdventureTaskReward req = packet.DecodeBody(); + session.adventureBookManager.ClaimTasks((AdventureTaskType)req.TaskType); + session.Send(new PacketScAdventureBookSync(session), packet.csHead.UpSeqid); + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsWeaponPuton.cs b/Campofinale/Packets/Cs/HandleCsWeaponPuton.cs index 6e2c56a..3f041ca 100644 --- a/Campofinale/Packets/Cs/HandleCsWeaponPuton.cs +++ b/Campofinale/Packets/Cs/HandleCsWeaponPuton.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs b/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs index bf2a0b9..874120f 100644 --- a/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs +++ b/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs @@ -1,6 +1,7 @@ using Campofinale.Network; using Campofinale.Protocol; using Campofinale.Resource; +using static Campofinale.Game.Adventure.AdventureBookManager; namespace Campofinale.Packets.Sc { @@ -8,19 +9,13 @@ namespace Campofinale.Packets.Sc { public PacketScAdventureBookSync(Player player) { ScAdventureBookSync proto = new ScAdventureBookSync() { - AdventureBookStage=1, - DailyActivation=100, + AdventureBookStage=player.adventureBookManager.data.adventureBookStage, + DailyActivation=player.adventureBookManager.data.dailyActivation, + }; - foreach(var i in ResourceManager.adventureTaskTable) + foreach (GameAdventureTask task in player.adventureBookManager.data.tasks) { - if (i.Value.adventureBookStage == 1) - { - proto.Tasks.Add(new AdventureTask() - { - TaskId = i.Value.adventureTaskId, - State = 1 - }); - } + proto.Tasks.Add(task.ToProto()); } SetData(ScMsgId.ScAdventureBookSync, proto); } diff --git a/Campofinale/Packets/Sc/PacketScCharBagAddChar.cs b/Campofinale/Packets/Sc/PacketScCharBagAddChar.cs index 7c6617d..c41b53e 100644 --- a/Campofinale/Packets/Sc/PacketScCharBagAddChar.cs +++ b/Campofinale/Packets/Sc/PacketScCharBagAddChar.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Sc/PacketScCharBagDelChar.cs b/Campofinale/Packets/Sc/PacketScCharBagDelChar.cs index 9ba09d7..4ca11ce 100644 --- a/Campofinale/Packets/Sc/PacketScCharBagDelChar.cs +++ b/Campofinale/Packets/Sc/PacketScCharBagDelChar.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Packets/Sc/PacketScCharUnlockTalentNode.cs b/Campofinale/Packets/Sc/PacketScCharUnlockTalentNode.cs index 0a65011..c23e6ba 100644 --- a/Campofinale/Packets/Sc/PacketScCharUnlockTalentNode.cs +++ b/Campofinale/Packets/Sc/PacketScCharUnlockTalentNode.cs @@ -1,4 +1,4 @@ -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Network; using Campofinale.Protocol; diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 4659602..a1e90f1 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -3,7 +3,7 @@ using Campofinale.Protocol; using Google.Protobuf; using System.Net.Sockets; using Campofinale.Packets.Sc; -using Campofinale.Game.Character; +using Campofinale.Game.Char; using Campofinale.Resource; using Campofinale.Game.Inventory; using static Campofinale.Resource.ResourceManager; @@ -16,6 +16,7 @@ using Campofinale.Game.Factory; using Campofinale.Game.MissionSys; using Pastel; using System.Drawing; +using Campofinale.Game.Adventure; namespace Campofinale @@ -98,6 +99,7 @@ namespace Campofinale public BitsetManager bitsetManager; public FactoryManager factoryManager; public MissionSystem missionSystem; + public AdventureBookManager adventureBookManager; public int teamIndex = 0; public List teams = new List(); public List mails = new List(); @@ -106,6 +108,7 @@ namespace Campofinale public long maxDashEnergy = 250; public uint curStamina = 10; public long nextRecoverTime = 0; + public long nextDailyReset = 0; public Dungeon currentDungeon; public PlayerSafeZoneInfo savedSaveZone; @@ -128,6 +131,7 @@ namespace Campofinale spaceshipManager = new(this); factoryManager = new(this); missionSystem = new(this); + adventureBookManager = new(this); receivorThread = new Thread(new ThreadStart(Receive)); } @@ -168,6 +172,7 @@ namespace Campofinale { sceneManager.scenes = data.scenes; } + nextDailyReset = data.nextDailyReset; bitsetManager.Load(data.bitsets); savedSaveZone = data.savedSafeZone; if(Server.config.serverOptions.missionsEnabled) missionSystem.Load(); @@ -176,7 +181,7 @@ namespace Campofinale { Initialize(); //only if no account found } - + adventureBookManager.Load(); sceneManager.Load(); factoryManager.Load(); return (data != null); @@ -572,6 +577,7 @@ namespace Campofinale DatabaseManager.db.SavePlayerData(this); inventoryManager.Save(); spaceshipManager.Save(); + adventureBookManager.Save(); if(Server.config.serverOptions.missionsEnabled) missionSystem.Save(); SaveCharacters(); SaveMails(); @@ -579,6 +585,7 @@ namespace Campofinale } public void AddStamina(uint stamina) { + curStamina += stamina; if(curStamina > maxStamina) { @@ -595,6 +602,12 @@ namespace Campofinale nextRecoverTime= DateTime.UtcNow.AddMinutes(7).ToUnixTimestampMilliseconds(); AddStamina(1); } + if(curtimestamp >= nextDailyReset && adventureBookManager.data!=null) + { + nextDailyReset = DateTime.UtcNow.GetNextDailyReset().ToUnixTimestampMilliseconds(); + adventureBookManager.DailyReset(); + this.Send(new PacketScAdventureBookSync(this)); + } if(LoadFinish) sceneManager.Update(); factoryManager.Update(); diff --git a/Campofinale/Program.cs b/Campofinale/Program.cs index 8ae113c..1b4bf3d 100644 --- a/Campofinale/Program.cs +++ b/Campofinale/Program.cs @@ -21,7 +21,8 @@ class Program } private static void FakeClientTester() { - string serverIp = "beyond-ric.gryphline.com"; + // + string serverIp = "beyond-tyo.gryphline.com"; int serverPort = 30000; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); diff --git a/Campofinale/Resource/GameEnums.cs b/Campofinale/Resource/GameEnums.cs index e74b912..463e0b1 100644 --- a/Campofinale/Resource/GameEnums.cs +++ b/Campofinale/Resource/GameEnums.cs @@ -17,6 +17,185 @@ Completed = 3, Failed = 4, } + public enum AdventureTaskState + { + None = 0, + Processing = 1, + Completed = 2, + Rewarded = 3 + } + public enum ConditionType + { + Combined = 0, + NumberOfKills = 1, + TotalOfKills = 2, + MissionGroupComplete = 3, + MissionAvailable = 4, + MissionProcessing = 5, + MissionCompleted = 6, + MissionAction = 7, + ReachDestination = 8, + NumOfProduceItems = 9, + TotalOfProduceItems = 10, + GuideFinish = 11, + RepairBuilding = 12, + TotalOfOrder = 13, + BlocLevel = 14, + BlocExpFull = 15, + CanChangeGold = 16, + CharMaxLevel = 17, + QuestStateEqual = 18, + MissionStateEqual = 19, + CheckMissionSucceedId = 20, + ItemBagHasItem = 106, + PlayerHasItem = 107, + CastSkill = 108, + DepotHasItem = 109, + CheckGetEnoughItem = 110, + CheckGetEnoughItemInBag = 111, + CheckGetEnoughItemInDepot = 112, + FacBuildingConnected = 501, + FacBuildingUpgrade = 502, + FacBuildingAdded = 503, + FacBuildingWorking = 504, + FacRepairBuilding = 505, + FacProducePowerReach = 511, + FacProductivityReach = 512, + KillSpecificEnemy = 1000, + CheckBaseAndPoleConnected = 1001, + CheckBaseAndMinerRunning = 1002, + CheckTotalMinerRunning = 1003, + CheckInteract = 1004, + OnInteract = 1005, + CheckInteractiveBool = 1006, + CheckPlayerInMap = 1007, + CheckInteractiveInt = 1008, + SceneCollectionProgress = 2000, + CompareProperty = 4000, + PlusThenCompareTargetInteractiveProperty = 4001, + CheckTriggerSpecificInteractiveEvent = 4002, + CheckClientObjectiveCommon = 4003, + CompareTargetInteractiveProperty = 4004, + HasItemCount = 4501, + DungeonKeptTime = 4502, + CheckDoodadIsPickable = 5000, + CheckDoodadIsBreakable = 5001, + CheckInteractiveDestroyed = 5002, + CheckUnlockTech = 5003, + CheckRepairBuilding = 5004, + CheckStorageBoxHasEnoughItem = 5005, + CheckBuildingConnected = 5006, + CheckBuildingStateInArea = 5007, + CheckBuildingConnectedAsMA2SB = 5008, + CheckUnlockMultipleTech = 5009, + DoFacTradeCashAnyOrder = 5010, + CheckSceneAreaUnlocked = 5011, + CheckUnlockTechPackage = 5012, + CheckUnlockTechLayer = 5013, + FacBuildingCountInScene = 5014, + FacBuildingProducingCountInScene = 5015, + FacProducingFormulaCountInScene = 5016, + FacStatisticItemGenRate = 5017, + FacStatisticItemGen = 5018, + FacPowerCostSum = 5019, + FacBoxConveyorLengthSum = 5020, + FacStorageBoxHasItems = 5021, + CheckSpaceshipRoomLevel = 5022, + CheckAdventureLevel = 5023, + CheckShopNothingToBuy = 5024, + CheckLiquidInBag = 5025, + SettlementCheckExpEnoughToLevelup = 5026, + CheckBuildingConnectedSpecify = 5027, + CheckSpaceshipRoomUnlock = 5028, + CheckSpaceshipRoomBuilt = 5029, + CheckSpaceshipRoomStationCount = 5030, + CheckPassGameMechanicsId = 5031, + FacBuildingFluidContainerHasItem = 5032, + CheckFacSoilHarvest = 5033, + CheckFacBuildingState = 5034, + FacBattleBuildingCurEnergy = 5035, + CheckSpaceshipGrowCabinHarvest = 5036, + CheckGameInstCompletionStatus = 5037, + CheckItemGot = 5038, + CheckBuildingConnectedExist = 5039, + CheckFacSoilPlacedInPanel = 5040, + CheckWeaponGachaPoolIsOpen = 5041, + CheckShopGoodsIsSoldOut = 5042, + CheckPassedGameMechanicsNum = 5044, + CheckSettlementLevelSum = 5045, + CheckInteractiveLock = 5244, + CheckRichContentReadingDone = 5245, + CheckInteractiveSubmitSuccess = 5246, + CheckInteractiveNextAvailableTime = 5247, + CheckMonsterSpawnerComplete = 5248, + CheckItemBagCanPutIn = 5249, + CheckFluidVolume = 5250, + CheckGreaterWeapeonStageNum = 5251, + CheckRoleCreateTime = 5252, + CheckSceneGrade = 5253, + CheckUnlockGroupTechNum = 5254, + CheckCharSkillLevel = 5255, + CheckCharUnlockBreakTalentId = 5256, + CheckFactoryBlackBoxStateNum = 5257, + CheckDungeonTypePassNum = 5258, + CheckEquipTierLevelNumCharNum = 5259, + CheckInteractiveIsActivable = 5260, + CheckInteractiveIsActived = 5261, + CheckSceneScope = 5262, + CheckGameInstStartDuration = 5263, + CheckPlayerInDungeon = 5264, + CheckCharUnlock = 5265, + CheckCharFavorability = 5266, + CheckEtherSubmitCount = 5267, + CheckTDStart = 5600, + CheckTDSettlement = 5601, + CheckPanelOpen = 6000, + CheckQuestSubmitItem = 6001, + CheckLevelScriptProperty = 6002, + CheckRepeatableTalkFinish = 6003, + KillEnemyIdList = 6004, + CheckCompletedBlocMissionNum = 6005, + CheckSceneCollectionNum = 6006, + CheckPRTSCollectionUnlock = 6007, + CheckCostStamina = 6008, + CheckTmpShopAlreadyBuyCount = 6009, + CheckInPowerMinerCount = 6010, + CheckTimestamp = 6011, + CheckMissionProperty = 6012, + CheckProperty = 6015, + CheckClientGameVar = 6016, + CheckServerGameVar = 6017, + CheckPlayerHasEnoughItemList = 6018, + CheckMiniGameCompletedCount = 6019, + CheckMonsterKilledNum = 6020, + CheckTerminalReadingDone = 6021, + CheckScriptTaskStateEqual = 6022, + CheckFactoryBlackBoxState = 6023, + CheckTeamMemberNumberEven = 6024, + CheckDaysNumAfterMissionComplete = 6025, + CheckTimelineFinish = 6026, + CheckFmvFinish = 6027, + CheckRemoteCommFinish = 6028, + CheckTalkFinish = 6029, + CheckPrtsInvestigateFinish = 6030, + CheckSNSDialogComplete = 6500, + CheckSNSDialogContent = 6501, + CheckGreaterCharLevelNum = 6502, + CheckGreaterWeapeonLevelNum = 6503, + CheckGreaterCharStageNum = 6504, + CheckGreaterCharPotentialNum = 6505, + CheckGreaterSettlementLevelNum = 6506, + CheckStatisticVal = 6507, + ClientOnly = 9999, + SystemUnlocked = 10000, + None = 2147483647 + } + public enum AdventureTaskType + { + None = 0, + Daily = 1, + AdventureBook = 2 + } public enum LevelScriptState { None = 0, @@ -358,13 +537,6 @@ KeyStepFinish = 2, Completed = 3 } - public enum AdventureTaskState // TypeDefIndex: 33702 - { - None = 0, - Processing = 1, - Completed = 2, - Rewarded = 3 - } public enum EntryState // TypeDefIndex: 24402 { Empty = 0, @@ -373,12 +545,6 @@ LevelLoaded = 3, Invalid = 4 } - public enum AdventureTaskType // TypeDefIndex: 33687 - { - None = 0, - Daily = 1, - AdventureBook = 2 - } public enum ItemStorageSpace // TypeDefIndex: 33575 { None = 0, diff --git a/Campofinale/Resource/Json/ConditionData.cs b/Campofinale/Resource/Json/ConditionData.cs new file mode 100644 index 0000000..2664ca0 --- /dev/null +++ b/Campofinale/Resource/Json/ConditionData.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Resource.Json +{ + [TableCfgType("Data/Conditions.json", LoadPriority.LOW)] + public class ConditionData + { + public List args = new(); + + + public string Get(int index) + { + return args[index]; + } + public int ToInt(int index) + { + return int.Parse(args[index]); + } + } +} diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 448d3a5..fe94da8 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -79,6 +79,7 @@ namespace Campofinale.Resource public static List levelDatas = new(); public static List interactiveData = new(); public static List spawnerConfigs = new(); + public static Dictionary conditions=new(); public static int GetSceneNumIdFromLevelData(string name) { if (levelDatas.Find(a => a.id == name) == null) return 0; @@ -409,13 +410,13 @@ namespace Campofinale.Resource public int adventureBookStage; public string adventureTaskId; public string conditionId; - public int conditionType; + public ConditionType conditionType; public string jumpSystemId; public int progressToCompare; public string rewardId; public int sortId; public TaskDescription taskDesc; - public int taskType; + public AdventureTaskType taskType; } public class TaskDescription { diff --git a/Campofinale/Resource/ServerEnums.cs b/Campofinale/Resource/ServerEnums.cs new file mode 100644 index 0000000..43cf3de --- /dev/null +++ b/Campofinale/Resource/ServerEnums.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Resource +{ + public enum ServerEventExec + { + UpdateTasks=0 + } + +} diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index fc79073..94ea2f4 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -21,6 +21,17 @@ namespace Campofinale { return (long)(dateTime - UnixEpoch).TotalMilliseconds; } + public static DateTime GetNextDailyReset(this DateTime dateTime) + { + DateTime now = DateTime.UtcNow; + DateTime todayReset = new DateTime(now.Year, now.Month, now.Day, 6, 0, 0, DateTimeKind.Utc); + + // Se siamo già passati oltre le 6:00 AM di oggi, ritorna le 6:00 AM di domani + if (now >= todayReset) + return todayReset.AddDays(1); + else + return todayReset; + } } public class Server { From bb7c9831b40229272d922f97fbe1d0c477e22bf6 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 25 Jul 2025 17:41:39 +0200 Subject: [PATCH 19/27] GateBulletin hardcoded + bug fix --- Campofinale/Http/GateBulletin.cs | 145 ++++++++++++++++++ .../Packets/Sc/PacketScActivitySync.cs | 1 + .../Packets/Sc/PacketScAdventureBookSync.cs | 1 - Campofinale/Player.cs | 3 +- 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 Campofinale/Http/GateBulletin.cs diff --git a/Campofinale/Http/GateBulletin.cs b/Campofinale/Http/GateBulletin.cs new file mode 100644 index 0000000..5136f71 --- /dev/null +++ b/Campofinale/Http/GateBulletin.cs @@ -0,0 +1,145 @@ +using Campofinale.Database; +using HttpServerLite; +using MongoDB.Driver; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata; +using System.Security.Cryptography; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using static Campofinale.Http.GateBulletin.DetailRsp; +using static Campofinale.Http.GateBulletin.DetailRsp.DetailData; +using static System.Net.Mime.MediaTypeNames; + +namespace Campofinale.Http +{ + public class GateBulletin + { + //http://192.168.1.3:5000/bulletin/aggregate?lang=en-us&platform=Windows&server=EUAndUS&type=0&code=endfield_cbt2_overseas&hideDetail=1 + public class AggregateRsp + { + public int code = 0; + public string msg = ""; + + public Data data = new Data(); + public class Data + { + public string topicCid = "2113"; + public int type = 1; + public string platform = "Windows"; + public string server = "#DEFAULT"; + public string channel = "#DEFAULT"; + public string lang = "en"; + public string key = "1:Windows:#DEFAULT:#DEFAULT:en"; + public string version = "d41d8cd98f00b204e9800998ecf8427e"; + public List onlineList = new(); + public List popupList = new(); + public int popupVersion; + public int updatedAt = 0; + public List list = new(); + + public class BulletinEntry + { + public string cid; + public string type; + + public string tab; + public string title; + public int startAt; + public string? tag; + public int? sort; + } + } + } + [StaticRoute(HttpServerLite.HttpMethod.GET, "/bulletin/aggregate")] + public static async Task bulletin_aggregate(HttpContext ctx) + { + string resp = "{}"; + AggregateRsp rsp = new(); + rsp.data.list.Add(new AggregateRsp.Data.BulletinEntry() + { + cid = "1", + title = "Endfield Private Server", + type = "news", + tab = "news", + sort = 0, + tag = "campaign", + startAt = 0, + }); + rsp.data.list.Add(new AggregateRsp.Data.BulletinEntry() + { + cid = "2", + title = "Informations", + type = "news", + tab = "news", + sort = 1, + tag = "campaign", + startAt = 0, + }); + resp = JsonConvert.SerializeObject(rsp); + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } + public class DetailRsp + { + public int code = 0; + public string msg = ""; + public DetailData data=new(); + + + public class DetailData + { + public string title = "Test"; + public string header = "Test"; + public TextData data = new(); + public string content = "null"; + public string displayType = "rich_text"; + + public class TextData + { + public string html; + public string text; + } + } + } + [StaticRoute(HttpServerLite.HttpMethod.GET, "/bulletin/detail/2")] + public static async Task bulletin_1(HttpContext ctx) + { + string resp = "{}"; + DetailRsp rsp = new(); + rsp.data.title = "Informations"; + rsp.data.header = "Informations"; + rsp.data.data = new TextData() + { + html= "Repository https://git.muiegratis.online/suikoakari/Campofinale", + }; + resp = JsonConvert.SerializeObject(rsp); + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } + [StaticRoute(HttpServerLite.HttpMethod.GET, "/bulletin/detail/1")] + public static async Task bulletin_2(HttpContext ctx) + { + string resp = "{}"; + DetailRsp rsp = new(); + rsp.data.title = "Endfield Private Server"; + rsp.data.header = "Endfield Private Server"; + rsp.data.data = new TextData() + { + html = "Welcome to Campofinale! A private server for Arknights: Endfield!", + }; + resp = JsonConvert.SerializeObject(rsp); + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } + } +} diff --git a/Campofinale/Packets/Sc/PacketScActivitySync.cs b/Campofinale/Packets/Sc/PacketScActivitySync.cs index 5bf730a..038e6ec 100644 --- a/Campofinale/Packets/Sc/PacketScActivitySync.cs +++ b/Campofinale/Packets/Sc/PacketScActivitySync.cs @@ -26,6 +26,7 @@ namespace Campofinale.Packets.Sc { LoginDays=1, RewardDays=16, + } } } diff --git a/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs b/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs index 874120f..5c1ca8d 100644 --- a/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs +++ b/Campofinale/Packets/Sc/PacketScAdventureBookSync.cs @@ -11,7 +11,6 @@ namespace Campofinale.Packets.Sc ScAdventureBookSync proto = new ScAdventureBookSync() { AdventureBookStage=player.adventureBookManager.data.adventureBookStage, DailyActivation=player.adventureBookManager.data.dailyActivation, - }; foreach (GameAdventureTask task in player.adventureBookManager.data.tasks) { diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index a1e90f1..1511124 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -606,7 +606,8 @@ namespace Campofinale { nextDailyReset = DateTime.UtcNow.GetNextDailyReset().ToUnixTimestampMilliseconds(); adventureBookManager.DailyReset(); - this.Send(new PacketScAdventureBookSync(this)); + if (Initialized) + this.Send(new PacketScAdventureBookSync(this)); } if(LoadFinish) sceneManager.Update(); From 775baf5c3b663b1bd017f4f77ae76cf924d84bd5 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sat, 26 Jul 2025 23:13:48 +0200 Subject: [PATCH 20/27] Player.SeamlessEnterScene (not working...) --- .../Packets/Cs/HandleCsSceneLoadFinish.cs | 5 +- .../Cs/HandleCsSceneSetLastSafeZone.cs | 7 ++- .../Packets/Sc/PacketScSelfSceneInfo.cs | 5 +- Campofinale/Player.cs | 49 +++++++++++++++++-- Campofinale/Server.cs | 2 +- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs index c392d95..2b3da13 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs @@ -13,11 +13,10 @@ namespace Campofinale.Packets.Cs { CsSceneLoadFinish req = packet.DecodeBody(); - + session.curSceneNumId=req.SceneNumId; session.Send(new PacketScSelfSceneInfo(session, SelfInfoReasonType.SlrEnterScene)); session.sceneManager.LoadCurrentTeamEntities(); session.sceneManager.LoadCurrent(); - session.LoadFinish = true; if (session.curSceneNumId == 98) { @@ -37,7 +36,7 @@ namespace Campofinale.Packets.Cs } } - session.LoadFinish = true; + session.sceneLoadState = Player.SceneLoadState.OK; } } } diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs index 30c39d0..e6844db 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs @@ -10,7 +10,12 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLastSafeZone req = packet.DecodeBody(); - + Logger.Print($"Current Scene: {req.SceneNumId}"); + //Change seamlessy scene + if (req.SceneNumId != session.curSceneNumId) + { + session.SeamlessEnterScene(req.SceneNumId); + } } } diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index a07c902..fbb5069 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -59,7 +59,10 @@ namespace Campofinale.Packets.Sc sceneInfo.Detail.CharList.Add(session.chars.Find(c => c.guid == m).ToSceneProto()); }); - //Levelscripts here? + if (infoReason == SelfInfoReasonType.SlrSeamlesslyEnterScene) + { + sceneInfo.TeamInfo = null; + } if(infoReason!= SelfInfoReasonType.SlrChangeTeam) ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.ForEach(l => { diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 1511124..f8fb8a6 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -17,6 +17,7 @@ using Campofinale.Game.MissionSys; using Pastel; using System.Drawing; using Campofinale.Game.Adventure; +using static Campofinale.Player; namespace Campofinale @@ -349,7 +350,7 @@ namespace Campofinale { //sceneManager.UnloadCurrent(false); //sceneManager.LoadCurrent(); - LoadFinish = false; + sceneLoadState = SceneLoadState.Loading; Send(new PacketScEnterSceneNotify(this, curSceneNumId)); } if (savedSaveZone == null || savedSaveZone.sceneNumId == 0) @@ -362,7 +363,14 @@ namespace Campofinale }; } } - public bool LoadFinish = true; + public enum SceneLoadState + { + OK=0, + Loading=1, + + } + public SceneLoadState sceneLoadState=0; + // public bool LoadFinish = true; public void EnterScene(int sceneNumId, Vector3f pos, Vector3f rot, PassThroughData passThroughData = null) { // if (!LoadFinish) return; @@ -381,7 +389,7 @@ namespace Campofinale curSceneNumId = sceneNumId; position = pos; rotation = rot; - LoadFinish = false; + sceneLoadState = SceneLoadState.Loading; Send(new PacketScEnterSceneNotify(this, sceneNumId, pos, passThroughData)); //sceneManager.LoadCurrent(); } @@ -390,6 +398,37 @@ namespace Campofinale Logger.PrintError($"Scene {sceneNumId} not found"); } } + /// + /// Seamless Crossing scene is not working, self scene info is not modifying the current scene num id in the client... + /// + /// + public void SeamlessEnterScene(int sceneNumId) + { + if(curSceneNumId != sceneNumId && sceneLoadState == SceneLoadState.OK) + { + sceneLoadState=SceneLoadState.Loading; + curSceneNumId = sceneNumId; + Send(new PacketScSelfSceneInfo(this, SelfInfoReasonType.SlrSeamlesslyEnterScene)); + ScFactoryModifyChapterScene modify = new() + { + ChapterId=GetCurrentChapter(), + SceneId=sceneNumId, + Tms=DateTime.UtcNow.ToUnixTimestampMilliseconds() + }; + Send(ScMsgId.ScFactoryModifyChapterScene, modify); + ScSceneCrossSceneStatus cross = new() + { + ObjId = teams[teamIndex].leader, + SceneNumId = curSceneNumId + }; + Send(ScMsgId.ScSceneCrossSceneStatus, cross); + + + sceneManager.LoadCurrentTeamEntities(); + sceneManager.LoadCurrent(); + sceneLoadState = SceneLoadState.OK; + } + } public void EnterScene(int sceneNumId) { if(GetLevelData(sceneNumId) != null) @@ -410,7 +449,7 @@ namespace Campofinale position = GetLevelData(sceneNumId).playerInitPos; rotation = GetLevelData(sceneNumId).playerInitRot; // sceneManager.LoadCurrent(); - LoadFinish = false; + sceneLoadState = SceneLoadState.Loading; Send(new PacketScEnterSceneNotify(this, sceneNumId)); } @@ -609,7 +648,7 @@ namespace Campofinale if (Initialized) this.Send(new PacketScAdventureBookSync(this)); } - if(LoadFinish) + if(sceneLoadState==0) sceneManager.Update(); factoryManager.Update(); } diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 94ea2f4..2daf8a4 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -67,7 +67,7 @@ namespace Campofinale public static Dispatch? dispatch; public static ConfigFile? config; public static List csMessageToHide = new() { CsMsgId.CsMoveObjectMove, CsMsgId.CsBattleOp,CsMsgId.CsPing }; - public static List scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing }; + public static List scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing,ScMsgId.ScObjectEnterView }; public void Start(ConfigFile config) { { From fb63df9eb23da227af0a0f07ce75a6c8f8c4c0b2 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sun, 27 Jul 2025 00:56:56 +0200 Subject: [PATCH 21/27] de-hardcoding ultimateSp in CsBattleOp --- Campofinale/Packets/Cs/HandleCsBattleOp.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Campofinale/Packets/Cs/HandleCsBattleOp.cs b/Campofinale/Packets/Cs/HandleCsBattleOp.cs index d68c292..14b9e3d 100644 --- a/Campofinale/Packets/Cs/HandleCsBattleOp.cs +++ b/Campofinale/Packets/Cs/HandleCsBattleOp.cs @@ -19,6 +19,7 @@ namespace Campofinale.Packets.Cs { case BattleActionOperateType.BattleOpEntityValueModify: + OnEntityValueModify(session, data); break; case BattleActionOperateType.BattleOpSkillStartCast: @@ -34,7 +35,7 @@ namespace Campofinale.Packets.Cs OnEntityDie(session, data.EntityDieOpData); break; default: - Logger.PrintWarn($"Unsupported BattleActionOperateType.{data.OpType}"); + Logger.PrintWarn($"Unimplemented BattleActionOperateType.{data.OpType}"); break; } } @@ -73,9 +74,8 @@ namespace Campofinale.Packets.Cs HealEntity(session, item); } break; - default: - Logger.PrintWarn($"Unsupported ServerBattleActionType.{data.Action.ActionType}"); + Logger.PrintWarn($"Unimplemented ServerBattleActionType.{data.Action.ActionType}"); break; } } @@ -106,7 +106,6 @@ namespace Campofinale.Packets.Cs private static void OnSkillStartCast(Player session, BattleClientOpData data) { ulong casterId = data.OwnerId; - Character character = session.chars.Find(c => c.guid == casterId); if (character != null) { @@ -140,7 +139,7 @@ namespace Campofinale.Packets.Cs BattleInfo = new() { Hp = character.curHp, - Ultimatesp = character.ultimateSp+1 + Ultimatesp = character.ultimateSp }, Objid = character.guid, }; @@ -154,17 +153,17 @@ namespace Campofinale.Packets.Cs private static void OnEntityValueModify(Player session, BattleClientOpData data) { - Logger.PrintWarn("EntityValueModify called: " + data.EntityValueModifyData.ToString()); - Character character = session.chars.Find(c => c.guid == data.EntityValueModifyData.EntityInstId); if (character != null) { + character.curHp = data.EntityValueModifyData.Value.Hp; + character.ultimateSp = data.EntityValueModifyData.Value.Ultimatesp; ScCharSyncStatus s = new() { BattleInfo = new() { - Hp = data.EntityValueModifyData.Value.Hp, + Hp = character.curHp, Ultimatesp = character.ultimateSp }, Objid = character.guid, From 0f2a3dade4cf87c6d2a9ace5966dc41fc25f56bd Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sun, 27 Jul 2025 15:58:32 +0200 Subject: [PATCH 22/27] bug fix --- Campofinale/Game/Entities/Entity.cs | 1 + Campofinale/Game/SceneManager.cs | 14 ++++++++++---- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Campofinale/Game/Entities/Entity.cs b/Campofinale/Game/Entities/Entity.cs index df9363a..13891d8 100644 --- a/Campofinale/Game/Entities/Entity.cs +++ b/Campofinale/Game/Entities/Entity.cs @@ -23,6 +23,7 @@ namespace Campofinale.Game.Entities public int sceneNumId; public bool spawned = false; public bool defaultHide = false; + public bool scriptSpawn = false; public Entity() { diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 3602800..a57a885 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -412,7 +412,7 @@ namespace Campofinale.Game if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { - if(currentAreaRange.IsObjectInside(e.Position)) + if(currentAreaRange.IsObjectInside(e.Position) || sceneNumId==87) if (!e.defaultHide) { toSpawn.Add(e); @@ -435,7 +435,7 @@ namespace Campofinale.Game List toDespawn=new(); foreach(Entity en in GetEntityExcludingChar().FindAll(e=> e.spawned==true)) { - if (!currentAreaRange.IsObjectInside(en.Position)) + if (!currentAreaRange.IsObjectInside(en.Position) && en.scriptSpawn==false && sceneNumId != 87) { toDespawn.Add(en.guid); en.spawned = false; @@ -458,7 +458,7 @@ namespace Campofinale.Game }); GetOwner().Send(new PacketScObjectEnterView(GetOwner(), GetEntityExcludingChar().FindAll(e => e.belongLevelScriptId == id))); } - public void SpawnEnemy(ulong v) + public void SpawnEnemy(ulong v, bool scriptSpawn=false) { LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); LevelEnemyData en = lv_scene.levelData.enemies.Find(e=>e.levelLogicId == v); @@ -468,11 +468,17 @@ namespace Campofinale.Game { type = en.entityType, belongLevelScriptId = en.belongLevelScriptId, - levelLogicId = en.levelLogicId + levelLogicId = en.levelLogicId, + scriptSpawn = scriptSpawn }; entities.Add(entity); + Logger.Print($"Enemy Id {v} found on scene {sceneNumId}:{lv_scene.mapIdStr}"); SpawnEntity(entity); } + else + { + Logger.PrintWarn($"Enemy Id {v} not found on scene {sceneNumId}:{lv_scene.mapIdStr}"); + } } public void SpawnWaveEnemy(ulong spawnerId, int waveId) diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 851433f..48c6d02 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -122,7 +122,7 @@ namespace Campofinale.Packets.Cs case ScriptActionType.SpawnEnemy: foreach (ulong id in action.valueUlong) { - player.sceneManager.GetCurScene().SpawnEnemy(id); + player.sceneManager.GetCurScene().SpawnEnemy(id,true); } break; From 3d99dc303b316defa2e54ff83a1583fc8e20414b Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Wed, 30 Jul 2025 19:40:11 +0200 Subject: [PATCH 23/27] some changes --- Campofinale/Http/Dispatch.cs | 39 ++++++++++- Campofinale/Http/SDK.cs | 129 +++++++++++++++++++++++++++++++---- Campofinale/Program.cs | 6 +- 3 files changed, 157 insertions(+), 17 deletions(-) diff --git a/Campofinale/Http/Dispatch.cs b/Campofinale/Http/Dispatch.cs index 17a271f..8616f60 100644 --- a/Campofinale/Http/Dispatch.cs +++ b/Campofinale/Http/Dispatch.cs @@ -1,5 +1,6 @@ using Campofinale.Game; using HttpServerLite; +using Newtonsoft.Json; namespace Campofinale.Http { @@ -63,11 +64,46 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } + public class U8ProductInfo + { + public string app_id; + public string channel_id; + public int world_id; + public int store_id; + public string product_id; + public string desc; + public string name; + public int type; + public long price; + public string extra_data; + public string appstore_id; + public string channel_product_id; + } + public class U8ProductListData + { + public List productList = new(); + } [StaticRoute(HttpServerLite.HttpMethod.POST, "/u8/pay/getAllProductList")] public static async Task getAllProductList(HttpContext ctx) { string resp = "{\"productList\":[]}"; - + U8ProductListData rsp = new(); + rsp.productList.Add(new U8ProductInfo() + { + appstore_id="0", + app_id="1", + channel_id="1", + channel_product_id="1", + desc="Test", + name="Test", + price=10, + type=0, + product_id="1", + store_id=1, + world_id=0, + + }); + resp = JsonConvert.SerializeObject(rsp); ctx.Response.StatusCode = 200; ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; @@ -164,7 +200,6 @@ namespace Campofinale.Http } ctx.Response.StatusCode = 200; - //ctx.Response.ContentLength = resp.Length; ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); diff --git a/Campofinale/Http/SDK.cs b/Campofinale/Http/SDK.cs index c097c30..4c5690e 100644 --- a/Campofinale/Http/SDK.cs +++ b/Campofinale/Http/SDK.cs @@ -1,5 +1,9 @@ using Campofinale.Database; using HttpServerLite; +using Newtonsoft.Json; +using System.Diagnostics; +using System.Text; +using System.Text.Json; using static Campofinale.Game.Gacha.GachaManager; using static Campofinale.Http.Dispatch; @@ -20,7 +24,18 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } + [StaticRoute(HttpServerLite.HttpMethod.GET, "/user/pay/v1/query_app_order")] + public static async Task query_app_order(HttpContext ctx) + { + string requestBody = ctx.Request.DataAsString; + Console.WriteLine(requestBody); + string resp = "{\"data\":{\"paidApp\":true,\"hasMinorOrder\":false},\"msg\":\"OK\",\"status\":0,\"type\":\"A\"}"; + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/json"; + await ctx.Response.SendAsync(resp); + + } [StaticRoute(HttpServerLite.HttpMethod.POST, "/user/auth/v1/token_by_phone_password")] public static async Task token_login_phone_cn(HttpContext ctx) { @@ -100,21 +115,69 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } - public struct GrantData + public class GrantReqData { public string token; + public string encodeNonce; + public string appCode; } - [StaticRoute(HttpServerLite.HttpMethod.POST, "/user/oauth2/v2/grant")] - public static async Task account_ugrant(HttpContext ctx) + public class GrantRsp + { + public Data data; + public string msg; + public int status; + public string type; + + public class Data + { + public string token; + public string code; + public string hgId; + public string uid; + public string encodeSign; + } + } + + + /*[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/oauth2/v2/grant")] + public static async Task account_ugrant_old(HttpContext ctx) { string requestBody = ctx.Request.DataAsString; - GrantData grant = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); + GrantReqData grant = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); Account account = DatabaseManager.db.GetAccountByToken(grant.token); string resp = "{\"msg\": \"Error\", \"status\": 2, \"type\": \"A\"}"; if (account != null) { resp = "{\"data\": { \"uid\": \"" + account.id + "\", \"code\": \"" + DatabaseManager.db.GrantCode(account) + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}"; + if(grant.appCode== "2289f1dd2b923c53") + { + var url = "https://as.hypergryph.com/user/oauth2/v2/grant"; + + var b = new + { + appCode = "2289f1dd2b923c53", + encodeNonce = grant.encodeNonce, + token = "/kKCPAzTCkGOKft+X7sE7T0W", + type = 1 + }; + + var json = JsonSerializer.Serialize(b); + + var handler = new HttpClientHandler + { + UseProxy = false, + }; + + using var client = new HttpClient(handler); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = await client.PostAsync(url, content); + var responseString = await response.Content.ReadAsStringAsync(); + Logger.Print(responseString); + GrantRspOff rsp = JsonSerializer.Deserialize(responseString); + resp = "{ \"data\": { \"token\": \"" + DatabaseManager.db.GrantCode(account) + "\", \"hgId\": \"" + account.id + "\", \"encodeSign\": \""+ rsp.data.encodeSign + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}"; + } } ctx.Response.StatusCode = 200; @@ -122,26 +185,70 @@ namespace Campofinale.Http ctx.Response.ContentType = "application/json"; await ctx.Response.SendAsync(resp); + }*/ + [StaticRoute(HttpServerLite.HttpMethod.POST, "/user/oauth2/v2/grant")] + public static async Task account_ugrant(HttpContext ctx) + { + string requestBody = ctx.Request.DataAsString; + + GrantReqData grant = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); + GrantRsp rsp = new GrantRsp(); + Account account = DatabaseManager.db.GetAccountByToken(grant.token); + rsp.type = "A"; + if (account != null) + { + rsp.msg = "OK"; + string grantedToken = DatabaseManager.db.GrantCode(account); + rsp.data = new() + { + hgId = account.id, + uid = account.id, + token = grantedToken, + code = grantedToken + }; + } + else + { + rsp.status = 2; + rsp.msg = "Error"; + + } + + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/json"; + await ctx.Response.SendAsync(JsonConvert.SerializeObject(rsp)); } [StaticRoute(HttpServerLite.HttpMethod.POST, "/u8/user/auth/v2/grant")] public static async Task account_grant(HttpContext ctx) { string requestBody = ctx.Request.DataAsString; - GrantData grant = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); + GrantReqData grant = Newtonsoft.Json.JsonConvert.DeserializeObject(requestBody); + GrantRsp rsp = new GrantRsp(); Account account = DatabaseManager.db.GetAccountByTokenGrant(grant.token); - string resp = "{\"msg\": \"Error\", \"status\": 2, \"type\": \"A\"}"; + rsp.type = "A"; if (account != null) { - - resp = "{\"data\": { \"token\": \"" + account.token + "\", \"uid\": \"" + account.id + "\", \"code\": \"" + account.grantToken + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}"; + rsp.msg = "OK"; + rsp.data = new() + { + hgId = account.id, + uid = account.id, + token = account.token, + code = account.grantToken, + }; + } + else + { + rsp.status = 2; + rsp.msg = "Error"; } ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/json"; - await ctx.Response.SendAsync(resp); + await ctx.Response.SendAsync(JsonConvert.SerializeObject(rsp)); } public class TokenChannelData @@ -233,10 +340,8 @@ namespace Campofinale.Http { transactions.transactionList = new(); } - string resp = Newtonsoft.Json.JsonConvert.SerializeObject(transactions); - ctx.Response.StatusCode = 200; - await ctx.Response.SendAsync(resp); + await ctx.Response.SendAsync(JsonConvert.SerializeObject(transactions)); } [StaticRoute(HttpServerLite.HttpMethod.GET, "/gachahistory")] public static async Task gachahistory(HttpContext ctx) diff --git a/Campofinale/Program.cs b/Campofinale/Program.cs index 1b4bf3d..78e50ad 100644 --- a/Campofinale/Program.cs +++ b/Campofinale/Program.cs @@ -12,7 +12,7 @@ class Program { static void Main(string[] args) { - StartServer(args); + StartServer(args); //FakeClientTester(); } public static byte[] ConcatenateByteArrays(byte[] array1, byte[] array2) @@ -22,7 +22,7 @@ class Program private static void FakeClientTester() { // - string serverIp = "beyond-tyo.gryphline.com"; + string serverIp = "beyond-cn.hypergryph.com"; int serverPort = 30000; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); @@ -33,7 +33,6 @@ class Program socket.Connect(new IPEndPoint(ipAddress, serverPort)); socket.Send(Packet.EncodePacket((int)CsMsgId.CsLogin,new CsLogin() { ClientVersion="0.5.5",Uid= "", Token= "", Env=EnvType.Prod,PlatformId=ClientPlatformType.Windows,Area=AreaType.Oversea,ClientResVersion="", LoginToken= "" }.ToByteArray())); - while (true) { byte[] buffer = new byte[3]; @@ -44,6 +43,7 @@ class Program byte headLength = Packet.GetByte(buffer, 0); ushort bodyLength = Packet.GetUInt16(buffer, 1); byte[] moreData = new byte[bodyLength + headLength]; + while (socket.Available < moreData.Length) { From 3df44653ae5e00c09c0afb8c17ac1b01945c44a8 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 1 Aug 2025 22:03:24 +0200 Subject: [PATCH 24/27] some changes --- Campofinale/Game/Dungeons/Dungeon.cs | 33 ++++- Campofinale/Game/Entities/Entity.cs | 1 - Campofinale/Game/SceneManager.cs | 45 ++----- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 120 ++++++++---------- Campofinale/Player.cs | 23 +--- Campofinale/Resource/ResourceManager.cs | 1 + 6 files changed, 102 insertions(+), 121 deletions(-) diff --git a/Campofinale/Game/Dungeons/Dungeon.cs b/Campofinale/Game/Dungeons/Dungeon.cs index c22e73d..a16b756 100644 --- a/Campofinale/Game/Dungeons/Dungeon.cs +++ b/Campofinale/Game/Dungeons/Dungeon.cs @@ -1,4 +1,6 @@ -using static Campofinale.Resource.ResourceManager; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Dungeons { @@ -13,5 +15,34 @@ namespace Campofinale.Game.Dungeons { } + + public void Enter() + { + player.sceneManager.GetScene(GetSceneNumIdFromLevelData(table.sceneId)).activeScripts.Clear(); + player.sceneManager.GetScene(GetSceneNumIdFromLevelData(table.sceneId)).scripts.ForEach(script => + { + script.state = 1; + }); + ScEnterDungeon enter = new() + { + DungeonId = table.dungeonId, + SceneId = table.sceneId, + }; + player.Send(new PacketScSyncAllUnlock(player)); + + player.EnterScene(GetSceneNumIdFromLevelData(table.sceneId)); + player.Send(ScMsgId.ScEnterDungeon, enter); + } + public void Leave() + { + ScLeaveDungeon rsp = new() + { + DungeonId = table.dungeonId, + }; + player.Send(new PacketScSyncAllUnlock(player)); + player.currentDungeon = null; + player.EnterScene(prevPlayerSceneNumId, prevPlayerPos, prevPlayerRot); + player.Send(ScMsgId.ScLeaveDungeon, rsp); + } } } diff --git a/Campofinale/Game/Entities/Entity.cs b/Campofinale/Game/Entities/Entity.cs index 13891d8..df9363a 100644 --- a/Campofinale/Game/Entities/Entity.cs +++ b/Campofinale/Game/Entities/Entity.cs @@ -23,7 +23,6 @@ namespace Campofinale.Game.Entities public int sceneNumId; public bool spawned = false; public bool defaultHide = false; - public bool scriptSpawn = false; public Entity() { diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index a57a885..33f2deb 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -260,8 +260,6 @@ namespace Campofinale.Game public List activeScripts = new(); public List scripts = new(); - [BsonIgnore, JsonIgnore] - private LevelFunctionRangeData currentAreaRange = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -293,6 +291,7 @@ namespace Campofinale.Game foreach(Entity e in GetEntityExcludingChar().FindAll(e => e.spawned)) { guids.Add(e.guid); + e.spawned = false; } entities.Clear(); GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), guids)); @@ -388,35 +387,28 @@ namespace Campofinale.Game return true; } } - - private void UpdateArea() - { - LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); - lv_scene.levelData.functionArea.ranges.ForEach(range => - { - if (range.IsObjectInside(GetOwner().position)) - { - currentAreaRange=range; - } - }); - } + //Bug on scene 101: spawning entities in this way make the game break if you try to load another scene from scene 101 public async void UpdateShowEntities() { - UpdateArea(); List toSpawn = new(); List toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false); toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position))); foreach (Entity e in toCheck) { - - if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) + if(e.Position.Distance(GetOwner().position) > 300 && sceneNumId != 87) + { + continue; + } + if(e.spawned==false) { - if(currentAreaRange.IsObjectInside(e.Position) || sceneNumId==87) if (!e.defaultHide) { - toSpawn.Add(e); - e.spawned = true; + if (GetActiveScript(e.belongLevelScriptId)) + { + toSpawn.Add(e); + e.spawned = true; + } } } @@ -432,18 +424,6 @@ namespace Campofinale.Game GetOwner().Send(new PacketScObjectEnterView(GetOwner(), chunk)); } } - List toDespawn=new(); - foreach(Entity en in GetEntityExcludingChar().FindAll(e=> e.spawned==true)) - { - if (!currentAreaRange.IsObjectInside(en.Position) && en.scriptSpawn==false && sceneNumId != 87) - { - toDespawn.Add(en.guid); - en.spawned = false; - } - - } - if(toDespawn.Count > 0) - GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), toDespawn)); } public Player GetOwner() @@ -469,7 +449,6 @@ namespace Campofinale.Game type = en.entityType, belongLevelScriptId = en.belongLevelScriptId, levelLogicId = en.levelLogicId, - scriptSpawn = scriptSpawn }; entities.Add(entity); Logger.Print($"Enemy Id {v} found on scene {sceneNumId}:{lv_scene.mapIdStr}"); diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 48c6d02..a2127af 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -16,51 +16,44 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLevelScriptActive req = packet.DecodeBody(); - if (req.IsActive) + LevelScriptData data = ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.Find(s=>s.scriptId==req.ScriptId); + if (data != null) + if (data.refGameId != null && session.currentDungeon != null) + { + if (session.currentDungeon.table.dungeonId != data.refGameId) + { + return; + } + } + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + + if (sceneScript != null) { - var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); - if (sceneScript != null) + if (req.IsActive) { sceneScript.state = 3; - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() - { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - State = sceneScript.state - }; - - if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) - { - session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); - session.sceneManager.GetCurScene().UpdateShowEntities(); - } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - - - - } - else - { - var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); - if (sceneScript != null) + else { sceneScript.state = 2; - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() - { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - State = sceneScript.state - }; - - session.sceneManager.GetCurScene().UpdateShowEntities(); - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = sceneScript.state + }; + + if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) + { + session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); + session.sceneManager.GetCurScene().UpdateShowEntities(); + } + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - + } @@ -68,45 +61,40 @@ namespace Campofinale.Packets.Cs public static void HandleCsSceneSetLevelScriptStart(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLevelScriptStart req = packet.DecodeBody(); - - if (req.IsStart) + LevelScriptData data = ResourceManager.GetLevelData(session.curSceneNumId).levelData.levelScripts.Find(s => s.scriptId == req.ScriptId); + if(data!=null) + if (data.refGameId != null && session.currentDungeon != null) { - var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); - if (sceneScript != null) + if (session.currentDungeon.table.dungeonId != data.refGameId) + { + return; + } + } + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) + { + + + if (req.IsStart) { sceneScript.state = 4; - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() - { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - State = sceneScript.state - }; - - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - - } - else - { - var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); - if (sceneScript != null) + else { sceneScript.state = 3; - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() - { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - - State = sceneScript.state - }; - - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = sceneScript.state + }; + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - - + + } public static void ExecuteEventAction(Player player, ScriptAction action, CsSceneLevelScriptEventTrigger req) diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index f8fb8a6..b79b3be 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -678,30 +678,13 @@ namespace Campofinale table = ResourceManager.dungeonTable[dungeonId], }; this.currentDungeon = dungeon; - ScEnterDungeon enter = new() - { - DungeonId = dungeonId, - SceneId = dungeon.table.sceneId, - - }; - - Send(new PacketScSyncAllUnlock(this)); - - EnterScene(GetSceneNumIdFromLevelData(dungeon.table.sceneId)); - Send(ScMsgId.ScEnterDungeon, enter); - + dungeon.Enter(); } public void LeaveDungeon(CsLeaveDungeon req) { - ScLeaveDungeon rsp = new() - { - DungeonId = req.DungeonId, - }; - Send(ScMsgId.ScLeaveDungeon, rsp); - Dungeon dungeon = currentDungeon; - currentDungeon = null; - EnterScene(dungeon.prevPlayerSceneNumId, dungeon.prevPlayerPos, dungeon.prevPlayerRot); + if(currentDungeon!=null) + currentDungeon.Leave(); } public string GetCurrentChapter() diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index fe94da8..739b6dc 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -601,6 +601,7 @@ namespace Campofinale.Resource public class LevelScriptData { public ulong scriptId; + public string refGameId; public List properties = new(); public Dictionary propertyIdToKeyMap = new(); public ScriptActionMap actionMap = new(); From fee2df2fd9a5b57dfb9183e20e6013d02a41ac89 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sun, 3 Aug 2025 15:07:11 +0200 Subject: [PATCH 25/27] Sending ScSceneInteractiveEventTrigger to prevent issues on mobile cbt --- Campofinale/Game/Factory/FactoryManager.cs | 1 + .../Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs | 7 +++++-- Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs | 6 ++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index c30ec1f..2367b33 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -105,6 +105,7 @@ namespace Campofinale.Game.Factory { v++; uint nodeId = v; + FactoryBuildingTable table = ResourceManager.factoryBuildingTable[place.TemplateId]; FactoryNode node = new() { diff --git a/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs b/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs index eec5fcd..0af0482 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneInteractiveEventTrigger.cs @@ -11,8 +11,11 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneInteractiveEventTrigger req = packet.DecodeBody(); - - + ScSceneInteractiveEventTrigger rsp = new() + { + + }; + session.Send(ScMsgId.ScSceneInteractiveEventTrigger, rsp,packet.csHead.UpSeqid); EntityInteractive entity = (EntityInteractive)session.sceneManager.GetEntity(req.Id); if (entity != null) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs index e6844db..555a566 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs @@ -10,12 +10,10 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLastSafeZone req = packet.DecodeBody(); - Logger.Print($"Current Scene: {req.SceneNumId}"); - //Change seamlessy scene - if (req.SceneNumId != session.curSceneNumId) + /*if (req.SceneNumId != session.curSceneNumId) { session.SeamlessEnterScene(req.SceneNumId); - } + }*/ } } From aa59766cfd9bbd148ab6f570fd8bf2504fe06aac Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Thu, 7 Aug 2025 01:05:16 +0200 Subject: [PATCH 26/27] factory manager now is working!! --- Campofinale/Database/Database.cs | 24 +- .../Game/Entities/EntityInteractive.cs | 22 +- Campofinale/Game/Entities/EntityMonster.cs | 6 +- .../Components/FComponentTravelPole.cs | 6 +- Campofinale/Game/Factory/FactoryManager.cs | 599 +++++++++++++++--- Campofinale/Game/SceneManager.cs | 39 +- .../Sc/PacketScFactoryModifyChapterNodes.cs | 37 ++ .../Packets/Sc/PacketScFactoryOpRet.cs | 39 +- .../Packets/Sc/PacketScFactorySyncChapter.cs | 10 +- Campofinale/Player.cs | 1 + Campofinale/Resource/ResourceManager.cs | 14 +- .../Table/InteractiveFacWrapperTable.cs | 8 + 12 files changed, 702 insertions(+), 103 deletions(-) create mode 100644 Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs create mode 100644 Campofinale/Resource/Table/InteractiveFacWrapperTable.cs diff --git a/Campofinale/Database/Database.cs b/Campofinale/Database/Database.cs index d174064..7f5009a 100644 --- a/Campofinale/Database/Database.cs +++ b/Campofinale/Database/Database.cs @@ -11,6 +11,7 @@ using MongoDB.Driver; using System.Security.Cryptography; using System.Text; using static Campofinale.Game.Adventure.AdventureBookManager; +using static Campofinale.Game.Factory.FactoryManager; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Database @@ -103,7 +104,10 @@ namespace Campofinale.Database { return _database.GetCollection("spaceship_rooms").Find(c => c.owner == roleId).ToList(); } - + public FactoryData LoadFactoryData(ulong roleId) + { + return _database.GetCollection("factory").Find(c => c.roleId == roleId).ToList().FirstOrDefault(); + } public List LoadInventoryItems(ulong roleId) { return _database.GetCollection("items").Find(c => c.owner == roleId).ToList(); @@ -319,6 +323,22 @@ namespace Campofinale.Database new ReplaceOptions { IsUpsert = true } ); } + public void UpsertFactoryData(FactoryData item) + { + if (item._id == ObjectId.Empty) + { + item._id = ObjectId.GenerateNewId(); + } + var collection = _database.GetCollection("factory"); + var filter = + Builders.Filter.Eq(c => c.roleId, item.roleId); + + var result = collection.ReplaceOne( + filter, + item, + new ReplaceOptions { IsUpsert = true } + ); + } public void UpsertItem(Item item) { if (item._id == ObjectId.Empty) @@ -427,6 +447,6 @@ namespace Campofinale.Database } } - + } } diff --git a/Campofinale/Game/Entities/EntityInteractive.cs b/Campofinale/Game/Entities/EntityInteractive.cs index 9034815..2a633d8 100644 --- a/Campofinale/Game/Entities/EntityInteractive.cs +++ b/Campofinale/Game/Entities/EntityInteractive.cs @@ -33,9 +33,25 @@ namespace Campofinale.Game.Entities this.BornRot = rot; this.templateId = templateId; this.sceneNumId = scene; + } - + public void InitDefaultProperties() + { + InteractiveData data = ResourceManager.interactiveData.Find(i => i.id == templateId); + if (data != null) + { + properties.AddRange(data.saveProperties); + } + } + public void SetPropValue(uint val, string key) + { + ParamKeyValue keyValue = properties.Find(p => p.key == key); + if (keyValue != null) + { + keyValue.value.valueArray[0].valueBit64 = val; + } + } public SceneInteractive ToProto() { @@ -105,15 +121,17 @@ namespace Campofinale.Game.Entities { string oriTemplateId = ResourceManager.interactiveTable.interactiveDataDict[templateId].templateId; InteractiveData data=ResourceManager.interactiveData.Find(i=>i.id == oriTemplateId); + if(data != null) { return (true,data.propertyKeyToIdMap[key]); } + Logger.PrintError("Interactive Data not found"); return (false, maxCur + 1); } catch (Exception ex) { - //Logger.PrintError(ex.Message); + Logger.PrintError(ex.Message); return (false,maxCur+1); } diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index 08cdc94..7917dcb 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -43,7 +43,11 @@ namespace Campofinale.Game.Entities { List attrInfo = new(); EnemyTable table = ResourceManager.enemyTable[templateId]; - enemyAttributeTemplateTable[table.attrTemplateId].levelDependentAttributes[level].attrs.ForEach(attr => + if(level >= enemyAttributeTemplateTable[table.attrTemplateId].levelDependentAttributes.Count) + { + level = 80; + } + enemyAttributeTemplateTable[table.attrTemplateId].levelDependentAttributes[level-1].attrs.ForEach(attr => { attrInfo.Add(new AttrInfo() { diff --git a/Campofinale/Game/Factory/Components/FComponentTravelPole.cs b/Campofinale/Game/Factory/Components/FComponentTravelPole.cs index cda4e62..d3f1931 100644 --- a/Campofinale/Game/Factory/Components/FComponentTravelPole.cs +++ b/Campofinale/Game/Factory/Components/FComponentTravelPole.cs @@ -5,13 +5,17 @@ namespace Campofinale.Game.Factory.Components { public class FComponentTravelPole : FComponent { + public uint defaultNext; public FComponentTravelPole(uint id) : base(id, FCComponentType.TravelPole) { } public override void SetComponentInfo(ScdFacCom proto) { - proto.TravelPole = new(); + proto.TravelPole = new() + { + DefaultNext = defaultNext + }; } } } diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index 2367b33..d62ae5d 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -1,9 +1,15 @@ -using Campofinale.Game.Entities; +using Campofinale.Database; +using Campofinale.Game.Entities; using Campofinale.Game.Factory.Components; using Campofinale.Packets.Sc; using Campofinale.Protocol; using Campofinale.Resource; +using Campofinale.Resource.Table; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; +using System.Linq; +using System.Numerics; +using System.Xml.Linq; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Factory @@ -12,18 +18,40 @@ namespace Campofinale.Game.Factory { public Player player; public List chapters = new(); - - + public ObjectId _id; + public class FactoryData + { + public ulong roleId; + public ObjectId _id; + public List chapters = new(); + } public FactoryManager(Player player) { - this.player = player; } public void Load() { - //TODO Save - chapters.Add(new FactoryChapter("domain_1", player.roleId)); - chapters.Add(new FactoryChapter("domain_2", player.roleId)); + FactoryData data = DatabaseManager.db.LoadFactoryData(player.roleId); + if (data != null) + { + _id=data._id; + chapters = data.chapters; + } + if(!ChapterExist("domain_1")) chapters.Add(new FactoryChapter("domain_1", player.roleId)); + if(!ChapterExist("domain_2")) chapters.Add(new FactoryChapter("domain_2", player.roleId)); + } + public bool ChapterExist(string id) + { + return chapters.Find(c=>c.chapterId==id)!=null; + } + public void Save() + { + DatabaseManager.db.UpsertFactoryData(new FactoryData() + { + _id= _id, + roleId=player.roleId, + chapters=chapters + }); } public void ExecOp(CsFactoryOp op, ulong seq) { @@ -62,11 +90,180 @@ namespace Campofinale.Game.Factory public List nodes=new(); public uint v = 1; public uint compV = 0; + public int bandwidth = 200; + + public ScFactorySyncChapter ToProto() + { + ScFactorySyncChapter chapter = new() + { + ChapterId = chapterId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, + Blackboard = new() + { + Power = new() + { + PowerGen = 0, + PowerSaveMax = 0, + PowerSaveCurrent = 0, + PowerCost = 0 + }, + InventoryNodeId = 1 + }, + Statistic = new() + { + LastDay = new() + { + + }, + Other = new() + { + InPowerBuilding = 1 + } + }, + PinBoard = new() + { + Cards = + { + + }, + + }, + }; + chapter.Blackboard.Power.PowerSaveCurrent = bandwidth; + domainDataTable[chapterId].levelGroup.ForEach(levelGroup => + { + int grade = GetOwner().sceneManager.GetScene(GetSceneNumIdFromLevelData(levelGroup)).grade; + LevelGradeInfo sceneGrade = ResourceManager.levelGradeTable[levelGroup].grades.Find(g=>g.grade==grade); + if (sceneGrade != null) + { + chapter.Blackboard.Power.PowerGen += sceneGrade.bandwidth; + chapter.Blackboard.Power.PowerSaveMax += sceneGrade.bandwidth; + + var scene = new ScdFactorySyncScene() + { + SceneId = GetSceneNumIdFromLevelData(levelGroup), + + Bandwidth = new() + { + Current = 0, + Max = sceneGrade.bandwidth, + TravelPoleMax = sceneGrade.travelPoleLimit, + + BattleCurrent = 0, + BattleMax = sceneGrade.battleBuildingLimit, + }, + Settlements = + { + + }, + + Panels = + { + + } + }; + int index = 0; + LevelScene scen = GetLevelData(GetSceneNumIdFromLevelData(levelGroup)); + foreach (var reg in scen.levelData.factoryRegions) + { + foreach (var area in reg.areas) + { + var lvData = area.levelData.Find(l=>l.level==grade); + if (lvData == null) + { + lvData = area.levelData.Last(); + } + if (lvData.levelBounds.Count > 0) + { + var bounds = lvData.levelBounds[0]; + scene.Panels.Add(new ScdFactorySyncScenePanel() + { + Index = index, + Level = lvData.level, + MainMesh = + { + new ScdRectInt() + { + X=(int)bounds.start.x, + Z=(int)bounds.start.z, + Y=(int)bounds.start.y, + W=(int)bounds.size.x, + H=(int)bounds.size.y, + L=(int)bounds.size.z, + } + } + }); + index++; + } + + } + } + chapter.Scenes.Add(scene); + } + + }); + nodes.ForEach(node => + { + chapter.Nodes.Add(node.ToProto()); + }); + chapter.Maps.AddRange(GetMaps()); + return chapter; + } + public List GetMaps() + { + List maps = new(); + string levelId = domainDataTable[chapterId].levelGroup[0]; + string mapId = GetLevelData(GetSceneNumIdFromLevelData(levelId)).mapIdStr; + maps.Add(new ScdFactorySyncMap() + { + MapId = ResourceManager.strIdNumTable.chapter_map_id.dic[mapId], + Wires = + { + GetWires() + } + }); + return maps; + } + + public List GetWires() + { + List wires = new(); + HashSet<(ulong, ulong)> addedConnections = new(); // evita doppioni esatti + ulong i = 0; + + foreach (FactoryNode node in nodes) + { + foreach (var conn in node.connectedComps) + { + ulong compA = conn.Key; + ulong compB = conn.Value; + + var key = (compA, compB); + + if (!addedConnections.Contains(key)) + { + wires.Add(new ScdFactorySyncMapWire() + { + Index = i, + FromComId = compA, + ToComId = compB + }); + + addedConnections.Add(key); + i++; + } + } + } + + return wires; + } + public void Update() { try { + UpdatePowerGrid(nodes); foreach (FactoryNode node in nodes) { node.Update(this); @@ -89,51 +286,242 @@ namespace Campofinale.Game.Factory switch (op.OpType) { case FactoryOpType.Place: - CreateNode(op.Place, seq); + CreateNode(op, seq); + break; + case FactoryOpType.MoveNode: + MoveNode(op, seq); + break; + case FactoryOpType.Dismantle: + DismantleNode(op, seq); + break; + case FactoryOpType.AddConnection: + AddConnection(op, seq); + break; + case FactoryOpType.SetTravelPoleDefaultNext: + FactoryNode travelNode = GetNodeByCompId(op.SetTravelPoleDefaultNext.ComponentId); + travelNode.GetComponent().defaultNext = op.SetTravelPoleDefaultNext.DefaultNext; + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, travelNode)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); break; default: break; } } + public void MoveNode(CsFactoryOp op, ulong seq) + { + var move = op.MoveNode; + FactoryNode node = nodes.Find(n => n.nodeId == move.NodeId); + if (node != null) + { + node.direction = new Vector3f(move.Direction); + node.position = new Vector3f(move.Position); + node.worldPosition = new Vector3f(move.InteractiveParam.Position); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId, op), seq); + node.SendEntity(GetOwner(), chapterId); + } + else + { + ScFactoryOpRet ret = new() + { + RetCode = FactoryOpRetCode.Fail, + }; + GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); + } + } + public void DismantleNode(CsFactoryOp op, ulong seq) + { + var dismantle = op.Dismantle; + + FactoryNode nodeRem = nodes.Find(n => n.nodeId == dismantle.NodeId); + if (nodeRem != null) + { + RemoveConnectionsToNode(nodeRem, nodes); + nodes.Remove(nodeRem); + GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() + { + ChapterId = chapterId, + MapId = nodeRem.mapId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Wires = + { + GetWires() + } + }); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, nodeRem.nodeId)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), nodeRem.nodeId, op), seq); + } + else + { + ScFactoryOpRet ret = new() + { + RetCode = FactoryOpRetCode.Fail, + + }; + GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); + } + } + public void RemoveConnectionsToNode(FactoryNode nodeRem, List allNodes) + { + // Ottieni tutti i compId del nodo da rimuovere + HashSet remCompIds = nodeRem.components.Select(c => (ulong)c.compId).ToHashSet(); + + foreach (var node in allNodes) + { + node.connectedComps.RemoveAll(conn => + remCompIds.Contains(conn.Key) || remCompIds.Contains(conn.Value)); + } + } + + public uint nextCompV() { compV++; return compV; } - private void CreateNode(CsdFactoryOpPlace place, ulong seq) + public FactoryNode.FComponent GetCompById(ulong compId) + { + foreach(FactoryNode node in nodes) + { + if (node.components.Find(c => c.compId == compId) != null) + { + return node.components.Find(c => c.compId == compId); + } + } + return null; + } + public FactoryNode GetNodeByCompId(ulong compId) + { + foreach (FactoryNode node in nodes) + { + if (node.components.Find(c => c.compId == compId) != null) + { + return node; + } + } + return null; + } + private void AddConnection(CsFactoryOp op,ulong seq) + { + FactoryNode.FComponent nodeFrom = GetCompById(op.AddConnection.FromComId); + FactoryNode.FComponent nodeTo = GetCompById(op.AddConnection.ToComId); + + if(nodeFrom!=null && nodeTo != null) + { + GetNodeByCompId(nodeFrom.compId).connectedComps.Add(new(nodeFrom.compId, nodeTo.compId)); + GetNodeByCompId(nodeTo.compId).connectedComps.Add(new(nodeTo.compId, nodeFrom.compId)); + GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() + { + ChapterId = chapterId, + MapId = GetNodeByCompId(nodeFrom.compId).mapId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, + Wires = + { + GetWires() + } + }); + var wire = GetWires().Find(w => + (w.FromComId == op.AddConnection.FromComId && w.ToComId == op.AddConnection.ToComId) || + (w.FromComId == op.AddConnection.ToComId && w.ToComId == op.AddConnection.FromComId)); + + if (wire != null) + { + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), (uint)wire.Index, op), seq); + } + else + { + // Facoltativo: log di errore + Console.WriteLine($"[WARN] Connessione non trovata tra {op.AddConnection.FromComId} e {op.AddConnection.ToComId}"); + } + + } + + } + void ResetAllPower(List allNodes) + { + foreach (var node in allNodes) + node.powered = false; + } + void UpdatePowerGrid(List allNodes) + { + ResetAllPower(allNodes); + + HashSet visited = new(); + + foreach (var node in allNodes) + { + if (node.templateId.Contains("hub") || node.templateId == "power_diffuser_1") + { + //if(node.forcePowerOn) + if(node.templateId== "power_diffuser_1") + { + //Check inside factory region + + } + else + { + PropagatePowerFrom(node, visited); + } + + } + } + } + void PropagatePowerFrom(FactoryNode node, HashSet visited) + { + if (visited.Contains(node.nodeId)) + return; + + visited.Add(node.nodeId); + node.powered = true; + if(node.templateId == "power_diffuser_1") + { + //get builds in area test + List nodes=GetNodesInRange(node.position, 15); + foreach(FactoryNode propagateNode in nodes) + { + if (propagateNode.GetComponent() == null) + { + propagateNode.powered = true; + } + } + } + if (node.GetComponent() != null) + foreach (var connectedCompId in node.connectedComps) + { + FactoryNode connectedNode = GetNodeByCompId(connectedCompId.Value); + if (connectedNode != null) + { + PropagatePowerFrom(connectedNode, visited); + } + } + } + private void CreateNode(CsFactoryOp op, ulong seq) { v++; uint nodeId = v; - + CsdFactoryOpPlace place = op.Place; FactoryBuildingTable table = ResourceManager.factoryBuildingTable[place.TemplateId]; FactoryNode node = new() { nodeId = nodeId, templateId = place.TemplateId, mapId = place.MapId, + sceneNumId = GetOwner().sceneManager.GetCurScene().sceneNumId, nodeType = table.GetNodeType(), position = new Vector3f(place.Position), direction = new Vector3f(place.Direction), - guid = GetOwner().random.NextRand() + worldPosition = new Vector3f(place.InteractiveParam.Position), + guid = GetOwner().random.NextRand(), + }; node.InitComponents(this); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); nodes.Add(node); - ScFactoryModifyChapterNodes edit = new() - { - ChapterId = chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), - - }; - GetOwner().Send(new PacketScFactorySyncChapter(GetOwner(), chapterId)); - edit.Nodes.Add(node.ToProto()); - Logger.Print(Newtonsoft.Json.JsonConvert.SerializeObject(edit, Newtonsoft.Json.Formatting.Indented)); - EntityInteractive e = new(place.TemplateId, GetOwner().roleId, new Vector3f(place.Position), new Vector3f(place.Direction), GetOwner().sceneManager.GetCurScene().sceneNumId, node.guid); - GetOwner().sceneManager.GetCurScene().entities.Add(e); - GetOwner().sceneManager.GetCurScene().SpawnEntity(e); - GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, edit); - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId,FactoryOpType.Place),seq); + node.SendEntity(GetOwner(), chapterId); + + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId,op),seq); } @@ -165,46 +553,39 @@ namespace Campofinale.Game.Factory public string templateId; public Vector3f position=new(); public Vector3f direction = new(); + public Vector3f worldPosition = new(); public string instKey=""; public bool deactive = false; public int mapId; + public int sceneNumId; public bool forcePowerOn = false; public List components = new(); [BsonIgnore] public bool powered = false; [BsonIgnore] - public uint connectedPowerNode = 0; + public bool lastPowered = false; + public List connectedComps = new(); public ulong guid; + + public class ConnectedComp + { + public ulong Key; + public ulong Value; + public ConnectedComp(ulong key, ulong value) + { + this.Key = key; + this.Value = value; + } + } public void Update(FactoryChapter chapter) { - if(!templateId.Contains("hub")) - if (GetComponent() != null) + LevelScene scen = GetLevelData(sceneNumId); + if (lastPowered != powered) { - FactoryNode curEnergyNode = chapter.nodes.Find(n => n.nodeId == connectedPowerNode && n.position.Distance(position) <= 20 && n.InPower()); - if (templateId != "power_pole_2") - { - FactoryNode energyNode = chapter.GetNodesInRange(position, 20).Find(n=>n.GetComponent< FComponentPowerPole>()!=null && n.InPower()); - if (energyNode != null && curEnergyNode==null && energyNode.connectedPowerNode!=nodeId) - { - powered= true; - connectedPowerNode = energyNode.nodeId; - chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, new ScFactoryModifyChapterNodes() { Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Nodes = { this.ToProto()} }); - } - else - { - if (curEnergyNode == null && powered==true) - { - powered = false; - connectedPowerNode = 0; - chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, new ScFactoryModifyChapterNodes() { Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Nodes = { this.ToProto() } }); - } - } - } - else - { - //Check near - } + lastPowered = powered; + chapter.GetOwner().Send(new PacketScFactoryModifyChapterNodes(chapter.GetOwner(), chapter.chapterId, this)); } + } public bool InPower() { @@ -222,41 +603,54 @@ namespace Campofinale.Game.Factory { FMesh mesh = new FMesh(); - if (ResourceManager.factoryBuildingTable.ContainsKey(templateId)) + if (ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table)) { - FactoryBuildingTable table = ResourceManager.factoryBuildingTable[templateId]; + float width = table.range.width - 1; + float height = table.range.height - 1; + float depth = table.range.depth-1; - double centerX = position.x + table.range.width / 2.0; - double centerZ = position.z + table.range.depth / 2.0; + Vector3f p1_final = new Vector3f(); + Vector3f p2_final = new Vector3f(); - Vector3f p1 = new Vector3f(position.x, position.y, position.z); - Vector3f p2 = new Vector3f( - position.x + table.range.width, - position.y + table.range.height, - position.z + table.range.depth - ); + switch (direction.y) + { + case 0f: + case 360f: + default: + p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z); + p2_final = p1_final + new Vector3f(width, height, depth); + break; - p1 = RotateAroundY(p1, new Vector3f((float)centerX, position.y, (float)centerZ), direction.y); - p2 = RotateAroundY(p2, new Vector3f((float)centerX, position.y, (float)centerZ), direction.y); - mesh.points.Add(p1); - mesh.points.Add(p2); + case 90f: + // Rotazione 90°: Larghezza e profondità si scambiano. + // Il mesh parte da 'position' ma si estende su assi diversi. + p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z - width); + p2_final = p1_final + new Vector3f(depth, height, width); + break; + + case 180f: + // Rotazione 180°: Larghezza e profondità mantengono i loro valori + // ma il mesh si estende in direzioni negative. + p1_final = position + new Vector3f(table.range.x - width, table.range.y, table.range.z - depth); + p2_final = p1_final + new Vector3f(width, height, depth); + break; + + case 270f: + // Rotazione 270°: Larghezza e profondità si scambiano. + // Il mesh si estende in direzioni diverse rispetto alla rotazione di 90°. + p1_final = position + new Vector3f(table.range.x - depth, table.range.y, table.range.z); + p2_final = p1_final + new Vector3f(depth, height, width); + break; + } + + mesh.points.Add(p1_final); + mesh.points.Add(p2_final); } + return mesh; } - private Vector3f RotateAroundY(Vector3f point, Vector3f origin, double angleDegrees) - { - double angleRadians = angleDegrees * (Math.PI / 180.0); - double cosTheta = Math.Cos(angleRadians); - double sinTheta = Math.Sin(angleRadians); - double dx = point.x - origin.x; - double dz = point.z - origin.z; - double rotatedX = origin.x + (dx * cosTheta - dz * sinTheta); - double rotatedZ = origin.z + (dx * sinTheta + dz * cosTheta); - - return new Vector3f((float)rotatedX, point.y, (float)rotatedZ); - } public ScdFacNode ToProto() { ScdFacNode node = new ScdFacNode() @@ -270,7 +664,7 @@ namespace Campofinale.Game.Factory Power = new() { InPower= InPower(), - NeedInPower=false, + NeedInPower=true, }, NodeType=(int)nodeType, @@ -286,7 +680,8 @@ namespace Campofinale.Game.Factory if(templateId!="__inventory__") { node.Transform.Mesh = GetMesh().ToProto(); - node.Transform.WorldPosition = position.ToProto(); + node.Transform.Position = position.ToProtoScd(); + node.Transform.WorldPosition = worldPosition.ToProto(); node.Transform.WorldRotation = direction.ToProto(); node.InteractiveObject = new() { @@ -354,6 +749,50 @@ namespace Campofinale.Game.Factory } } + + public void SendEntity(Player player, string chapterId) + { + Entity exist = player.sceneManager.GetCurScene().entities.Find(e => e.guid == guid); + if (exist != null) + { + exist.Position = worldPosition; + exist.Rotation = direction; + ScMoveObjectMove move = new() + { + ServerNotify = true, + MoveInfo = + { + new MoveObjectMoveInfo() + { + Objid = guid, + SceneNumId=sceneNumId, + MotionInfo = new() + { + Position=exist.Position.ToProto(), + Rotation=exist.Rotation.ToProto(), + Speed=new Vector() + { + + }, + State=MotionState.MotionNone + } + } + } + }; + player.Send(ScMsgId.ScMoveObjectMove, move); + } + else + { + EntityInteractive e = new(interactiveFacWrapperTable[templateId].interactiveTemplateId, player.roleId, worldPosition, direction, sceneNumId, guid); + e.InitDefaultProperties(); + e.SetPropValue(nodeId, "factory_inst_id"); + + player.sceneManager.GetCurScene().entities.Add(e); + player.sceneManager.GetCurScene().SpawnEntity(e); + } + + } + [BsonDiscriminator(Required = true)] [BsonKnownTypes(typeof(FComponentSelector))] diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 33f2deb..c000be1 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -3,8 +3,10 @@ using Campofinale.Game.Inventory; using Campofinale.Packets.Sc; using Campofinale.Resource; using Campofinale.Resource.Dynamic; +using Campofinale.Resource.Table; using MongoDB.Bson.Serialization.Attributes; using System; +using System.Diagnostics; using System.Text.Json.Serialization; using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; @@ -220,13 +222,18 @@ namespace Campofinale.Game { foreach (var level in ResourceManager.levelDatas) { - if(scenes.Find(s=>s.sceneNumId==level.idNum) == null) + int grade = 1; + if (ResourceManager.levelGradeTable.ContainsKey(level.id)) + { + grade = ResourceManager.levelGradeTable[level.id].grades.Last().grade; + } + if (scenes.Find(s=>s.sceneNumId==level.idNum) == null) scenes.Add(new Scene() { guid = (ulong)player.random.Next(), ownerId=player.roleId, sceneNumId=level.idNum, - + grade= grade }); } } @@ -260,6 +267,8 @@ namespace Campofinale.Game public List activeScripts = new(); public List scripts = new(); + public int grade = 0; + public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -304,7 +313,18 @@ namespace Campofinale.Game { Unload(); LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); - + + LevelGradeInfo sceneGrade = null; + LevelGradeTable table = null; + ResourceManager.levelGradeTable.TryGetValue(lv_scene.id, out table); + if (table != null) + { + sceneGrade=table.grades.Find(g=>g.grade==grade); + } + if (sceneGrade == null) + { + sceneGrade = new(); + } lv_scene.levelData.interactives.ForEach(en => { if (GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87) @@ -342,7 +362,7 @@ namespace Campofinale.Game { if(GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87) return; - EntityMonster entity = new(en.entityDataIdKey,en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) + EntityMonster entity = new(en.entityDataIdKey,sceneGrade.monsterBaseLevel+ en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { type=en.entityType, belongLevelScriptId=en.belongLevelScriptId, @@ -366,7 +386,16 @@ namespace Campofinale.Game entity.defaultHide = en.defaultHide; entities.Add(entity); }); - + GetOwner().factoryManager.chapters.ForEach(ch => + { + ch.nodes.ForEach(n => + { + if (n.sceneNumId == sceneNumId) + { + n.SendEntity(GetOwner(), ch.chapterId); + } + }); + }); UpdateShowEntities(); } diff --git a/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs b/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs new file mode 100644 index 0000000..d34a9d9 --- /dev/null +++ b/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs @@ -0,0 +1,37 @@ +using Campofinale.Game.Factory; +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Sc +{ + public class PacketScFactoryModifyChapterNodes : Packet + { + + public PacketScFactoryModifyChapterNodes(Player client,string chapterId,FactoryNode node) { + ScFactoryModifyChapterNodes edit = new() + { + ChapterId = chapterId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, + Nodes = + { + node.ToProto() + } + }; + SetData(ScMsgId.ScFactoryModifyChapterNodes, edit); + } + public PacketScFactoryModifyChapterNodes(Player client, string chapterId, uint nodeId) + { + ScFactoryModifyChapterNodes edit = new() + { + ChapterId = chapterId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + RemoveNodes = + { + nodeId + } + }; + SetData(ScMsgId.ScFactoryModifyChapterNodes, edit); + } + + } +} diff --git a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs index 9057871..0dcb19c 100644 --- a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs +++ b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs @@ -6,23 +6,50 @@ namespace Campofinale.Packets.Sc public class PacketScFactoryOpRet : Packet { - public PacketScFactoryOpRet(Player client, uint nodeId,FactoryOpType type) { + public PacketScFactoryOpRet(Player client, uint val,CsFactoryOp op) { ScFactoryOpRet proto = new ScFactoryOpRet() { RetCode=FactoryOpRetCode.Ok, - OpType=type, + OpType=op.OpType, }; - if(type == FactoryOpType.Place) + if(op.OpType == FactoryOpType.Place) { proto.Place = new() { - NodeId = nodeId + NodeId = val }; - proto.Index = "CHANNLE_BUILDING"; } - + if (op.OpType == FactoryOpType.MoveNode) + { + proto.MoveNode = new() + { + + }; + } + if (op.OpType == FactoryOpType.AddConnection) + { + proto.AddConnection = new() + { + Index = val, + }; + } + if (op.OpType == FactoryOpType.Dismantle) + { + proto.Dismantle = new() + { + + }; + } + if (op.OpType == FactoryOpType.SetTravelPoleDefaultNext) + { + proto.SetTravelPoleDefaultNext = new() + { + + }; + } + proto.Index=op.Index; SetData(ScMsgId.ScFactoryOpRet, proto); } diff --git a/Campofinale/Packets/Sc/PacketScFactorySyncChapter.cs b/Campofinale/Packets/Sc/PacketScFactorySyncChapter.cs index f154a82..eff592b 100644 --- a/Campofinale/Packets/Sc/PacketScFactorySyncChapter.cs +++ b/Campofinale/Packets/Sc/PacketScFactorySyncChapter.cs @@ -12,7 +12,7 @@ namespace Campofinale.Packets.Sc public PacketScFactorySyncChapter(Player client, string chapterId) { - string json = File.ReadAllText("ScFactorySyncChapter.json"); + /*string json = File.ReadAllText("ScFactorySyncChapter.json"); //ScFactorySyncChapter chapter = Newtonsoft.Json.JsonConvert.DeserializeObject(json); ScFactorySyncChapter chapter = new() @@ -61,7 +61,7 @@ namespace Campofinale.Packets.Sc } } - }*/ + } }, Blackboard = new() { @@ -119,7 +119,7 @@ namespace Campofinale.Packets.Sc { }, - });*/ + }); LevelGradeInfo sceneGrade = ResourceManager.levelGradeTable[levelGroup].grades[0]; chapter.Blackboard.Power.PowerGen += sceneGrade.bandwidth; chapter.Blackboard.Power.PowerSaveMax += sceneGrade.bandwidth; @@ -185,9 +185,9 @@ namespace Campofinale.Packets.Sc foreach(FactoryNode node in client.factoryManager.GetChapter(chapterId).nodes) { chapter.Nodes.Add(node.ToProto()); - } + }*/ //Logger.Print(Newtonsoft.Json.JsonConvert.SerializeObject(chapter,Newtonsoft.Json.Formatting.Indented)); - SetData(ScMsgId.ScFactorySyncChapter, chapter); + SetData(ScMsgId.ScFactorySyncChapter, client.factoryManager.GetChapter(chapterId).ToProto()); } } diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index b79b3be..ebce970 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -617,6 +617,7 @@ namespace Campofinale inventoryManager.Save(); spaceshipManager.Save(); adventureBookManager.Save(); + factoryManager.Save(); if(Server.config.serverOptions.missionsEnabled) missionSystem.Save(); SaveCharacters(); SaveMails(); diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 739b6dc..37d0b90 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json; using System.Numerics; using System; using static Campofinale.Resource.ResourceManager.LevelScene; +using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; namespace Campofinale.Resource { @@ -73,6 +74,7 @@ namespace Campofinale.Resource public static Dictionary itemTypeTable = new(); // public static Dictionary snsChatTable = new();// public static Dictionary giftItemTable = new(); + public static Dictionary interactiveFacWrapperTable = new(); public static List missionDataTable = new(); public static InteractiveTable interactiveTable = new(); // @@ -225,6 +227,7 @@ namespace Campofinale.Resource foreach (string json in jsonFiles) { InteractiveData data = JsonConvert.DeserializeObject(ReadJsonFile(json)); + if (data != null) { interactiveData.Add(data); @@ -339,7 +342,8 @@ namespace Campofinale.Resource public class InteractiveData { public string id; - public Dictionary propertyKeyToIdMap; + public Dictionary propertyKeyToIdMap = new(); + public List saveProperties = new(); } public class FactoryBuildingTable { @@ -816,6 +820,10 @@ namespace Campofinale.Resource param.ValueIntList.Add(val.valueBit64); param.ValueType = (int)ParamValueType.Int; break; + case ParamRealType.UInt: + param.ValueIntList.Add(val.valueBit64); + param.ValueType = (int)ParamValueType.Int; + break; case ParamRealType.WaterVolumePtr: param.ValueIntList.Add(val.valueBit64); param.ValueType = (int)ParamValueType.Int; @@ -980,6 +988,10 @@ namespace Campofinale.Resource { return new Vector3f(v.x * scalar, v.y * scalar, v.z * scalar); } + public static Vector3f operator +(Vector3f v, Vector3f v2) + { + return new Vector3f(v.x + v2.x, v.y + v2.y, v.z + v2.z); + } public Vector3f(float x, float y, float z) { this.x = x; diff --git a/Campofinale/Resource/Table/InteractiveFacWrapperTable.cs b/Campofinale/Resource/Table/InteractiveFacWrapperTable.cs new file mode 100644 index 0000000..a4fcbd3 --- /dev/null +++ b/Campofinale/Resource/Table/InteractiveFacWrapperTable.cs @@ -0,0 +1,8 @@ +namespace Campofinale.Resource.Table +{ + [TableCfgType("TableCfg/InteractiveFacWrapperTable.json", LoadPriority.LOW)] + public class InteractiveFacWrapperTable + { + public string interactiveTemplateId; + } +} From f9af58687cdc01f6a6374d5e18f9bdf1a64005a1 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Thu, 7 Aug 2025 01:06:39 +0200 Subject: [PATCH 27/27] 1.1.6 --- Campofinale/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 2daf8a4..4f2b587 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -59,7 +59,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.6-dev"; + public static string ServerVersion = "1.1.6"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true;