Skip to content

Commit

Permalink
Merge pull request #653 from pacampbell/task_scheduling
Browse files Browse the repository at this point in the history
feat: Implement a generic task scheduler
  • Loading branch information
pacampbell authored Dec 16, 2024
2 parents e036a65 + d1f75c8 commit a1f9c33
Show file tree
Hide file tree
Showing 29 changed files with 526 additions and 14 deletions.
3 changes: 3 additions & 0 deletions Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@
<None Update="Files\Database\Script\migration_epitaph_road.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Files\Database\Script\migration_scheduling.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static class DdonDatabaseBuilder
private static readonly ILogger Logger = LogProvider.Logger<Logger>(typeof(DdonDatabaseBuilder));
private const string DefaultSchemaFile = "Script/schema_sqlite.sql";

public const uint Version = 26;
public const uint Version = 27;

public static IDatabase Build(DatabaseSetting settings)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE ddon_schedule_next (
"type" INTEGER NOT NULL,
"timestamp" BIGINT NOT NULL,
PRIMARY KEY("type")
);

INSERT INTO ddon_schedule_next(type, timestamp) VALUES (19, 0);
Original file line number Diff line number Diff line change
Expand Up @@ -782,3 +782,11 @@ CREATE TABLE IF NOT EXISTS ddon_epitaph_claimed_weekly_rewards (
CONSTRAINT "pk_ddon_epitaph_claimed_weekly_rewards" PRIMARY KEY ("character_id", "epitaph_id"),
CONSTRAINT "fk_ddon_epitaph_claimed_weekly_rewards_character_id" FOREIGN KEY ("character_id") REFERENCES "ddon_character"("character_id") ON DELETE CASCADE
);


CREATE TABLE IF NOT EXISTS ddon_schedule_next (
"type" INTEGER NOT NULL,
"timestamp" BIGINT NOT NULL,
PRIMARY KEY("type")
);
INSERT INTO ddon_schedule_next(type, timestamp) VALUES (19, 0);
7 changes: 6 additions & 1 deletion Arrowgene.Ddon.Database/IDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Arrowgene.Ddon.Shared.Model.BattleContent;
using Arrowgene.Ddon.Shared.Model.Clan;
using Arrowgene.Ddon.Shared.Model.Quest;
using Arrowgene.Ddon.Shared.Model.Scheduler;

