You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.5 KiB
152 lines
4.5 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Sog;
|
|
|
|
namespace Game
|
|
{
|
|
//玩家server patch 机制,
|
|
//使用场景:老玩家的一些数据随着版本迭代已经不符合当下的需求,或者一些业务存在bug,导致玩家数据不正确,需要修复
|
|
//对应的数据,但是不想把修复代码参合再现有的逻辑中、补丁方式修复,所以建议采用patch 机制,玩家只需要执行一次修复,
|
|
//后续将不用再维护相关的修复逻辑。
|
|
|
|
public static class PatchSvc
|
|
{
|
|
private class PatchModel
|
|
{
|
|
public int Id;
|
|
public Func<PlayerOnGame, int> Patch;
|
|
}
|
|
|
|
private static readonly ReaderWriterLockSlim Locker = new();
|
|
|
|
private static int _maxPatch;
|
|
|
|
private static readonly Dictionary<int, PatchModel> AllPatchMethods = new();
|
|
|
|
public static void RegisterAll()
|
|
{
|
|
try
|
|
{
|
|
Locker.EnterUpgradeableReadLock();
|
|
try
|
|
{
|
|
//写锁线程只有一个
|
|
Locker.EnterWriteLock();
|
|
|
|
AllPatchMethods.Clear();
|
|
Register(PatchCode.PATCH_CODE_FIX_TEST, FixTest);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Error("Patch.Register register method failed,e={0}", e.Message);
|
|
}
|
|
finally
|
|
{
|
|
Locker.ExitWriteLock();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Error("Patch.Register register method failed,e={0}", e.Message);
|
|
}
|
|
finally
|
|
{
|
|
Locker.ExitUpgradeableReadLock();
|
|
}
|
|
}
|
|
|
|
private static void Register(int id, Func<PlayerOnGame, int> method)
|
|
|
|
{
|
|
if (method == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TraceLog.Trace("PatchSvc.Register register method,id={0},name={1}", id, method.Method.Name);
|
|
AllPatchMethods[id] = new PatchModel() { Id = id, Patch = method };
|
|
_maxPatch = Math.Max(_maxPatch, id);
|
|
}
|
|
|
|
public static void PatchAll(PlayerOnGame player)
|
|
{
|
|
_Patch(player);
|
|
player.MakeDirty();
|
|
}
|
|
|
|
private static void _Patch(PlayerOnGame player)
|
|
{
|
|
try
|
|
{
|
|
Locker.EnterReadLock();
|
|
int position = player.RoleData.ExtData.Patch;
|
|
if (position == _maxPatch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (AllPatchMethods.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var patch in AllPatchMethods.Where(patch => patch.Key > position))
|
|
{
|
|
try
|
|
{
|
|
patch.Value.Patch(player);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Trace("PatchSvc.PatchAll patch failed. id={0},name={1},error info={2}", patch.Key,
|
|
patch.Value.Patch.Method.Name, e.Message);
|
|
break;
|
|
}
|
|
|
|
position = Math.Max(patch.Key, position);
|
|
}
|
|
|
|
player.RoleData.ExtData.Patch = position;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Trace("PatchSvc.PatchAll patch failed,e={0}", e.Message);
|
|
}
|
|
finally
|
|
{
|
|
Locker.ExitReadLock();
|
|
}
|
|
}
|
|
|
|
public static void OnPlayerBorn(PlayerOnGame player)
|
|
{
|
|
int position = 0;
|
|
try
|
|
{
|
|
Locker.EnterReadLock();
|
|
position = _maxPatch;
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Error("PatchSvc.OnPlayerBorn error: {0}", e.Message);
|
|
}
|
|
finally
|
|
{
|
|
Locker.ExitReadLock();
|
|
}
|
|
player.RoleData.ExtData.Patch = position;
|
|
}
|
|
|
|
//---------------------------------------------------------------- 需要修复的逻辑
|
|
|
|
public static int FixTest(PlayerOnGame player)
|
|
{
|
|
TraceLog.Trace("test fix data player uid={0}", player.UserID);
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|