Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Small fixes 12/11 #663

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Arrowgene.Ddon.GameServer/Characters/HubManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
{
Expand Down
16 changes: 15 additions & 1 deletion Arrowgene.Ddon.GameServer/Characters/QuestManager.cs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should do this instead of filtering out the data from the pcaps

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't filter out the data from the pcaps; these quests control world state and things get angry when they're not present. The problem is that they also want to progress on login, and in my tinkering with the pcaps, I couldn't get them to not progress and still properly do their world state things.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should maybe be a TODO comment to remove the IDs from this list when they get properly handled i suppose

Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ private QuestManager()
private static Dictionary<uint, HashSet<uint>> gTutorialQuests = new Dictionary<uint, HashSet<uint>>();
private static Dictionary<QuestAreaId, HashSet<QuestId>> gWorldQuests = new Dictionary<QuestAreaId, HashSet<QuestId>>();

/// <summary>
/// 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.
/// </summary>
private static readonly HashSet<uint> KnownBadQuestScheduleIds = new HashSet<uint>()
{
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;
Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
}
Expand Down
19 changes: 19 additions & 0 deletions Arrowgene.Ddon.GameServer/WeatherManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.

/// <summary>
/// Number of game hours between forecast times.
Expand Down Expand Up @@ -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<CDataWeatherForecast> GetForecast()
{
List<CDataWeatherForecast> forecast = new List<CDataWeatherForecast>();
Expand Down
Loading