namespace Arrowgene.Ddon.Database
{
Expand Down Expand Up @@ -590,6 +591,10 @@ bool InsertBBMContentTreasure(

bool InsertEpitaphWeeklyReward(uint characterId, uint epitaphId, DbConnection? connectionIn = null);
HashSet<uint> GetEpitaphClaimedWeeklyRewards(uint characterId, DbConnection? connectionIn = null);
void DeleteWeeklyRewards(DbConnection? connectionIn = null);
void DeleteWeeklyEpitaphClaimedRewards(DbConnection? connectionIn = null);

// Scheduler
Dictionary<TaskType, SchedulerTaskEntry> SelectAllTaskEntries();
bool UpdateScheduleInfo(TaskType type, long timestamp);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public HashSet<uint> GetEpitaphClaimedWeeklyRewards(uint characterId, DbConnecti
return results;
}

public void DeleteWeeklyRewards(DbConnection? connectionIn = null)
public void DeleteWeeklyEpitaphClaimedRewards(DbConnection? connectionIn = null)
{
ExecuteQuerySafe(connectionIn, (connection) =>
{
Expand Down
49 changes: 49 additions & 0 deletions Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbScheduleNext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Arrowgene.Ddon.Shared.Model.Scheduler;
using System.Collections.Generic;
using System.Data.Common;

namespace Arrowgene.Ddon.Database.Sql.Core
{
public abstract partial class DdonSqlDb<TCon, TCom, TReader> : SqlDb<TCon, TCom, TReader>
where TCon : DbConnection
where TCom : DbCommand
where TReader : DbDataReader
{
protected static readonly string[] ScheduleNextFields = new string[]
{
"type", "timestamp"
};

private static readonly string SqlUpdateScheduleNext = $"UPDATE \"ddon_schedule_next\" SET \"timestamp\"=@timestamp WHERE \"type\"=@type;";
private static readonly string SqlSelectScheduleNext = $"SELECT {BuildQueryField(ScheduleNextFields)} FROM \"ddon_schedule_next\";";


public Dictionary<TaskType, SchedulerTaskEntry> SelectAllTaskEntries()
{
Dictionary<TaskType, SchedulerTaskEntry> results = new Dictionary<TaskType, SchedulerTaskEntry>();
ExecuteReader(SqlSelectScheduleNext, command => { }, reader =>
{
while (reader.Read())
{
TaskType type = (TaskType) GetUInt32(reader, "type");
results[type] = new SchedulerTaskEntry()
{
Type = type,
Timestamp = GetInt64(reader, "timestamp")
};
}
});
return results;
}

public bool UpdateScheduleInfo(TaskType type, long timestamp)
{
return ExecuteNonQuery(SqlUpdateScheduleNext, command =>
{
AddParameter(command, "@type", (uint) type);
AddParameter(command, "@timestamp", timestamp);
}) == 1;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Data.Common;

namespace Arrowgene.Ddon.Database.Sql.Core.Migration
{
public class TaskSchedulerMigration : IMigrationStrategy
{
public uint From => 26;
public uint To => 27;

private readonly DatabaseSetting DatabaseSetting;

public TaskSchedulerMigration(DatabaseSetting databaseSetting)
{
DatabaseSetting = databaseSetting;
}

public bool Migrate(IDatabase db, DbConnection conn)
{
string adaptedSchema = DdonDatabaseBuilder.GetAdaptedSchema(DatabaseSetting, "Script/migration_scheduling.sql");
db.Execute(conn, adaptedSchema);
return true;
}
}
}

2 changes: 1 addition & 1 deletion Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public Character SelectCharacter(uint characterId, DbConnection? connectionIn =

character.EpitaphRoadState.UnlockedContent = _Server.Database.GetEpitaphRoadUnlocks(character.CharacterId, connectionIn);

if (_Server.Setting.GameLogicSetting.EnableEpitaphWeeklyRewards)
if (_Server.Setting.GameLogicSetting.EnableEpitaphWeeklyRewards.Value)
{
character.EpitaphRoadState.WeeklyRewardsClaimed = _Server.Database.GetEpitaphClaimedWeeklyRewards(character.CharacterId, connectionIn);
}
Expand Down
19 changes: 18 additions & 1 deletion Arrowgene.Ddon.GameServer/Characters/EpitaphRoadManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,7 @@ public List<InstancedGatheringItem> RollGatheringLoot(GameClient client, Charact
{
results.AddRange(RollWeeklyChestReward(dungeonInfo, reward));

if (_Server.Setting.GameLogicSetting.EnableEpitaphWeeklyRewards)
if (_Server.Setting.GameLogicSetting.EnableEpitaphWeeklyRewards.Value)
{
character.EpitaphRoadState.WeeklyRewardsClaimed.Add(reward.EpitaphId);
_Server.Database.InsertEpitaphWeeklyReward(character.CharacterId, reward.EpitaphId);
Expand Down Expand Up @@ -1321,5 +1321,22 @@ public List<InstancedGatheringItem> RollGatheringLoot(GameClient client, Charact

return results;
}

/// <summary>
/// Called by the task manager. The main task will signal all channels
/// to flush the cached information queried by the player when first
/// logging in and send a notification to all players that the action
/// occurred.
/// </summary>
public void PerformWeeklyReset()
{
_Server.ChatManager.BroadcastMessage(LobbyChatMsgType.ManagementAlertN, "Epitaph Road Weekly Rewards Reset");

// Clear out cached data related to epitaph weekly rewards
foreach (var client in _Server.ClientLookup.GetAll())
{
client.Character.EpitaphRoadState.WeeklyRewardsClaimed.Clear();
}
}
}
}
20 changes: 13 additions & 7 deletions Arrowgene.Ddon.GameServer/Chat/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Logging;
using System;
using System.Collections.Generic;
using System.Linq;

Expand All @@ -14,11 +15,11 @@ public class ChatManager
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(ChatManager));

private readonly List<IChatHandler> _handler;
private readonly DdonGameServer _server;
private readonly DdonGameServer _Server;

public ChatManager(DdonGameServer server)
{
_server = server;
_Server = server;
_handler = new List<IChatHandler>();
}

Expand All @@ -42,7 +43,7 @@ public void SendMessage(string message, string firstName, string lastName, Lobby
response.PhrasesIndex = 0;
foreach (uint characterId in characterIds)
{
GameClient client = _server.ClientLookup.GetClientByCharacterId(characterId);
GameClient client = _Server.ClientLookup.GetClientByCharacterId(characterId);
if (client == null)
{
continue;
Expand Down Expand Up @@ -73,6 +74,11 @@ public void SendMessage(string message, string firstName, string lastName, Lobby
response.Recipients.AddRange(recipients);
Send(response);
}

public void BroadcastMessage(LobbyChatMsgType type, string message)
{
SendMessage(message, string.Empty, string.Empty, type, _Server.ClientLookup.GetAll());
}

public void SendTellMessage(GameClient sender, GameClient receiver, C2SChatSendTellMsgReq request)
{
Expand All @@ -89,7 +95,7 @@ public void SendTellMessage(GameClient sender, GameClient receiver, C2SChatSendT

public void SendTellMessageForeign(GameClient client, C2SChatSendTellMsgReq request)
{
_server.RpcManager.AnnounceTellChat(client, request);
_Server.RpcManager.AnnounceTellChat(client, request);

ChatResponse senderChatResponse = new ChatResponse
{
Expand Down Expand Up @@ -155,7 +161,7 @@ private void Deliver(GameClient client, ChatResponse response)
{
case LobbyChatMsgType.Say:
case LobbyChatMsgType.Shout:
response.Recipients.AddRange(_server.ClientLookup.GetAll());
response.Recipients.AddRange(_Server.ClientLookup.GetAll());
break;
case LobbyChatMsgType.Party:
PartyGroup party = client.Party;
Expand All @@ -171,13 +177,13 @@ private void Deliver(GameClient client, ChatResponse response)
break;
}

response.Recipients.AddRange(_server.ClientLookup.GetAll().Where(
response.Recipients.AddRange(_Server.ClientLookup.GetAll().Where(
x => x.Character != null
&& client.Character != null
&& x.Character.ClanId == client.Character.ClanId)
);

_server.RpcManager.AnnounceClanChat(client, response);
_Server.RpcManager.AnnounceClanChat(client, response);
break;
default:
response.Recipients.Add(client);
Expand Down
8 changes: 8 additions & 0 deletions Arrowgene.Ddon.GameServer/DdonGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
ClanManager = new ClanManager(this);
RpcManager = new RpcManager(this);
EpitaphRoadManager = new EpitaphRoadManager(this);
ScheduleManager = new ScheduleManager(this);

// Orb Management is slightly complex and requires updating fields across multiple systems
OrbUnlockManager = new OrbUnlockManager(database, WalletManager, JobManager, CharacterManager);
Expand Down Expand Up @@ -115,6 +116,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
public ClanManager ClanManager { get; }
public RpcManager RpcManager { get; }
public EpitaphRoadManager EpitaphRoadManager { get; }
private ScheduleManager ScheduleManager { get; }

public ChatLogHandler ChatLogHandler { get; }

Expand All @@ -129,6 +131,12 @@ public override void Start()
{
QuestManager.LoadQuests(this);
GpCourseManager.EvaluateCourses();

if (ServerUtils.IsHeadServer(this))
{
ScheduleManager.StartServerTasks();
}

LoadChatHandler();
LoadPacketHandler();
base.Start();
Expand Down
12 changes: 12 additions & 0 deletions Arrowgene.Ddon.GameServer/RpcManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
using Arrowgene.Logging;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Security.Claims;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
Expand Down Expand Up @@ -142,6 +144,11 @@ public List<CDataGameServerListInfo> ServerListInfo()
return ChannelInfo.Keys.Select(x => ServerListInfo(x)).ToList();
}

public ServerInfo HeadServer()
{
return ChannelInfo.Values.ToList().OrderBy(x => x.Id).ToList()[0];
}

public CDataGameServerListInfo ServerListInfo(ushort channelId)
{
var info = ChannelInfo[channelId].ToCDataGameServerListInfo();
Expand Down Expand Up @@ -412,5 +419,10 @@ public void AnnounceClanPacket<T>(uint clanId, T packet, uint characterId = 0)
AnnounceClan(clanId, "internal/packet", RpcInternalCommand.AnnouncePacketClan, data);
}
}

public void AnnounceEpitaphWeeklyReset()
{
AnnounceAll("internal/packet", RpcInternalCommand.EpitaphRoadWeeklyReset, null);
}
}
}
Loading

0 comments on commit a1f9c33

Please sign in to comment.