diff --git a/Arrowgene.Ddon.GameServer/Characters/HubManager.cs b/Arrowgene.Ddon.GameServer/Characters/HubManager.cs index c092e5952..884b8e375 100644 --- a/Arrowgene.Ddon.GameServer/Characters/HubManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/HubManager.cs @@ -77,6 +77,8 @@ public void UpdateLobbyContextOnStageChange(GameClient client, uint previousStag HubMembers[previousStageId].Remove(client); foreach (GameClient otherClient in Server.ClientLookup.GetAll().Where(x => x.Character != null)) { + if (otherClient == client) continue; + if (HubMembers[previousStageId].Contains(otherClient)) { // They saw us leave, and do not need to be updated, their clients discard the context automatically. @@ -99,6 +101,8 @@ public void UpdateLobbyContextOnStageChange(GameClient client, uint previousStag { foreach (GameClient otherClient in HubMembers[targetStageId].Where(x => x.Character != null)) { + if (otherClient == client) continue; + uint otherId = otherClient.Character.CharacterId; if (!otherClient.Character.LastSeenLobby.TryGetValue(id, out var lastStage) || lastStage != targetStageId) { diff --git a/Arrowgene.Ddon.GameServer/Characters/QuestManager.cs b/Arrowgene.Ddon.GameServer/Characters/QuestManager.cs index 351e2f6b4..6c42c841a 100644 --- a/Arrowgene.Ddon.GameServer/Characters/QuestManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/QuestManager.cs @@ -32,6 +32,16 @@ private QuestManager() private static Dictionary> gTutorialQuests = new Dictionary>(); private static Dictionary> gWorldQuests = new Dictionary>(); + /// + /// QuestScheduleIds that are requested as part of World Manage Quests from pcaps. + /// We know they can't be found, so don't audibly complain about them. + /// TODO: Remove this when those quests are handled properly. + /// + private static readonly HashSet KnownBadQuestScheduleIds = new HashSet() + { + 25077, 43645, 43646, 47734, 47736, 47737, 47738, 47739, 49692, 77644, 151381, 208640, 233576, 259411, 259412, 287378, 315624 + }; + public static void LoadQuests(DdonGameServer server) { var assetRepository = server.AssetRepository; @@ -125,7 +135,11 @@ public static Quest GetQuestByScheduleId(uint questScheduleId) { if (!gQuests.ContainsKey(questScheduleId)) { - Logger.Error($"GetQuestByScheduleId: Invalid questScheduleId {questScheduleId}"); + if (!KnownBadQuestScheduleIds.Contains(questScheduleId)) + { + Logger.Error($"GetQuestByScheduleId: Invalid questScheduleId {questScheduleId}"); + } + return null; } diff --git a/Arrowgene.Ddon.GameServer/Handler/ServerGameTimeGetBaseinfoHandler.cs b/Arrowgene.Ddon.GameServer/Handler/ServerGameTimeGetBaseinfoHandler.cs index c0103d6c3..bc4e72006 100644 --- a/Arrowgene.Ddon.GameServer/Handler/ServerGameTimeGetBaseinfoHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/ServerGameTimeGetBaseinfoHandler.cs @@ -1,6 +1,5 @@ using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Ddon.Shared.Entity.Structure; using Arrowgene.Logging; namespace Arrowgene.Ddon.GameServer.Handler @@ -20,15 +19,7 @@ public override S2CServerGameTimeGetBaseInfoRes Handle(GameClient client, C2SSer res.GameTimeBaseInfo.OriginalRealTimeSec = WeatherManager.OriginalRealTimeSec; res.GameTimeBaseInfo.GameTimeOneDayMin = Server.Setting.GameLogicSetting.GameClockTimescale; res.WeatherLoop = Server.WeatherManager.WeatherLoopList; - - //TODO: Investigate these values. The moon cycles but predicting the current phase serverside is still unclear. - res.MoonAgeLoopSec = Server.Setting.GameLogicSetting.GameClockTimescale * 60; - res.MoonSchedule.Add(new CDataMoonSchedule() - { - BeginTimeSec = long.MinValue, - EndTimeSec = long.MaxValue, - MoonAge = 14 - }); + res.MoonAgeLoopSec = WeatherManager.MoonAgeLoopSec; return res; } diff --git a/Arrowgene.Ddon.GameServer/WeatherManager.cs b/Arrowgene.Ddon.GameServer/WeatherManager.cs index e7f7dacab..92cfb3383 100644 --- a/Arrowgene.Ddon.GameServer/WeatherManager.cs +++ b/Arrowgene.Ddon.GameServer/WeatherManager.cs @@ -15,6 +15,8 @@ public class WeatherManager public static readonly long OriginalRealTimeSec = 0x55DDD470; // Taken from the pcaps. A few days before DDOn release public static readonly long OriginalGameTimeSec = 0x22C2ED000; // Taken from the pcaps. public static readonly uint GameTimeDayHour = 24; + public static readonly uint GameTimeMoonAges = 30; + public static readonly uint MoonAgeLoopSec = 1209600; // Taken from the pcaps; 14 real life days per lunar cycle. /// /// Number of game hours between forecast times. @@ -56,6 +58,23 @@ public Weather GetWeather(DateTimeOffset time) return Weather.Fine; } + public uint GetMoonPhase() + { + return GetMoonPhase(DateTimeOffset.UtcNow); + } + + public uint GetMoonPhase(DateTimeOffset time) + { + ulong secondsPerLestanianDay = _Server.Setting.GameLogicSetting.GameClockTimescale * 60; + ulong secondsPerMoonAge = MoonAgeLoopSec / GameTimeMoonAges; + ulong secondsElapsed = (ulong)(time.ToUnixTimeSeconds() - OriginalRealTimeSec); + + // This is how the android app calculates this. Is this exploiting some integer math trickery? + ulong offsetMoonTime = (secondsElapsed + secondsPerLestanianDay / 2) / secondsPerLestanianDay * secondsPerLestanianDay; + + return (uint)(offsetMoonTime / secondsPerMoonAge) % GameTimeMoonAges; + } + public List GetForecast() { List forecast = new List();