mirror of
https://github.com/BillyCool/MariesWonderland.git
synced 2026-05-07 05:03:44 +02:00
Simplify userdb access
This commit is contained in:
@@ -10,6 +10,8 @@ namespace MariesWonderland.Data;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DarkUserMemoryDatabase
|
public class DarkUserMemoryDatabase
|
||||||
{
|
{
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
public List<EntityIUser> EntityIUser { get; set; } = [];
|
public List<EntityIUser> EntityIUser { get; set; } = [];
|
||||||
|
|
||||||
public List<EntityIUserApple> EntityIUserApple { get; set; } = [];
|
public List<EntityIUserApple> EntityIUserApple { get; set; } = [];
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
var userId = GenerateUserId();
|
var userId = GenerateUserId();
|
||||||
_uuidToUserId[uuid] = userId;
|
_uuidToUserId[uuid] = userId;
|
||||||
var db = new DarkUserMemoryDatabase();
|
var db = new DarkUserMemoryDatabase { UserId = userId };
|
||||||
SeedInitialUserData(db, userId);
|
SeedInitialUserData(db);
|
||||||
_users[userId] = db;
|
_users[userId] = db;
|
||||||
return (userId, true);
|
return (userId, true);
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
{
|
{
|
||||||
if (!_users.TryGetValue(userId, out var db))
|
if (!_users.TryGetValue(userId, out var db))
|
||||||
{
|
{
|
||||||
db = new DarkUserMemoryDatabase();
|
db = new DarkUserMemoryDatabase { UserId = userId };
|
||||||
_users[userId] = db;
|
_users[userId] = db;
|
||||||
}
|
}
|
||||||
return db;
|
return db;
|
||||||
@@ -96,7 +96,10 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
/// Stores a user database, replacing any existing one for that userId.
|
/// Stores a user database, replacing any existing one for that userId.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Set(long userId, DarkUserMemoryDatabase db)
|
public void Set(long userId, DarkUserMemoryDatabase db)
|
||||||
=> _users[userId] = db;
|
{
|
||||||
|
db.UserId = userId;
|
||||||
|
_users[userId] = db;
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<long, DarkUserMemoryDatabase> All => _users;
|
public IReadOnlyDictionary<long, DarkUserMemoryDatabase> All => _users;
|
||||||
|
|
||||||
@@ -141,7 +144,10 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
_sessions.Clear();
|
_sessions.Clear();
|
||||||
|
|
||||||
foreach (var (userId, db) in snapshot.Users)
|
foreach (var (userId, db) in snapshot.Users)
|
||||||
|
{
|
||||||
|
db.UserId = userId;
|
||||||
_users[userId] = db;
|
_users[userId] = db;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var (uuid, userId) in snapshot.UuidToUserId)
|
foreach (var (uuid, userId) in snapshot.UuidToUserId)
|
||||||
_uuidToUserId[uuid] = userId;
|
_uuidToUserId[uuid] = userId;
|
||||||
@@ -173,13 +179,13 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Populates a new user database with default records (profile, status, starting weapons, etc.).
|
/// Populates a new user database with default records (profile, status, starting weapons, etc.).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SeedInitialUserData(DarkUserMemoryDatabase db, long userId)
|
private void SeedInitialUserData(DarkUserMemoryDatabase db)
|
||||||
{
|
{
|
||||||
var nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
var nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
db.EntityIUser.Add(new EntityIUser
|
db.EntityIUser.Add(new EntityIUser
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
PlayerId = GeneratePlayerId(),
|
PlayerId = GeneratePlayerId(),
|
||||||
OsType = 2,
|
OsType = 2,
|
||||||
PlatformType = PlatformType.GOOGLE_PLAY_STORE,
|
PlatformType = PlatformType.GOOGLE_PLAY_STORE,
|
||||||
@@ -190,13 +196,13 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserSetting.Add(new EntityIUserSetting
|
db.EntityIUserSetting.Add(new EntityIUserSetting
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
IsNotifyPurchaseAlert = false
|
IsNotifyPurchaseAlert = false
|
||||||
});
|
});
|
||||||
|
|
||||||
db.EntityIUserStatus.Add(new EntityIUserStatus
|
db.EntityIUserStatus.Add(new EntityIUserStatus
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
Exp = 0,
|
Exp = 0,
|
||||||
StaminaMilliValue = 60000,
|
StaminaMilliValue = 60000,
|
||||||
@@ -205,7 +211,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserProfile.Add(new EntityIUserProfile
|
db.EntityIUserProfile.Add(new EntityIUserProfile
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
Name = string.Empty,
|
Name = string.Empty,
|
||||||
NameUpdateDatetime = nowMs,
|
NameUpdateDatetime = nowMs,
|
||||||
Message = string.Empty,
|
Message = string.Empty,
|
||||||
@@ -216,7 +222,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserLogin.Add(new EntityIUserLogin
|
db.EntityIUserLogin.Add(new EntityIUserLogin
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
TotalLoginCount = 1,
|
TotalLoginCount = 1,
|
||||||
ContinualLoginCount = 1,
|
ContinualLoginCount = 1,
|
||||||
MaxContinualLoginCount = 1,
|
MaxContinualLoginCount = 1,
|
||||||
@@ -226,7 +232,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserLoginBonus.Add(new EntityIUserLoginBonus
|
db.EntityIUserLoginBonus.Add(new EntityIUserLoginBonus
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
LoginBonusId = 1,
|
LoginBonusId = 1,
|
||||||
CurrentPageNumber = 1,
|
CurrentPageNumber = 1,
|
||||||
CurrentStampNumber = 0,
|
CurrentStampNumber = 0,
|
||||||
@@ -235,7 +241,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserTutorialProgress.Add(new EntityIUserTutorialProgress
|
db.EntityIUserTutorialProgress.Add(new EntityIUserTutorialProgress
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
TutorialType = TutorialType.GAME_START,
|
TutorialType = TutorialType.GAME_START,
|
||||||
ProgressPhase = 0,
|
ProgressPhase = 0,
|
||||||
ChoiceId = 0
|
ChoiceId = 0
|
||||||
@@ -247,7 +253,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserWeapon.Add(new EntityIUserWeapon
|
db.EntityIUserWeapon.Add(new EntityIUserWeapon
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserWeaponUuid = uuid,
|
UserWeaponUuid = uuid,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
@@ -259,7 +265,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserWeaponNote.Add(new EntityIUserWeaponNote
|
db.EntityIUserWeaponNote.Add(new EntityIUserWeaponNote
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
MaxLevel = 1,
|
MaxLevel = 1,
|
||||||
MaxLimitBreakCount = 0,
|
MaxLimitBreakCount = 0,
|
||||||
@@ -268,7 +274,7 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
db.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory
|
db.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
ReleasedMaxStoryIndex = 1
|
ReleasedMaxStoryIndex = 1
|
||||||
});
|
});
|
||||||
@@ -277,10 +283,10 @@ public class UserDataStore(DarkMasterMemoryDatabase masterDb)
|
|||||||
if (masterWeapon != null)
|
if (masterWeapon != null)
|
||||||
{
|
{
|
||||||
foreach (EntityMWeaponAbilityGroup ag in _masterDb.EntityMWeaponAbilityGroup.Where(g => g.WeaponAbilityGroupId == masterWeapon.WeaponAbilityGroupId))
|
foreach (EntityMWeaponAbilityGroup ag in _masterDb.EntityMWeaponAbilityGroup.Where(g => g.WeaponAbilityGroupId == masterWeapon.WeaponAbilityGroupId))
|
||||||
db.EntityIUserWeaponAbility.Add(new EntityIUserWeaponAbility { UserId = userId, UserWeaponUuid = uuid, SlotNumber = ag.SlotNumber, Level = 1 });
|
db.EntityIUserWeaponAbility.Add(new EntityIUserWeaponAbility { UserId = db.UserId, UserWeaponUuid = uuid, SlotNumber = ag.SlotNumber, Level = 1 });
|
||||||
|
|
||||||
foreach (EntityMWeaponSkillGroup sg in _masterDb.EntityMWeaponSkillGroup.Where(g => g.WeaponSkillGroupId == masterWeapon.WeaponSkillGroupId))
|
foreach (EntityMWeaponSkillGroup sg in _masterDb.EntityMWeaponSkillGroup.Where(g => g.WeaponSkillGroupId == masterWeapon.WeaponSkillGroupId))
|
||||||
db.EntityIUserWeaponSkill.Add(new EntityIUserWeaponSkill { UserId = userId, UserWeaponUuid = uuid, SlotNumber = sg.SlotNumber, Level = 1 });
|
db.EntityIUserWeaponSkill.Add(new EntityIUserWeaponSkill { UserId = db.UserId, UserWeaponUuid = uuid, SlotNumber = sg.SlotNumber, Level = 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public static class PossessionHelper
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a possession to the user by type, delegating to type-specific handlers.
|
/// Grants a possession to the user by type, delegating to type-specific handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Apply(DarkUserMemoryDatabase userDb, long userId, PossessionType type, int id, int count, DarkMasterMemoryDatabase masterDb)
|
public static void Apply(DarkUserMemoryDatabase userDb, PossessionType type, int id, int count, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ public static class PossessionHelper
|
|||||||
{
|
{
|
||||||
EntityIUserMaterial? mat = userDb.EntityIUserMaterial.FirstOrDefault(m => m.MaterialId == id);
|
EntityIUserMaterial? mat = userDb.EntityIUserMaterial.FirstOrDefault(m => m.MaterialId == id);
|
||||||
if (mat == null)
|
if (mat == null)
|
||||||
userDb.EntityIUserMaterial.Add(new EntityIUserMaterial { UserId = userId, MaterialId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
userDb.EntityIUserMaterial.Add(new EntityIUserMaterial { UserId = userDb.UserId, MaterialId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
||||||
else
|
else
|
||||||
mat.Count += count;
|
mat.Count += count;
|
||||||
break;
|
break;
|
||||||
@@ -38,7 +38,7 @@ public static class PossessionHelper
|
|||||||
{
|
{
|
||||||
EntityIUserConsumableItem? item = userDb.EntityIUserConsumableItem.FirstOrDefault(c => c.ConsumableItemId == id);
|
EntityIUserConsumableItem? item = userDb.EntityIUserConsumableItem.FirstOrDefault(c => c.ConsumableItemId == id);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem { UserId = userId, ConsumableItemId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem { UserId = userDb.UserId, ConsumableItemId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
||||||
else
|
else
|
||||||
item.Count += count;
|
item.Count += count;
|
||||||
break;
|
break;
|
||||||
@@ -47,7 +47,7 @@ public static class PossessionHelper
|
|||||||
{
|
{
|
||||||
EntityIUserImportantItem? item = userDb.EntityIUserImportantItem.FirstOrDefault(c => c.ImportantItemId == id);
|
EntityIUserImportantItem? item = userDb.EntityIUserImportantItem.FirstOrDefault(c => c.ImportantItemId == id);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
userDb.EntityIUserImportantItem.Add(new EntityIUserImportantItem { UserId = userId, ImportantItemId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
userDb.EntityIUserImportantItem.Add(new EntityIUserImportantItem { UserId = userDb.UserId, ImportantItemId = id, Count = count, FirstAcquisitionDatetime = nowMs });
|
||||||
else
|
else
|
||||||
item.Count += count;
|
item.Count += count;
|
||||||
break;
|
break;
|
||||||
@@ -56,24 +56,24 @@ public static class PossessionHelper
|
|||||||
{
|
{
|
||||||
EntityIUserPremiumItem? item = userDb.EntityIUserPremiumItem.FirstOrDefault(p => p.PremiumItemId == id);
|
EntityIUserPremiumItem? item = userDb.EntityIUserPremiumItem.FirstOrDefault(p => p.PremiumItemId == id);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
userDb.EntityIUserPremiumItem.Add(new EntityIUserPremiumItem { UserId = userId, PremiumItemId = id, AcquisitionDatetime = nowMs });
|
userDb.EntityIUserPremiumItem.Add(new EntityIUserPremiumItem { UserId = userDb.UserId, PremiumItemId = id, AcquisitionDatetime = nowMs });
|
||||||
else
|
else
|
||||||
item.AcquisitionDatetime = nowMs;
|
item.AcquisitionDatetime = nowMs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PossessionType.WEAPON:
|
case PossessionType.WEAPON:
|
||||||
case PossessionType.WEAPON_ENHANCED:
|
case PossessionType.WEAPON_ENHANCED:
|
||||||
WeaponHelper.GrantWeapon(userDb, userId, id, masterDb);
|
WeaponHelper.GrantWeapon(userDb, id, masterDb);
|
||||||
break;
|
break;
|
||||||
case PossessionType.COSTUME:
|
case PossessionType.COSTUME:
|
||||||
case PossessionType.COSTUME_ENHANCED:
|
case PossessionType.COSTUME_ENHANCED:
|
||||||
GrantCostume(userDb, userId, id, masterDb);
|
GrantCostume(userDb, id, masterDb);
|
||||||
break;
|
break;
|
||||||
case PossessionType.COMPANION:
|
case PossessionType.COMPANION:
|
||||||
GrantCompanion(userDb, userId, id);
|
GrantCompanion(userDb, id);
|
||||||
break;
|
break;
|
||||||
case PossessionType.PARTS:
|
case PossessionType.PARTS:
|
||||||
GrantParts(userDb, userId, id, masterDb);
|
GrantParts(userDb, id, masterDb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,14 +81,14 @@ public static class PossessionHelper
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a costume to the user, unlocking the associated character if not already owned.
|
/// Grants a costume to the user, unlocking the associated character if not already owned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void GrantCostume(DarkUserMemoryDatabase userDb, long userId, int costumeId, DarkMasterMemoryDatabase masterDb)
|
public static void GrantCostume(DarkUserMemoryDatabase userDb, int costumeId, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
string uuid = Guid.NewGuid().ToString();
|
string uuid = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
userDb.EntityIUserCostume.Add(new EntityIUserCostume
|
userDb.EntityIUserCostume.Add(new EntityIUserCostume
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserCostumeUuid = uuid,
|
UserCostumeUuid = uuid,
|
||||||
CostumeId = costumeId,
|
CostumeId = costumeId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
@@ -99,22 +99,22 @@ public static class PossessionHelper
|
|||||||
// Auto-unlock the character tied to this costume if not already owned
|
// Auto-unlock the character tied to this costume if not already owned
|
||||||
EntityMCostume? masterCostume = masterDb.EntityMCostume.FirstOrDefault(c => c.CostumeId == costumeId);
|
EntityMCostume? masterCostume = masterDb.EntityMCostume.FirstOrDefault(c => c.CostumeId == costumeId);
|
||||||
if (masterCostume != null && !userDb.EntityIUserCharacter.Any(c => c.CharacterId == masterCostume.CharacterId))
|
if (masterCostume != null && !userDb.EntityIUserCharacter.Any(c => c.CharacterId == masterCostume.CharacterId))
|
||||||
userDb.EntityIUserCharacter.Add(new EntityIUserCharacter { UserId = userId, CharacterId = masterCostume.CharacterId, Level = 1 });
|
userDb.EntityIUserCharacter.Add(new EntityIUserCharacter { UserId = userDb.UserId, CharacterId = masterCostume.CharacterId, Level = 1 });
|
||||||
|
|
||||||
userDb.EntityIUserCostumeActiveSkill.Add(new EntityIUserCostumeActiveSkill { UserId = userId, UserCostumeUuid = uuid, Level = 1, AcquisitionDatetime = nowMs });
|
userDb.EntityIUserCostumeActiveSkill.Add(new EntityIUserCostumeActiveSkill { UserId = userDb.UserId, UserCostumeUuid = uuid, Level = 1, AcquisitionDatetime = nowMs });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a companion to the user. Skips if the companion is already owned.
|
/// Grants a companion to the user. Skips if the companion is already owned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void GrantCompanion(DarkUserMemoryDatabase userDb, long userId, int companionId)
|
public static void GrantCompanion(DarkUserMemoryDatabase userDb, int companionId)
|
||||||
{
|
{
|
||||||
if (userDb.EntityIUserCompanion.Any(c => c.CompanionId == companionId)) return;
|
if (userDb.EntityIUserCompanion.Any(c => c.CompanionId == companionId)) return;
|
||||||
|
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
userDb.EntityIUserCompanion.Add(new EntityIUserCompanion
|
userDb.EntityIUserCompanion.Add(new EntityIUserCompanion
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserCompanionUuid = Guid.NewGuid().ToString(),
|
UserCompanionUuid = Guid.NewGuid().ToString(),
|
||||||
CompanionId = companionId,
|
CompanionId = companionId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
@@ -126,7 +126,7 @@ public static class PossessionHelper
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a single Parts item to the user. Skips if the user already owns a part with the same PartsId.
|
/// Grants a single Parts item to the user. Skips if the user already owns a part with the same PartsId.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void GrantParts(DarkUserMemoryDatabase userDb, long userId, int partsId, DarkMasterMemoryDatabase masterDb)
|
public static void GrantParts(DarkUserMemoryDatabase userDb, int partsId, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
if (userDb.EntityIUserParts.Any(p => p.PartsId == partsId)) return;
|
if (userDb.EntityIUserParts.Any(p => p.PartsId == partsId)) return;
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ public static class PossessionHelper
|
|||||||
{
|
{
|
||||||
userDb.EntityIUserPartsGroupNote.Add(new EntityIUserPartsGroupNote
|
userDb.EntityIUserPartsGroupNote.Add(new EntityIUserPartsGroupNote
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
PartsGroupId = partsDef.PartsGroupId,
|
PartsGroupId = partsDef.PartsGroupId,
|
||||||
FirstAcquisitionDatetime = nowMs
|
FirstAcquisitionDatetime = nowMs
|
||||||
});
|
});
|
||||||
@@ -157,7 +157,7 @@ public static class PossessionHelper
|
|||||||
|
|
||||||
userDb.EntityIUserParts.Add(new EntityIUserParts
|
userDb.EntityIUserParts.Add(new EntityIUserParts
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserPartsUuid = Guid.NewGuid().ToString(),
|
UserPartsUuid = Guid.NewGuid().ToString(),
|
||||||
PartsId = partsId,
|
PartsId = partsId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ public static class WeaponHelper
|
|||||||
/// Grants a weapon to the user: creates EntityIUserWeapon, EntityIUserWeaponNote (if new),
|
/// Grants a weapon to the user: creates EntityIUserWeapon, EntityIUserWeaponNote (if new),
|
||||||
/// ability/skill slots, and unlocks weapon stories for the ACQUISITION condition.
|
/// ability/skill slots, and unlocks weapon stories for the ACQUISITION condition.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void GrantWeapon(DarkUserMemoryDatabase userDb, long userId, int weaponId, DarkMasterMemoryDatabase masterDb)
|
public static void GrantWeapon(DarkUserMemoryDatabase userDb, int weaponId, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
string uuid = Guid.NewGuid().ToString();
|
string uuid = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
userDb.EntityIUserWeapon.Add(new EntityIUserWeapon
|
userDb.EntityIUserWeapon.Add(new EntityIUserWeapon
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserWeaponUuid = uuid,
|
UserWeaponUuid = uuid,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
Level = 1,
|
Level = 1,
|
||||||
@@ -33,7 +33,7 @@ public static class WeaponHelper
|
|||||||
{
|
{
|
||||||
userDb.EntityIUserWeaponNote.Add(new EntityIUserWeaponNote
|
userDb.EntityIUserWeaponNote.Add(new EntityIUserWeaponNote
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
MaxLevel = 1,
|
MaxLevel = 1,
|
||||||
FirstAcquisitionDatetime = nowMs
|
FirstAcquisitionDatetime = nowMs
|
||||||
@@ -46,11 +46,11 @@ public static class WeaponHelper
|
|||||||
|
|
||||||
// Create one ability slot per entry in the weapon's ability group
|
// Create one ability slot per entry in the weapon's ability group
|
||||||
foreach (EntityMWeaponAbilityGroup ag in masterDb.EntityMWeaponAbilityGroup.Where(g => g.WeaponAbilityGroupId == masterWeapon.WeaponAbilityGroupId))
|
foreach (EntityMWeaponAbilityGroup ag in masterDb.EntityMWeaponAbilityGroup.Where(g => g.WeaponAbilityGroupId == masterWeapon.WeaponAbilityGroupId))
|
||||||
userDb.EntityIUserWeaponAbility.Add(new EntityIUserWeaponAbility { UserId = userId, UserWeaponUuid = uuid, SlotNumber = ag.SlotNumber, Level = 1 });
|
userDb.EntityIUserWeaponAbility.Add(new EntityIUserWeaponAbility { UserId = userDb.UserId, UserWeaponUuid = uuid, SlotNumber = ag.SlotNumber, Level = 1 });
|
||||||
|
|
||||||
// Create one skill slot per entry in the weapon's skill group
|
// Create one skill slot per entry in the weapon's skill group
|
||||||
foreach (EntityMWeaponSkillGroup sg in masterDb.EntityMWeaponSkillGroup.Where(g => g.WeaponSkillGroupId == masterWeapon.WeaponSkillGroupId))
|
foreach (EntityMWeaponSkillGroup sg in masterDb.EntityMWeaponSkillGroup.Where(g => g.WeaponSkillGroupId == masterWeapon.WeaponSkillGroupId))
|
||||||
userDb.EntityIUserWeaponSkill.Add(new EntityIUserWeaponSkill { UserId = userId, UserWeaponUuid = uuid, SlotNumber = sg.SlotNumber, Level = 1 });
|
userDb.EntityIUserWeaponSkill.Add(new EntityIUserWeaponSkill { UserId = userDb.UserId, UserWeaponUuid = uuid, SlotNumber = sg.SlotNumber, Level = 1 });
|
||||||
|
|
||||||
// Unlock weapon stories for ACQUISITION condition
|
// Unlock weapon stories for ACQUISITION condition
|
||||||
if (masterWeapon.WeaponStoryReleaseConditionGroupId != 0)
|
if (masterWeapon.WeaponStoryReleaseConditionGroupId != 0)
|
||||||
@@ -60,17 +60,17 @@ public static class WeaponHelper
|
|||||||
&& c.WeaponStoryReleaseConditionType == WeaponStoryReleaseConditionType.ACQUISITION
|
&& c.WeaponStoryReleaseConditionType == WeaponStoryReleaseConditionType.ACQUISITION
|
||||||
&& c.ConditionValue == 0))
|
&& c.ConditionValue == 0))
|
||||||
{
|
{
|
||||||
GrantWeaponStory(userDb, masterWeapon.WeaponId, condRow.StoryIndex, userId);
|
GrantWeaponStory(userDb, masterWeapon.WeaponId, condRow.StoryIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates or updates a weapon story unlock record.</summary>
|
/// <summary>Creates or updates a weapon story unlock record.</summary>
|
||||||
public static void GrantWeaponStory(DarkUserMemoryDatabase userDb, int weaponId, int storyIndex, long userId)
|
public static void GrantWeaponStory(DarkUserMemoryDatabase userDb, int weaponId, int storyIndex)
|
||||||
{
|
{
|
||||||
EntityIUserWeaponStory? existing = userDb.EntityIUserWeaponStory.FirstOrDefault(s => s.WeaponId == weaponId);
|
EntityIUserWeaponStory? existing = userDb.EntityIUserWeaponStory.FirstOrDefault(s => s.WeaponId == weaponId);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
userDb.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory { UserId = userId, WeaponId = weaponId, ReleasedMaxStoryIndex = storyIndex });
|
userDb.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory { UserId = userDb.UserId, WeaponId = weaponId, ReleasedMaxStoryIndex = storyIndex });
|
||||||
else
|
else
|
||||||
existing.ReleasedMaxStoryIndex = Math.Max(existing.ReleasedMaxStoryIndex, storyIndex);
|
existing.ReleasedMaxStoryIndex = Math.Max(existing.ReleasedMaxStoryIndex, storyIndex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class AutoSaveInterceptor(UserDataStore store, ILogger<AutoSaveIntercepto
|
|||||||
{
|
{
|
||||||
string[] parts = context.Method.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
string[] parts = context.Method.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||||
string methodSuffix = parts.Length >= 2 ? $"{parts[^2]}_{parts[^1]}" : context.Method.TrimStart('/').Replace('/', '_');
|
string methodSuffix = parts.Length >= 2 ? $"{parts[^2]}_{parts[^1]}" : context.Method.TrimStart('/').Replace('/', '_');
|
||||||
_ = Task.Run(() => SaveUser(userId, userDb, methodSuffix));
|
_ = Task.Run(() => SaveUser(userDb, methodSuffix));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@@ -40,20 +40,20 @@ public class AutoSaveInterceptor(UserDataStore store, ILogger<AutoSaveIntercepto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes and writes a user's database to a timestamped JSON file.
|
/// Serializes and writes a user's database to a timestamped JSON file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SaveUser(long userId, DarkUserMemoryDatabase userDb, string methodSuffix)
|
private void SaveUser(DarkUserMemoryDatabase userDb, string methodSuffix)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(SavesDirectory);
|
Directory.CreateDirectory(SavesDirectory);
|
||||||
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss");
|
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss");
|
||||||
string filePath = Path.Combine(SavesDirectory, $"{userId}_{timestamp}_{methodSuffix}.json");
|
string filePath = Path.Combine(SavesDirectory, $"{userDb.UserId}_{timestamp}_{methodSuffix}.json");
|
||||||
string json = JsonSerializer.Serialize(userDb, JsonOptions);
|
string json = JsonSerializer.Serialize(userDb, JsonOptions);
|
||||||
File.WriteAllText(filePath, json);
|
File.WriteAllText(filePath, json);
|
||||||
//logger.LogDebug("Auto-saved user {UserId} to {FilePath}", userId, filePath);
|
//logger.LogDebug("Auto-saved user {UserId} to {FilePath}", userDb.UserId, filePath);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "AutoSaveInterceptor failed to save user {UserId}", userId);
|
logger.LogError(ex, "AutoSaveInterceptor failed to save user {UserId}", userDb.UserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,22 +30,22 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
|
|
||||||
if (bhQuest is not null)
|
if (bhQuest is not null)
|
||||||
{
|
{
|
||||||
HandleBigHuntQuestStart(userDb, userId, bhQuest.QuestId, request.UserDeckNumber, nowMs);
|
HandleBigHuntQuestStart(userDb, bhQuest.QuestId, request.UserDeckNumber, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set progress status
|
// Set progress status
|
||||||
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb, userId);
|
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb);
|
||||||
progress.CurrentBigHuntBossQuestId = request.BigHuntBossQuestId;
|
progress.CurrentBigHuntBossQuestId = request.BigHuntBossQuestId;
|
||||||
progress.CurrentBigHuntQuestId = request.BigHuntQuestId;
|
progress.CurrentBigHuntQuestId = request.BigHuntQuestId;
|
||||||
progress.CurrentQuestSceneId = 0;
|
progress.CurrentQuestSceneId = 0;
|
||||||
progress.IsDryRun = request.IsDryRun;
|
progress.IsDryRun = request.IsDryRun;
|
||||||
|
|
||||||
// Store deck number in server-side session
|
// Store deck number in server-side session
|
||||||
EntitySBigHuntSession session = GetOrCreateSession(userDb, userId);
|
EntitySBigHuntSession session = GetOrCreateSession(userDb);
|
||||||
session.DeckNumber = request.UserDeckNumber;
|
session.DeckNumber = request.UserDeckNumber;
|
||||||
|
|
||||||
// Update per-boss-quest status
|
// Update per-boss-quest status
|
||||||
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, userId, request.BigHuntBossQuestId);
|
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, request.BigHuntBossQuestId);
|
||||||
status.DailyChallengeCount++;
|
status.DailyChallengeCount++;
|
||||||
status.LatestChallengeDatetime = nowMs;
|
status.LatestChallengeDatetime = nowMs;
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
long userId = context.GetUserId();
|
long userId = context.GetUserId();
|
||||||
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
||||||
|
|
||||||
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb, userId);
|
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb);
|
||||||
progress.CurrentQuestSceneId = request.QuestSceneId;
|
progress.CurrentQuestSceneId = request.QuestSceneId;
|
||||||
|
|
||||||
return Task.FromResult(new UpdateBigHuntQuestSceneProgressResponse());
|
return Task.FromResult(new UpdateBigHuntQuestSceneProgressResponse());
|
||||||
@@ -87,11 +87,11 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
|
|
||||||
if (bhQuest is not null)
|
if (bhQuest is not null)
|
||||||
{
|
{
|
||||||
HandleBigHuntQuestFinish(userDb, userId, bhQuest.QuestId, request.IsRetired, nowMs);
|
HandleBigHuntQuestFinish(userDb, bhQuest.QuestId, request.IsRetired, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb, userId);
|
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb);
|
||||||
EntitySBigHuntSession session = GetOrCreateSession(userDb, userId);
|
EntitySBigHuntSession session = GetOrCreateSession(userDb);
|
||||||
|
|
||||||
// Retired or dry run — clear progress and return empty score info.
|
// Retired or dry run — clear progress and return empty score info.
|
||||||
if (request.IsRetired || progress.IsDryRun)
|
if (request.IsRetired || progress.IsDryRun)
|
||||||
@@ -246,7 +246,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
List<(PossessionType Type, int Id, int Count)> newItems = CollectNewRewards(rewardGroupId, oldMaxScore, userScore);
|
List<(PossessionType Type, int Id, int Count)> newItems = CollectNewRewards(rewardGroupId, oldMaxScore, userScore);
|
||||||
foreach ((PossessionType type, int id, int count) in newItems)
|
foreach ((PossessionType type, int id, int count) in newItems)
|
||||||
{
|
{
|
||||||
GrantPossessionViaPossessionHelper(userDb, userId, type, id, count);
|
GrantPossessionViaPossessionHelper(userDb, type, id, count);
|
||||||
scoreRewards.Add(new BigHuntReward
|
scoreRewards.Add(new BigHuntReward
|
||||||
{
|
{
|
||||||
PossessionType = (int)type,
|
PossessionType = (int)type,
|
||||||
@@ -289,19 +289,19 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
EntityMBigHuntQuest? bhQuest = _masterDb.EntityMBigHuntQuest
|
EntityMBigHuntQuest? bhQuest = _masterDb.EntityMBigHuntQuest
|
||||||
.FirstOrDefault(q => q.BigHuntQuestId == request.BigHuntQuestId);
|
.FirstOrDefault(q => q.BigHuntQuestId == request.BigHuntQuestId);
|
||||||
|
|
||||||
EntitySBigHuntSession session = GetOrCreateSession(userDb, userId);
|
EntitySBigHuntSession session = GetOrCreateSession(userDb);
|
||||||
|
|
||||||
if (bhQuest is not null)
|
if (bhQuest is not null)
|
||||||
{
|
{
|
||||||
HandleBigHuntQuestStart(userDb, userId, bhQuest.QuestId, session.DeckNumber, nowMs);
|
HandleBigHuntQuestStart(userDb, bhQuest.QuestId, session.DeckNumber, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset scene progress
|
// Reset scene progress
|
||||||
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb, userId);
|
EntityIUserBigHuntProgressStatus progress = GetOrCreateProgress(userDb);
|
||||||
progress.CurrentQuestSceneId = 0;
|
progress.CurrentQuestSceneId = 0;
|
||||||
|
|
||||||
// Increment daily challenge count
|
// Increment daily challenge count
|
||||||
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, userId, request.BigHuntBossQuestId);
|
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, request.BigHuntBossQuestId);
|
||||||
status.DailyChallengeCount++;
|
status.DailyChallengeCount++;
|
||||||
status.LatestChallengeDatetime = nowMs;
|
status.LatestChallengeDatetime = nowMs;
|
||||||
|
|
||||||
@@ -324,7 +324,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, userId, request.BigHuntBossQuestId);
|
EntityIUserBigHuntStatus status = GetOrCreateStatus(userDb, request.BigHuntBossQuestId);
|
||||||
status.DailyChallengeCount += request.SkipCount;
|
status.DailyChallengeCount += request.SkipCount;
|
||||||
status.LatestChallengeDatetime = nowMs;
|
status.LatestChallengeDatetime = nowMs;
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
long userId = context.GetUserId();
|
long userId = context.GetUserId();
|
||||||
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
DarkUserMemoryDatabase userDb = _store.GetOrCreate(userId);
|
||||||
|
|
||||||
EntitySBigHuntSession session = GetOrCreateSession(userDb, userId);
|
EntitySBigHuntSession session = GetOrCreateSession(userDb);
|
||||||
session.BattleBinary= request.BattleBinary.ToByteArray();
|
session.BattleBinary= request.BattleBinary.ToByteArray();
|
||||||
|
|
||||||
if (request.BigHuntBattleDetail is not null)
|
if (request.BigHuntBattleDetail is not null)
|
||||||
@@ -412,11 +412,11 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
.FirstOrDefault(s => s.BigHuntWeeklyVersion == weeklyVersion);
|
.FirstOrDefault(s => s.BigHuntWeeklyVersion == weeklyVersion);
|
||||||
|
|
||||||
// Resolve current week rewards
|
// Resolve current week rewards
|
||||||
List<BigHuntReward> weeklyRewards = ResolveWeeklyRewards(userDb, userId, weeklyVersion, nowMs);
|
List<BigHuntReward> weeklyRewards = ResolveWeeklyRewards(userDb, weeklyVersion, nowMs);
|
||||||
|
|
||||||
// Resolve last week rewards
|
// Resolve last week rewards
|
||||||
long lastWeekVersion = weeklyVersion - (7L * 24 * 60 * 60 * 1000);
|
long lastWeekVersion = weeklyVersion - (7L * 24 * 60 * 60 * 1000);
|
||||||
List<BigHuntReward> lastWeekRewards = ResolveWeeklyRewards(userDb, userId, lastWeekVersion, nowMs);
|
List<BigHuntReward> lastWeekRewards = ResolveWeeklyRewards(userDb, lastWeekVersion, nowMs);
|
||||||
|
|
||||||
GetBigHuntTopDataResponse response = new()
|
GetBigHuntTopDataResponse response = new()
|
||||||
{
|
{
|
||||||
@@ -434,13 +434,13 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes quest and mission state for the underlying quest, and transitions its state to active.
|
/// Initializes quest and mission state for the underlying quest, and transitions its state to active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleBigHuntQuestStart(DarkUserMemoryDatabase userDb, long userId, int questId, int deckNumber, long nowMs)
|
private void HandleBigHuntQuestStart(DarkUserMemoryDatabase userDb, int questId, int deckNumber, long nowMs)
|
||||||
{
|
{
|
||||||
EntityMQuest? masterQuest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
EntityMQuest? masterQuest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
||||||
|
|
||||||
EntityIUserQuest userQuest = userDb.EntityIUserQuest
|
EntityIUserQuest userQuest = userDb.EntityIUserQuest
|
||||||
.FirstOrDefault(q => q.QuestId == questId)
|
.FirstOrDefault(q => q.QuestId == questId)
|
||||||
?? AddEntity(userDb.EntityIUserQuest, new EntityIUserQuest { UserId = userId, QuestId = questId });
|
?? AddEntity(userDb.EntityIUserQuest, new EntityIUserQuest { UserId = userDb.UserId, QuestId = questId });
|
||||||
|
|
||||||
// Initialize quest missions
|
// Initialize quest missions
|
||||||
if (masterQuest is not null && masterQuest.QuestMissionGroupId != 0)
|
if (masterQuest is not null && masterQuest.QuestMissionGroupId != 0)
|
||||||
@@ -449,7 +449,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
.Where(g => g.QuestMissionGroupId == masterQuest.QuestMissionGroupId))
|
.Where(g => g.QuestMissionGroupId == masterQuest.QuestMissionGroupId))
|
||||||
{
|
{
|
||||||
if (!userDb.EntityIUserQuestMission.Any(m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId))
|
if (!userDb.EntityIUserQuestMission.Any(m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId))
|
||||||
userDb.EntityIUserQuestMission.Add(new EntityIUserQuestMission { UserId = userId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId });
|
userDb.EntityIUserQuestMission.Add(new EntityIUserQuestMission { UserId = userDb.UserId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// Marks the quest cleared, applies first-clear and drop rewards on success,
|
/// Marks the quest cleared, applies first-clear and drop rewards on success,
|
||||||
/// and clears quest missions.
|
/// and clears quest missions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleBigHuntQuestFinish(DarkUserMemoryDatabase userDb, long userId, int questId, bool isRetired, long nowMs)
|
private void HandleBigHuntQuestFinish(DarkUserMemoryDatabase userDb, int questId, bool isRetired, long nowMs)
|
||||||
{
|
{
|
||||||
EntityMQuest? masterQuest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
EntityMQuest? masterQuest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
||||||
EntityIUserQuest? userQuest = userDb.EntityIUserQuest
|
EntityIUserQuest? userQuest = userDb.EntityIUserQuest
|
||||||
@@ -486,7 +486,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
foreach (EntityMQuestFirstClearRewardGroup reward in _masterDb.EntityMQuestFirstClearRewardGroup
|
foreach (EntityMQuestFirstClearRewardGroup reward in _masterDb.EntityMQuestFirstClearRewardGroup
|
||||||
.Where(r => r.QuestFirstClearRewardGroupId == rewardGroupId))
|
.Where(r => r.QuestFirstClearRewardGroupId == rewardGroupId))
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(userDb, userId, reward.PossessionType, reward.PossessionId, reward.Count, _masterDb);
|
PossessionHelper.Apply(userDb, reward.PossessionType, reward.PossessionId, reward.Count, _masterDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +499,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
EntityMBattleDropReward? drop = _masterDb.EntityMBattleDropReward
|
EntityMBattleDropReward? drop = _masterDb.EntityMBattleDropReward
|
||||||
.FirstOrDefault(d => d.BattleDropRewardId == pickup.BattleDropRewardId);
|
.FirstOrDefault(d => d.BattleDropRewardId == pickup.BattleDropRewardId);
|
||||||
if (drop != null)
|
if (drop != null)
|
||||||
PossessionHelper.Apply(userDb, userId, drop.PossessionType, drop.PossessionId, drop.Count, _masterDb);
|
PossessionHelper.Apply(userDb, drop.PossessionType, drop.PossessionId, drop.Count, _masterDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,7 +519,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
.FirstOrDefault(m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId);
|
.FirstOrDefault(m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId);
|
||||||
if (userMission is null)
|
if (userMission is null)
|
||||||
{
|
{
|
||||||
userMission = new EntityIUserQuestMission { UserId = userId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId };
|
userMission = new EntityIUserQuestMission { UserId = userDb.UserId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId };
|
||||||
userDb.EntityIUserQuestMission.Add(userMission);
|
userDb.EntityIUserQuestMission.Add(userMission);
|
||||||
}
|
}
|
||||||
userMission.IsClear = true;
|
userMission.IsClear = true;
|
||||||
@@ -656,7 +656,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// Builds the list of weekly reward items earned across all boss attributes for a given week version,
|
/// Builds the list of weekly reward items earned across all boss attributes for a given week version,
|
||||||
/// based on the player's weekly max scores.
|
/// based on the player's weekly max scores.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<BigHuntReward> ResolveWeeklyRewards(DarkUserMemoryDatabase userDb, long userId, long weeklyVersion, long nowMs)
|
private List<BigHuntReward> ResolveWeeklyRewards(DarkUserMemoryDatabase userDb, long weeklyVersion, long nowMs)
|
||||||
{
|
{
|
||||||
List<BigHuntReward> rewards = [];
|
List<BigHuntReward> rewards = [];
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
}
|
}
|
||||||
|
|
||||||
EntityIUserBigHuntWeeklyMaxScore? ws = userDb.EntityIUserBigHuntWeeklyMaxScore
|
EntityIUserBigHuntWeeklyMaxScore? ws = userDb.EntityIUserBigHuntWeeklyMaxScore
|
||||||
.FirstOrDefault(m => m.UserId == userId
|
.FirstOrDefault(m => m.UserId == userDb.UserId
|
||||||
&& m.BigHuntWeeklyVersion == weeklyVersion
|
&& m.BigHuntWeeklyVersion == weeklyVersion
|
||||||
&& m.AttributeType == boss.AttributeType);
|
&& m.AttributeType == boss.AttributeType);
|
||||||
|
|
||||||
@@ -694,23 +694,23 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or initialises the player's BigHunt in-progress quest status record.
|
/// Gets or initialises the player's BigHunt in-progress quest status record.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static EntityIUserBigHuntProgressStatus GetOrCreateProgress(DarkUserMemoryDatabase userDb, long userId)
|
private static EntityIUserBigHuntProgressStatus GetOrCreateProgress(DarkUserMemoryDatabase userDb)
|
||||||
{
|
{
|
||||||
return userDb.EntityIUserBigHuntProgressStatus
|
return userDb.EntityIUserBigHuntProgressStatus
|
||||||
.FirstOrDefault(p => p.UserId == userId)
|
.FirstOrDefault(p => p.UserId == userDb.UserId)
|
||||||
?? AddEntity(userDb.EntityIUserBigHuntProgressStatus, new EntityIUserBigHuntProgressStatus { UserId = userId });
|
?? AddEntity(userDb.EntityIUserBigHuntProgressStatus, new EntityIUserBigHuntProgressStatus { UserId = userDb.UserId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or initialises the player's per-boss-quest challenge status record.
|
/// Gets or initialises the player's per-boss-quest challenge status record.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static EntityIUserBigHuntStatus GetOrCreateStatus(DarkUserMemoryDatabase userDb, long userId, int bossQuestId)
|
private static EntityIUserBigHuntStatus GetOrCreateStatus(DarkUserMemoryDatabase userDb, int bossQuestId)
|
||||||
{
|
{
|
||||||
return userDb.EntityIUserBigHuntStatus
|
return userDb.EntityIUserBigHuntStatus
|
||||||
.FirstOrDefault(s => s.BigHuntBossQuestId == bossQuestId)
|
.FirstOrDefault(s => s.BigHuntBossQuestId == bossQuestId)
|
||||||
?? AddEntity(userDb.EntityIUserBigHuntStatus, new EntityIUserBigHuntStatus
|
?? AddEntity(userDb.EntityIUserBigHuntStatus, new EntityIUserBigHuntStatus
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
BigHuntBossQuestId = bossQuestId
|
BigHuntBossQuestId = bossQuestId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -718,11 +718,11 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or initialises the player's server-side battle session record.
|
/// Gets or initialises the player's server-side battle session record.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static EntitySBigHuntSession GetOrCreateSession(DarkUserMemoryDatabase userDb, long userId)
|
private static EntitySBigHuntSession GetOrCreateSession(DarkUserMemoryDatabase userDb)
|
||||||
{
|
{
|
||||||
return userDb.EntitySBigHuntSession
|
return userDb.EntitySBigHuntSession
|
||||||
.FirstOrDefault(s => s.UserId == userId)
|
.FirstOrDefault(s => s.UserId == userDb.UserId)
|
||||||
?? AddEntity(userDb.EntitySBigHuntSession, new EntitySBigHuntSession { UserId = userId });
|
?? AddEntity(userDb.EntitySBigHuntSession, new EntitySBigHuntSession { UserId = userDb.UserId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -741,9 +741,9 @@ public class BigHuntService(UserDataStore store, DarkMasterMemoryDatabase master
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Routes possession grants through PossessionHelper.Apply for consistent handling.
|
/// Routes possession grants through PossessionHelper.Apply for consistent handling.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void GrantPossessionViaPossessionHelper(DarkUserMemoryDatabase userDb, long userId, PossessionType possessionType, int possessionId, int count)
|
private void GrantPossessionViaPossessionHelper(DarkUserMemoryDatabase userDb, PossessionType possessionType, int possessionId, int count)
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(userDb, userId, possessionType, possessionId, count, _masterDb);
|
PossessionHelper.Apply(userDb, possessionType, possessionId, count, _masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ────────── Time helpers ──────────
|
// ────────── Time helpers ──────────
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class CageOrnamentService(UserDataStore store, DarkMasterMemoryDatabase m
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PossessionHelper.Apply(userDb, userId, reward.PossessionType, reward.PossessionId, reward.Count, _masterDb);
|
PossessionHelper.Apply(userDb, reward.PossessionType, reward.PossessionId, reward.Count, _masterDb);
|
||||||
|
|
||||||
ReceiveRewardResponse response = new();
|
ReceiveRewardResponse response = new();
|
||||||
response.CageOrnamentReward.Add(new CageOrnamentReward
|
response.CageOrnamentReward.Add(new CageOrnamentReward
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConsumeCosts(userDb, panel);
|
ConsumeCosts(userDb, panel);
|
||||||
SetReleaseBit(userDb, userId, panel);
|
SetReleaseBit(userDb, panel);
|
||||||
ApplyEffects(userDb, userId, panel);
|
ApplyEffects(userDb, panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new ReleasePanelResponse());
|
return Task.FromResult(new ReleasePanelResponse());
|
||||||
@@ -129,7 +129,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sets the release bit for a panel on the user's character board, using bitfield-packed storage (32 panels per field).</summary>
|
/// <summary>Sets the release bit for a panel on the user's character board, using bitfield-packed storage (32 panels per field).</summary>
|
||||||
private static void SetReleaseBit(DarkUserMemoryDatabase userDb, long userId, EntityMCharacterBoardPanel panel)
|
private static void SetReleaseBit(DarkUserMemoryDatabase userDb, EntityMCharacterBoardPanel panel)
|
||||||
{
|
{
|
||||||
int boardId = panel.CharacterBoardId;
|
int boardId = panel.CharacterBoardId;
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
{
|
{
|
||||||
board = new EntityIUserCharacterBoard
|
board = new EntityIUserCharacterBoard
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
CharacterBoardId = boardId
|
CharacterBoardId = boardId
|
||||||
};
|
};
|
||||||
userDb.EntityIUserCharacterBoard.Add(board);
|
userDb.EntityIUserCharacterBoard.Add(board);
|
||||||
@@ -175,7 +175,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Applies the panel's release effects (ability unlocks or stat boosts) to the character.</summary>
|
/// <summary>Applies the panel's release effects (ability unlocks or stat boosts) to the character.</summary>
|
||||||
private void ApplyEffects(DarkUserMemoryDatabase userDb, long userId, EntityMCharacterBoardPanel panel)
|
private void ApplyEffects(DarkUserMemoryDatabase userDb, EntityMCharacterBoardPanel panel)
|
||||||
{
|
{
|
||||||
foreach (EntityMCharacterBoardPanelReleaseEffectGroup eff in _masterDb.EntityMCharacterBoardPanelReleaseEffectGroup)
|
foreach (EntityMCharacterBoardPanelReleaseEffectGroup eff in _masterDb.EntityMCharacterBoardPanelReleaseEffectGroup)
|
||||||
{
|
{
|
||||||
@@ -187,17 +187,17 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
switch (eff.CharacterBoardEffectType)
|
switch (eff.CharacterBoardEffectType)
|
||||||
{
|
{
|
||||||
case CharacterBoardEffectType.ABILITY:
|
case CharacterBoardEffectType.ABILITY:
|
||||||
ApplyAbilityEffect(userDb, userId, eff);
|
ApplyAbilityEffect(userDb, eff);
|
||||||
break;
|
break;
|
||||||
case CharacterBoardEffectType.STATUS_UP:
|
case CharacterBoardEffectType.STATUS_UP:
|
||||||
ApplyStatusUpEffect(userDb, userId, eff);
|
ApplyStatusUpEffect(userDb, eff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Grants or levels up a character ability from a board panel release, capped by the master-defined max level.</summary>
|
/// <summary>Grants or levels up a character ability from a board panel release, capped by the master-defined max level.</summary>
|
||||||
private void ApplyAbilityEffect(DarkUserMemoryDatabase userDb, long userId, EntityMCharacterBoardPanelReleaseEffectGroup eff)
|
private void ApplyAbilityEffect(DarkUserMemoryDatabase userDb, EntityMCharacterBoardPanelReleaseEffectGroup eff)
|
||||||
{
|
{
|
||||||
EntityMCharacterBoardAbility? ability = null;
|
EntityMCharacterBoardAbility? ability = null;
|
||||||
foreach (EntityMCharacterBoardAbility a in _masterDb.EntityMCharacterBoardAbility)
|
foreach (EntityMCharacterBoardAbility a in _masterDb.EntityMCharacterBoardAbility)
|
||||||
@@ -235,7 +235,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
{
|
{
|
||||||
state = new EntityIUserCharacterBoardAbility
|
state = new EntityIUserCharacterBoardAbility
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
CharacterId = characterId,
|
CharacterId = characterId,
|
||||||
AbilityId = ability.AbilityId,
|
AbilityId = ability.AbilityId,
|
||||||
Level = 0
|
Level = 0
|
||||||
@@ -260,7 +260,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Applies a stat increase (HP, ATK, AGI, VIT, CRIT) to a character from a board panel release.</summary>
|
/// <summary>Applies a stat increase (HP, ATK, AGI, VIT, CRIT) to a character from a board panel release.</summary>
|
||||||
private void ApplyStatusUpEffect(DarkUserMemoryDatabase userDb, long userId, EntityMCharacterBoardPanelReleaseEffectGroup eff)
|
private void ApplyStatusUpEffect(DarkUserMemoryDatabase userDb, EntityMCharacterBoardPanelReleaseEffectGroup eff)
|
||||||
{
|
{
|
||||||
EntityMCharacterBoardStatusUp? statusUp = null;
|
EntityMCharacterBoardStatusUp? statusUp = null;
|
||||||
foreach (EntityMCharacterBoardStatusUp s in _masterDb.EntityMCharacterBoardStatusUp)
|
foreach (EntityMCharacterBoardStatusUp s in _masterDb.EntityMCharacterBoardStatusUp)
|
||||||
@@ -300,7 +300,7 @@ public class CharacterBoardService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
{
|
{
|
||||||
state = new EntityIUserCharacterBoardStatusUp
|
state = new EntityIUserCharacterBoardStatusUp
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
CharacterId = characterId,
|
CharacterId = characterId,
|
||||||
StatusCalculationType = calcType
|
StatusCalculationType = calcType
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,14 +70,14 @@ public class ConsumableItemService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
|
|
||||||
if (totalGold > 0)
|
if (totalGold > 0)
|
||||||
{
|
{
|
||||||
AddGold(userDb, userId, totalGold);
|
AddGold(userDb, totalGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new SellResponse());
|
return Task.FromResult(new SellResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds gold (consumable item ID 1) to the user's inventory, creating the entry if needed.</summary>
|
/// <summary>Adds gold (consumable item ID 1) to the user's inventory, creating the entry if needed.</summary>
|
||||||
private void AddGold(DarkUserMemoryDatabase userDb, long userId, int amount)
|
private void AddGold(DarkUserMemoryDatabase userDb, int amount)
|
||||||
{
|
{
|
||||||
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,7 @@ public class ConsumableItemService(DarkMasterMemoryDatabase masterDb, UserDataSt
|
|||||||
|
|
||||||
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
ConsumableItemId = _gameConfig.ConsumableItemIdForGold,
|
ConsumableItemId = _gameConfig.ConsumableItemIdForGold,
|
||||||
Count = amount,
|
Count = amount,
|
||||||
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||||
|
|||||||
@@ -461,12 +461,12 @@ public class CostumeService(DarkMasterMemoryDatabase masterDb, UserDataStore sto
|
|||||||
switch (effect.CostumeAwakenEffectType)
|
switch (effect.CostumeAwakenEffectType)
|
||||||
{
|
{
|
||||||
case CostumeAwakenEffectType.STATUS_UP:
|
case CostumeAwakenEffectType.STATUS_UP:
|
||||||
ApplyAwakenStatusUp(userDb, userId, request.UserCostumeUuid, effect.CostumeAwakenEffectId);
|
ApplyAwakenStatusUp(userDb, request.UserCostumeUuid, effect.CostumeAwakenEffectId);
|
||||||
break;
|
break;
|
||||||
case CostumeAwakenEffectType.ABILITY:
|
case CostumeAwakenEffectType.ABILITY:
|
||||||
break;
|
break;
|
||||||
case CostumeAwakenEffectType.ITEM_ACQUIRE:
|
case CostumeAwakenEffectType.ITEM_ACQUIRE:
|
||||||
ApplyAwakenItemAcquire(userDb, userId, effect.CostumeAwakenEffectId);
|
ApplyAwakenItemAcquire(userDb, effect.CostumeAwakenEffectId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -668,7 +668,7 @@ public class CostumeService(DarkMasterMemoryDatabase masterDb, UserDataStore sto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies awakening stat bonuses (HP, ATK, VIT, AGI, CRIT, etc.) to the costume's awaken status record.
|
/// Applies awakening stat bonuses (HP, ATK, VIT, AGI, CRIT, etc.) to the costume's awaken status record.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ApplyAwakenStatusUp(DarkUserMemoryDatabase userDb, long userId, string userCostumeUuid, int statusUpGroupId)
|
private void ApplyAwakenStatusUp(DarkUserMemoryDatabase userDb, string userCostumeUuid, int statusUpGroupId)
|
||||||
{
|
{
|
||||||
foreach (EntityMCostumeAwakenStatusUpGroup row in _masterDb.EntityMCostumeAwakenStatusUpGroup)
|
foreach (EntityMCostumeAwakenStatusUpGroup row in _masterDb.EntityMCostumeAwakenStatusUpGroup)
|
||||||
{
|
{
|
||||||
@@ -691,7 +691,7 @@ public class CostumeService(DarkMasterMemoryDatabase masterDb, UserDataStore sto
|
|||||||
{
|
{
|
||||||
state = new EntityIUserCostumeAwakenStatusUp
|
state = new EntityIUserCostumeAwakenStatusUp
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserCostumeUuid = userCostumeUuid,
|
UserCostumeUuid = userCostumeUuid,
|
||||||
StatusCalculationType = row.StatusCalculationType,
|
StatusCalculationType = row.StatusCalculationType,
|
||||||
};
|
};
|
||||||
@@ -728,7 +728,7 @@ public class CostumeService(DarkMasterMemoryDatabase masterDb, UserDataStore sto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a thought item as an awakening reward, creating a new inventory entry if not already owned.
|
/// Grants a thought item as an awakening reward, creating a new inventory entry if not already owned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ApplyAwakenItemAcquire(DarkUserMemoryDatabase userDb, long userId, int itemAcquireId)
|
private void ApplyAwakenItemAcquire(DarkUserMemoryDatabase userDb, int itemAcquireId)
|
||||||
{
|
{
|
||||||
EntityMCostumeAwakenItemAcquire? acq = null;
|
EntityMCostumeAwakenItemAcquire? acq = null;
|
||||||
foreach (EntityMCostumeAwakenItemAcquire a in _masterDb.EntityMCostumeAwakenItemAcquire)
|
foreach (EntityMCostumeAwakenItemAcquire a in _masterDb.EntityMCostumeAwakenItemAcquire)
|
||||||
@@ -756,7 +756,7 @@ public class CostumeService(DarkMasterMemoryDatabase masterDb, UserDataStore sto
|
|||||||
|
|
||||||
userDb.EntityIUserThought.Add(new EntityIUserThought
|
userDb.EntityIUserThought.Add(new EntityIUserThought
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
UserThoughtUuid = uuid,
|
UserThoughtUuid = uuid,
|
||||||
ThoughtId = acq.PossessionId,
|
ThoughtId = acq.PossessionId,
|
||||||
AcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
AcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||||||
|
|||||||
@@ -34,14 +34,14 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
|
|
||||||
if (request.Deck != null)
|
if (request.Deck != null)
|
||||||
{
|
{
|
||||||
ApplyDeckReplacement(userDb, userId, (DeckType)request.DeckType, request.UserDeckNumber, request.Deck);
|
ApplyDeckReplacement(userDb, (DeckType)request.DeckType, request.UserDeckNumber, request.Deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new ReplaceDeckResponse());
|
return Task.FromResult(new ReplaceDeckResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates a deck character record from a DeckCharacter slot proto and returns the new UUID.</summary>
|
/// <summary>Creates a deck character record from a DeckCharacter slot proto and returns the new UUID.</summary>
|
||||||
private static string CreateDeckCharacter(DarkUserMemoryDatabase db, long userId, DeckCharacter? slot)
|
private static string CreateDeckCharacter(DarkUserMemoryDatabase db, DeckCharacter? slot)
|
||||||
{
|
{
|
||||||
if (slot is null || string.IsNullOrEmpty(slot.UserCostumeUuid))
|
if (slot is null || string.IsNullOrEmpty(slot.UserCostumeUuid))
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
string newUuid = Guid.NewGuid().ToString();
|
string newUuid = Guid.NewGuid().ToString();
|
||||||
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserCostumeUuid = slot.UserCostumeUuid,
|
UserCostumeUuid = slot.UserCostumeUuid,
|
||||||
MainUserWeaponUuid = slot.MainUserWeaponUuid,
|
MainUserWeaponUuid = slot.MainUserWeaponUuid,
|
||||||
@@ -64,7 +64,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
{
|
{
|
||||||
db.EntityIUserDeckCharacterDressupCostume.Add(new EntityIUserDeckCharacterDressupCostume
|
db.EntityIUserDeckCharacterDressupCostume.Add(new EntityIUserDeckCharacterDressupCostume
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
DressupCostumeId = slot.DressupCostumeId
|
DressupCostumeId = slot.DressupCostumeId
|
||||||
});
|
});
|
||||||
@@ -75,7 +75,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
if (string.IsNullOrEmpty(slot.UserPartsUuid[i])) { continue; }
|
if (string.IsNullOrEmpty(slot.UserPartsUuid[i])) { continue; }
|
||||||
db.EntityIUserDeckPartsGroup.Add(new EntityIUserDeckPartsGroup
|
db.EntityIUserDeckPartsGroup.Add(new EntityIUserDeckPartsGroup
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserPartsUuid = slot.UserPartsUuid[i],
|
UserPartsUuid = slot.UserPartsUuid[i],
|
||||||
SortOrder = i + 1
|
SortOrder = i + 1
|
||||||
@@ -87,7 +87,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
if (string.IsNullOrEmpty(slot.SubUserWeaponUuid[i])) { continue; }
|
if (string.IsNullOrEmpty(slot.SubUserWeaponUuid[i])) { continue; }
|
||||||
db.EntityIUserDeckSubWeaponGroup.Add(new EntityIUserDeckSubWeaponGroup
|
db.EntityIUserDeckSubWeaponGroup.Add(new EntityIUserDeckSubWeaponGroup
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserWeaponUuid = slot.SubUserWeaponUuid[i],
|
UserWeaponUuid = slot.SubUserWeaponUuid[i],
|
||||||
SortOrder = i + 1
|
SortOrder = i + 1
|
||||||
@@ -123,7 +123,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
|
|
||||||
if (request.DeckPower != null)
|
if (request.DeckPower != null)
|
||||||
{
|
{
|
||||||
ApplyDeckPowerRefresh(userDb, userId, (DeckType)request.DeckType, request.UserDeckNumber, request.DeckPower);
|
ApplyDeckPowerRefresh(userDb, (DeckType)request.DeckType, request.UserDeckNumber, request.DeckPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new RefreshDeckPowerResponse());
|
return Task.FromResult(new RefreshDeckPowerResponse());
|
||||||
@@ -148,7 +148,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDeckReplacement(userDb, userId, (DeckType)detail.DeckType, detail.UserDeckNumber, detail.Deck);
|
ApplyDeckReplacement(userDb, (DeckType)detail.DeckType, detail.UserDeckNumber, detail.Deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new ReplaceTripleDeckResponse());
|
return Task.FromResult(new ReplaceTripleDeckResponse());
|
||||||
@@ -167,7 +167,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDeckReplacement(userDb, userId, (DeckType)detail.DeckType, detail.UserDeckNumber, detail.Deck);
|
ApplyDeckReplacement(userDb, (DeckType)detail.DeckType, detail.UserDeckNumber, detail.Deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new ReplaceMultiDeckResponse());
|
return Task.FromResult(new ReplaceMultiDeckResponse());
|
||||||
@@ -186,14 +186,14 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDeckPowerRefresh(userDb, userId, (DeckType)info.DeckType, info.UserDeckNumber, info.DeckPower);
|
ApplyDeckPowerRefresh(userDb, (DeckType)info.DeckType, info.UserDeckNumber, info.DeckPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new RefreshMultiDeckPowerResponse());
|
return Task.FromResult(new RefreshMultiDeckPowerResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes old deck characters and creates new ones from the provided deck proto.</summary>
|
/// <summary>Removes old deck characters and creates new ones from the provided deck proto.</summary>
|
||||||
private static void ApplyDeckReplacement(DarkUserMemoryDatabase userDb, long userId, DeckType deckType, int deckNumber, Deck deck)
|
private static void ApplyDeckReplacement(DarkUserMemoryDatabase userDb, DeckType deckType, int deckNumber, Deck deck)
|
||||||
{
|
{
|
||||||
EntityIUserDeck? existing = userDb.EntityIUserDeck
|
EntityIUserDeck? existing = userDb.EntityIUserDeck
|
||||||
.FirstOrDefault(d => d.DeckType == deckType && d.UserDeckNumber == deckNumber);
|
.FirstOrDefault(d => d.DeckType == deckType && d.UserDeckNumber == deckNumber);
|
||||||
@@ -210,15 +210,15 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
userDb.EntityIUserDeckSubWeaponGroup.RemoveAll(swg => oldUuids.Contains(swg.UserDeckCharacterUuid));
|
userDb.EntityIUserDeckSubWeaponGroup.RemoveAll(swg => oldUuids.Contains(swg.UserDeckCharacterUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
string uuid01 = CreateDeckCharacter(userDb, userId, deck.Character01);
|
string uuid01 = CreateDeckCharacter(userDb, deck.Character01);
|
||||||
string uuid02 = CreateDeckCharacter(userDb, userId, deck.Character02);
|
string uuid02 = CreateDeckCharacter(userDb, deck.Character02);
|
||||||
string uuid03 = CreateDeckCharacter(userDb, userId, deck.Character03);
|
string uuid03 = CreateDeckCharacter(userDb, deck.Character03);
|
||||||
|
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
{
|
{
|
||||||
existing = new EntityIUserDeck
|
existing = new EntityIUserDeck
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
DeckType = deckType,
|
DeckType = deckType,
|
||||||
UserDeckNumber = deckNumber,
|
UserDeckNumber = deckNumber,
|
||||||
Name = $"Loadout {deckNumber}",
|
Name = $"Loadout {deckNumber}",
|
||||||
@@ -233,7 +233,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Updates deck and character power values and tracks max deck power per type.</summary>
|
/// <summary>Updates deck and character power values and tracks max deck power per type.</summary>
|
||||||
private static void ApplyDeckPowerRefresh(DarkUserMemoryDatabase userDb, long userId, DeckType deckType, int deckNumber, DeckPower deckPower)
|
private static void ApplyDeckPowerRefresh(DarkUserMemoryDatabase userDb, DeckType deckType, int deckNumber, DeckPower deckPower)
|
||||||
{
|
{
|
||||||
EntityIUserDeck? deck = userDb.EntityIUserDeck.FirstOrDefault(d =>
|
EntityIUserDeck? deck = userDb.EntityIUserDeck.FirstOrDefault(d =>
|
||||||
d.DeckType == deckType && d.UserDeckNumber == deckNumber);
|
d.DeckType == deckType && d.UserDeckNumber == deckNumber);
|
||||||
@@ -271,7 +271,7 @@ public class DeckService(UserDataStore store) : MariesWonderland.Proto.Deck.Deck
|
|||||||
|
|
||||||
if (note == null)
|
if (note == null)
|
||||||
{
|
{
|
||||||
note = new EntityIUserDeckTypeNote { UserId = userId, DeckType = deckType };
|
note = new EntityIUserDeckTypeNote { UserId = userDb.UserId, DeckType = deckType };
|
||||||
userDb.EntityIUserDeckTypeNote.Add(note);
|
userDb.EntityIUserDeckTypeNote.Add(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
int conversionRate = entry.Medal.ConversionRate > 0 ? entry.Medal.ConversionRate : 1;
|
int conversionRate = entry.Medal.ConversionRate > 0 ? entry.Medal.ConversionRate : 1;
|
||||||
int bookmarkCount = bs.MedalCount * conversionRate;
|
int bookmarkCount = bs.MedalCount * conversionRate;
|
||||||
|
|
||||||
PossessionHelper.Apply(userDb, userId, PossessionType.CONSUMABLE_ITEM, entry.Medal.ConsumableItemId, bookmarkCount, _masterDb);
|
PossessionHelper.Apply(userDb, PossessionType.CONSUMABLE_ITEM, entry.Medal.ConsumableItemId, bookmarkCount, _masterDb);
|
||||||
|
|
||||||
convertedMedal.ConvertedMedalPossession.Add(new ConsumableItemPossession
|
convertedMedal.ConvertedMedalPossession.Add(new ConsumableItemPossession
|
||||||
{
|
{
|
||||||
@@ -162,7 +162,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find or create banner state
|
// Find or create banner state
|
||||||
EntitySGachaBannerState bannerState = GetOrCreateBannerState(userDb, userId, entry.GachaId);
|
EntitySGachaBannerState bannerState = GetOrCreateBannerState(userDb, entry.GachaId);
|
||||||
|
|
||||||
// Draw items based on label type
|
// Draw items based on label type
|
||||||
List<DrawnItem> drawnItems;
|
List<DrawnItem> drawnItems;
|
||||||
@@ -221,7 +221,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
if (isMaterialDraw)
|
if (isMaterialDraw)
|
||||||
{
|
{
|
||||||
// Material draws: grant material and build simple result
|
// Material draws: grant material and build simple result
|
||||||
PossessionHelper.Apply(userDb, userId, (PossessionType)item.PossessionType, item.PossessionId, 1, _masterDb);
|
PossessionHelper.Apply(userDb, (PossessionType)item.PossessionType, item.PossessionId, 1, _masterDb);
|
||||||
bool isNew = !IsOwnedByType(item.PossessionType, item.PossessionId, ownedCostumeIds, ownedWeaponIds, userDb);
|
bool isNew = !IsOwnedByType(item.PossessionType, item.PossessionId, ownedCostumeIds, ownedWeaponIds, userDb);
|
||||||
|
|
||||||
gachaResults.Add(new DrawGachaOddsItem
|
gachaResults.Add(new DrawGachaOddsItem
|
||||||
@@ -259,14 +259,14 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PossessionHelper.GrantCostume(userDb, userId, item.PossessionId, _masterDb);
|
PossessionHelper.GrantCostume(userDb, item.PossessionId, _masterDb);
|
||||||
ownedCostumeIds.Add(item.PossessionId);
|
ownedCostumeIds.Add(item.PossessionId);
|
||||||
|
|
||||||
// Bonus weapon via costume->weapon pairing map
|
// Bonus weapon via costume->weapon pairing map
|
||||||
GachaItem bonusGachaItem = new();
|
GachaItem bonusGachaItem = new();
|
||||||
if (costumeWeaponMap.TryGetValue(item.PossessionId, out int pairedWeaponId) && pairedWeaponId > 0)
|
if (costumeWeaponMap.TryGetValue(item.PossessionId, out int pairedWeaponId) && pairedWeaponId > 0)
|
||||||
{
|
{
|
||||||
WeaponHelper.GrantWeapon(userDb, userId, pairedWeaponId, _masterDb);
|
WeaponHelper.GrantWeapon(userDb, pairedWeaponId, _masterDb);
|
||||||
bonusGachaItem = new GachaItem
|
bonusGachaItem = new GachaItem
|
||||||
{
|
{
|
||||||
PossessionType = (int)PossessionType.WEAPON,
|
PossessionType = (int)PossessionType.WEAPON,
|
||||||
@@ -294,7 +294,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
{
|
{
|
||||||
// Weapon
|
// Weapon
|
||||||
bool isNew = !ownedWeaponIds.Contains(item.PossessionId);
|
bool isNew = !ownedWeaponIds.Contains(item.PossessionId);
|
||||||
WeaponHelper.GrantWeapon(userDb, userId, item.PossessionId, _masterDb);
|
WeaponHelper.GrantWeapon(userDb, item.PossessionId, _masterDb);
|
||||||
ownedWeaponIds.Add(item.PossessionId);
|
ownedWeaponIds.Add(item.PossessionId);
|
||||||
|
|
||||||
gachaResults.Add(new DrawGachaOddsItem
|
gachaResults.Add(new DrawGachaOddsItem
|
||||||
@@ -325,7 +325,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
// Grant medal consumable items (1 per draw)
|
// Grant medal consumable items (1 per draw)
|
||||||
if (entry.Medal != null && medalBonus > 0)
|
if (entry.Medal != null && medalBonus > 0)
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(userDb, userId, PossessionType.CONSUMABLE_ITEM, entry.Medal.ConsumableItemId, medalBonus, _masterDb);
|
PossessionHelper.Apply(userDb, PossessionType.CONSUMABLE_ITEM, entry.Medal.ConsumableItemId, medalBonus, _masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawResponse response = new()
|
DrawResponse response = new()
|
||||||
@@ -361,7 +361,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
return Task.FromResult(new ResetBoxGachaResponse());
|
return Task.FromResult(new ResetBoxGachaResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
EntitySGachaBannerState bannerState = GetOrCreateBannerState(userDb, userId, request.GachaId);
|
EntitySGachaBannerState bannerState = GetOrCreateBannerState(userDb, request.GachaId);
|
||||||
bannerState.BoxDrewCounts = [];
|
bannerState.BoxDrewCounts = [];
|
||||||
bannerState.BoxNumber++;
|
bannerState.BoxNumber++;
|
||||||
|
|
||||||
@@ -459,7 +459,7 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
{
|
{
|
||||||
EntityMMaterial mat = materials[Random.Shared.Next(materials.Count)];
|
EntityMMaterial mat = materials[Random.Shared.Next(materials.Count)];
|
||||||
drawnItems.Add(((int)PossessionType.MATERIAL, mat.MaterialId));
|
drawnItems.Add(((int)PossessionType.MATERIAL, mat.MaterialId));
|
||||||
PossessionHelper.Apply(userDb, userId, PossessionType.MATERIAL, mat.MaterialId, 1, _masterDb);
|
PossessionHelper.Apply(userDb, PossessionType.MATERIAL, mat.MaterialId, 1, _masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
int newCount = currentCount + drawCount;
|
int newCount = currentCount + drawCount;
|
||||||
@@ -1248,14 +1248,14 @@ public class GachaService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EntitySGachaBannerState GetOrCreateBannerState(DarkUserMemoryDatabase userDb, long userId, int gachaId)
|
private static EntitySGachaBannerState GetOrCreateBannerState(DarkUserMemoryDatabase userDb, int gachaId)
|
||||||
{
|
{
|
||||||
EntitySGachaBannerState? bs = FindBannerState(userDb, gachaId);
|
EntitySGachaBannerState? bs = FindBannerState(userDb, gachaId);
|
||||||
if (bs != null) return bs;
|
if (bs != null) return bs;
|
||||||
|
|
||||||
bs = new EntitySGachaBannerState
|
bs = new EntitySGachaBannerState
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
GachaId = gachaId,
|
GachaId = gachaId,
|
||||||
BoxNumber = 1,
|
BoxNumber = 1,
|
||||||
StepNumber = 1
|
StepNumber = 1
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class PartsService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
// Award total gold earned from the sale
|
// Award total gold earned from the sale
|
||||||
if (totalGold > 0)
|
if (totalGold > 0)
|
||||||
{
|
{
|
||||||
AddGold(userDb, userId, totalGold);
|
AddGold(userDb, totalGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new SellResponse());
|
return Task.FromResult(new SellResponse());
|
||||||
@@ -452,7 +452,7 @@ public class PartsService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Credits gold to the user's consumable inventory, creating the inventory entry if one does not yet exist.
|
/// Credits gold to the user's consumable inventory, creating the inventory entry if one does not yet exist.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AddGold(DarkUserMemoryDatabase userDb, long userId, int amount)
|
private void AddGold(DarkUserMemoryDatabase userDb, int amount)
|
||||||
{
|
{
|
||||||
EntityIUserConsumableItem? gold = null;
|
EntityIUserConsumableItem? gold = null;
|
||||||
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
||||||
@@ -472,7 +472,7 @@ public class PartsService(DarkMasterMemoryDatabase masterDb, UserDataStore store
|
|||||||
{
|
{
|
||||||
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
ConsumableItemId = _gameConfig.ConsumableItemIdForGold,
|
ConsumableItemId = _gameConfig.ConsumableItemIdForGold,
|
||||||
Count = amount,
|
Count = amount,
|
||||||
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
EntityIUserPortalCageStatus portalCageStatus = userDb.EntityIUserPortalCageStatus.GetOrCreate(userId);
|
EntityIUserPortalCageStatus portalCageStatus = userDb.EntityIUserPortalCageStatus.GetOrCreate(userId);
|
||||||
portalCageStatus.IsCurrentProgress = false;
|
portalCageStatus.IsCurrentProgress = false;
|
||||||
|
|
||||||
ApplySceneGrants(userDb, questSceneId, userId);
|
ApplySceneGrants(userDb, questSceneId);
|
||||||
|
|
||||||
return Task.FromResult(new UpdateMainFlowSceneProgressResponse());
|
return Task.FromResult(new UpdateMainFlowSceneProgressResponse());
|
||||||
}
|
}
|
||||||
@@ -156,12 +156,12 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
if (IsSceneAhead(questSceneId, progressStatus.HeadQuestSceneId))
|
if (IsSceneAhead(questSceneId, progressStatus.HeadQuestSceneId))
|
||||||
progressStatus.HeadQuestSceneId = questSceneId;
|
progressStatus.HeadQuestSceneId = questSceneId;
|
||||||
|
|
||||||
ApplySceneGrants(userDb, questSceneId, userId);
|
ApplySceneGrants(userDb, questSceneId);
|
||||||
|
|
||||||
EntityMQuestScene? scene = _masterDb.EntityMQuestScene.FirstOrDefault(s => s.QuestSceneId == questSceneId);
|
EntityMQuestScene? scene = _masterDb.EntityMQuestScene.FirstOrDefault(s => s.QuestSceneId == questSceneId);
|
||||||
if (scene != null && scene.QuestResultType == QuestResultType.HALF_RESULT)
|
if (scene != null && scene.QuestResultType == QuestResultType.HALF_RESULT)
|
||||||
{
|
{
|
||||||
ClearQuestMissions(userDb, scene.QuestId, userId, nowMs);
|
ClearQuestMissions(userDb, scene.QuestId, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new UpdateExtraQuestSceneProgressResponse());
|
return Task.FromResult(new UpdateExtraQuestSceneProgressResponse());
|
||||||
@@ -181,12 +181,12 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
if (IsSceneAhead(questSceneId, progressStatus.HeadQuestSceneId))
|
if (IsSceneAhead(questSceneId, progressStatus.HeadQuestSceneId))
|
||||||
progressStatus.HeadQuestSceneId = questSceneId;
|
progressStatus.HeadQuestSceneId = questSceneId;
|
||||||
|
|
||||||
ApplySceneGrants(userDb, questSceneId, userId);
|
ApplySceneGrants(userDb, questSceneId);
|
||||||
|
|
||||||
EntityMQuestScene? scene = _masterDb.EntityMQuestScene.FirstOrDefault(s => s.QuestSceneId == questSceneId);
|
EntityMQuestScene? scene = _masterDb.EntityMQuestScene.FirstOrDefault(s => s.QuestSceneId == questSceneId);
|
||||||
if (scene != null && scene.QuestResultType == QuestResultType.HALF_RESULT)
|
if (scene != null && scene.QuestResultType == QuestResultType.HALF_RESULT)
|
||||||
{
|
{
|
||||||
ClearQuestMissions(userDb, scene.QuestId, userId, nowMs);
|
ClearQuestMissions(userDb, scene.QuestId, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new UpdateEventQuestSceneProgressResponse());
|
return Task.FromResult(new UpdateEventQuestSceneProgressResponse());
|
||||||
@@ -505,14 +505,14 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
{
|
{
|
||||||
if (isFirstClear)
|
if (isFirstClear)
|
||||||
{
|
{
|
||||||
ApplyExpRewards(userDb, quest, userId, questId);
|
ApplyExpRewards(userDb, quest, questId);
|
||||||
ApplyGoldReward(userDb, quest, userId, nowMs);
|
ApplyGoldReward(userDb, quest, nowMs);
|
||||||
ApplyFirstClearPossessions(userDb, firstClearRewardRows, userId, _masterDb);
|
ApplyFirstClearPossessions(userDb, firstClearRewardRows, _masterDb);
|
||||||
ApplyWeaponStoryUnlocks(userDb, questId, userId);
|
ApplyWeaponStoryUnlocks(userDb, questId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDropRewardPossessions(userDb, dropRewards, userId, _masterDb);
|
ApplyDropRewardPossessions(userDb, dropRewards, _masterDb);
|
||||||
ApplyDropRewardPossessions(userDb, replayFlowFirstClearRewards, userId, _masterDb);
|
ApplyDropRewardPossessions(userDb, replayFlowFirstClearRewards, _masterDb);
|
||||||
|
|
||||||
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
||||||
userQuest.ClearCount++;
|
userQuest.ClearCount++;
|
||||||
@@ -546,7 +546,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark all missions as cleared (always)
|
// Mark all missions as cleared (always)
|
||||||
ClearQuestMissions(userDb, questId, userId, nowMs);
|
ClearQuestMissions(userDb, questId, nowMs);
|
||||||
|
|
||||||
// Build response with all reward categories and clean up the server-side quest session
|
// Build response with all reward categories and clean up the server-side quest session
|
||||||
FinishMainQuestResponse response= new() { IsBigWin = isBigWin };
|
FinishMainQuestResponse response= new() { IsBigWin = isBigWin };
|
||||||
@@ -566,7 +566,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Applies user, character, and costume EXP from quest completion. Rental quests skip character/costume EXP.</summary>
|
/// <summary>Applies user, character, and costume EXP from quest completion. Rental quests skip character/costume EXP.</summary>
|
||||||
private void ApplyExpRewards(DarkUserMemoryDatabase userDb, EntityMQuest quest, long userId, int questId)
|
private void ApplyExpRewards(DarkUserMemoryDatabase userDb, EntityMQuest quest, int questId)
|
||||||
{
|
{
|
||||||
// User EXP is always applied regardless of deck.
|
// User EXP is always applied regardless of deck.
|
||||||
EntityIUserStatus? status = userDb.EntityIUserStatus.FirstOrDefault();
|
EntityIUserStatus? status = userDb.EntityIUserStatus.FirstOrDefault();
|
||||||
@@ -675,7 +675,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Clears all quest missions for a given quest, creating any missing records.</summary>
|
/// <summary>Clears all quest missions for a given quest, creating any missing records.</summary>
|
||||||
private void ClearQuestMissions(DarkUserMemoryDatabase userDb, int questId, long userId, long nowMs)
|
private void ClearQuestMissions(DarkUserMemoryDatabase userDb, int questId, long nowMs)
|
||||||
{
|
{
|
||||||
EntityMQuest? quest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
EntityMQuest? quest = _masterDb.EntityMQuest.FirstOrDefault(q => q.QuestId == questId);
|
||||||
if (quest == null || quest.QuestMissionGroupId == 0) return;
|
if (quest == null || quest.QuestMissionGroupId == 0) return;
|
||||||
@@ -685,7 +685,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
{
|
{
|
||||||
EntityIUserQuestMission userMission = userDb.EntityIUserQuestMission.GetOrCreate(
|
EntityIUserQuestMission userMission = userDb.EntityIUserQuestMission.GetOrCreate(
|
||||||
m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId,
|
m => m.QuestId == questId && m.QuestMissionId == missionGroupRow.QuestMissionId,
|
||||||
() => new EntityIUserQuestMission { UserId = userId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId });
|
() => new EntityIUserQuestMission { UserId = userDb.UserId, QuestId = questId, QuestMissionId = missionGroupRow.QuestMissionId });
|
||||||
userMission.IsClear = true;
|
userMission.IsClear = true;
|
||||||
userMission.ProgressValue = 1;
|
userMission.ProgressValue = 1;
|
||||||
userMission.LatestClearDatetime = nowMs;
|
userMission.LatestClearDatetime = nowMs;
|
||||||
@@ -693,44 +693,44 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Grants gold (consumable item ID 1) from quest completion.</summary>
|
/// <summary>Grants gold (consumable item ID 1) from quest completion.</summary>
|
||||||
private static void ApplyGoldReward(DarkUserMemoryDatabase userDb, EntityMQuest quest, long userId, long nowMs)
|
private static void ApplyGoldReward(DarkUserMemoryDatabase userDb, EntityMQuest quest, long nowMs)
|
||||||
{
|
{
|
||||||
if (quest.Gold <= 0) return;
|
if (quest.Gold <= 0) return;
|
||||||
EntityIUserConsumableItem? gold = userDb.EntityIUserConsumableItem.FirstOrDefault(c => c.ConsumableItemId == 1);
|
EntityIUserConsumableItem? gold = userDb.EntityIUserConsumableItem.FirstOrDefault(c => c.ConsumableItemId == 1);
|
||||||
if (gold == null)
|
if (gold == null)
|
||||||
{
|
{
|
||||||
gold = new EntityIUserConsumableItem { UserId = userId, ConsumableItemId = 1, Count = 0, FirstAcquisitionDatetime = nowMs };
|
gold = new EntityIUserConsumableItem { UserId = userDb.UserId, ConsumableItemId = 1, Count = 0, FirstAcquisitionDatetime = nowMs };
|
||||||
userDb.EntityIUserConsumableItem.Add(gold);
|
userDb.EntityIUserConsumableItem.Add(gold);
|
||||||
}
|
}
|
||||||
gold.Count += quest.Gold;
|
gold.Count += quest.Gold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Grants first-clear reward possessions to the user.</summary>
|
/// <summary>Grants first-clear reward possessions to the user.</summary>
|
||||||
private static void ApplyFirstClearPossessions(DarkUserMemoryDatabase userDb, List<EntityMQuestFirstClearRewardGroup> rewardRows, long userId, DarkMasterMemoryDatabase masterDb)
|
private static void ApplyFirstClearPossessions(DarkUserMemoryDatabase userDb, List<EntityMQuestFirstClearRewardGroup> rewardRows, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
foreach (EntityMQuestFirstClearRewardGroup row in rewardRows)
|
foreach (EntityMQuestFirstClearRewardGroup row in rewardRows)
|
||||||
PossessionHelper.Apply(userDb, userId, row.PossessionType, row.PossessionId, row.Count, masterDb);
|
PossessionHelper.Apply(userDb, row.PossessionType, row.PossessionId, row.Count, masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Grants scene-based possessions from master data for the given quest scene.</summary>
|
/// <summary>Grants scene-based possessions from master data for the given quest scene.</summary>
|
||||||
private void ApplySceneGrants(DarkUserMemoryDatabase userDb, int questSceneId, long userId)
|
private void ApplySceneGrants(DarkUserMemoryDatabase userDb, int questSceneId)
|
||||||
{
|
{
|
||||||
List<EntityMUserQuestSceneGrantPossession> grants = [.. _masterDb.EntityMUserQuestSceneGrantPossession
|
List<EntityMUserQuestSceneGrantPossession> grants = [.. _masterDb.EntityMUserQuestSceneGrantPossession
|
||||||
.Where(g => g.QuestSceneId == questSceneId && !g.IsDebug)];
|
.Where(g => g.QuestSceneId == questSceneId && !g.IsDebug)];
|
||||||
|
|
||||||
foreach (EntityMUserQuestSceneGrantPossession grant in grants)
|
foreach (EntityMUserQuestSceneGrantPossession grant in grants)
|
||||||
PossessionHelper.Apply(userDb, userId, grant.PossessionType, grant.PossessionId, grant.Count, _masterDb);
|
PossessionHelper.Apply(userDb, grant.PossessionType, grant.PossessionId, grant.Count, _masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Grants all drop reward possessions from a reward list.</summary>
|
/// <summary>Grants all drop reward possessions from a reward list.</summary>
|
||||||
private static void ApplyDropRewardPossessions(DarkUserMemoryDatabase userDb, List<QuestReward> rewards, long userId, DarkMasterMemoryDatabase masterDb)
|
private static void ApplyDropRewardPossessions(DarkUserMemoryDatabase userDb, List<QuestReward> rewards, DarkMasterMemoryDatabase masterDb)
|
||||||
{
|
{
|
||||||
foreach (QuestReward reward in rewards)
|
foreach (QuestReward reward in rewards)
|
||||||
PossessionHelper.Apply(userDb, userId, (PossessionType)reward.PossessionType, reward.PossessionId, reward.Count, masterDb);
|
PossessionHelper.Apply(userDb, (PossessionType)reward.PossessionType, reward.PossessionId, reward.Count, masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Unlocks weapon stories triggered by QUEST_CLEAR. ACQUISITION unlocks are handled by WeaponHelper.GrantWeapon.</summary>
|
/// <summary>Unlocks weapon stories triggered by QUEST_CLEAR. ACQUISITION unlocks are handled by WeaponHelper.GrantWeapon.</summary>
|
||||||
private void ApplyWeaponStoryUnlocks(DarkUserMemoryDatabase userDb, int questId, long userId)
|
private void ApplyWeaponStoryUnlocks(DarkUserMemoryDatabase userDb, int questId)
|
||||||
{
|
{
|
||||||
IEnumerable<EntityMWeaponStoryReleaseConditionGroup> questClearCondRows = _masterDb.EntityMWeaponStoryReleaseConditionGroup
|
IEnumerable<EntityMWeaponStoryReleaseConditionGroup> questClearCondRows = _masterDb.EntityMWeaponStoryReleaseConditionGroup
|
||||||
.Where(c => c.WeaponStoryReleaseConditionType == WeaponStoryReleaseConditionType.QUEST_CLEAR
|
.Where(c => c.WeaponStoryReleaseConditionType == WeaponStoryReleaseConditionType.QUEST_CLEAR
|
||||||
@@ -740,7 +740,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
EntityMWeapon? masterWeapon = _masterDb.EntityMWeapon
|
EntityMWeapon? masterWeapon = _masterDb.EntityMWeapon
|
||||||
.FirstOrDefault(w => w.WeaponStoryReleaseConditionGroupId == condRow.WeaponStoryReleaseConditionGroupId);
|
.FirstOrDefault(w => w.WeaponStoryReleaseConditionGroupId == condRow.WeaponStoryReleaseConditionGroupId);
|
||||||
if (masterWeapon != null)
|
if (masterWeapon != null)
|
||||||
WeaponHelper.GrantWeaponStory(userDb, masterWeapon.WeaponId, condRow.StoryIndex, userId);
|
WeaponHelper.GrantWeaponStory(userDb, masterWeapon.WeaponId, condRow.StoryIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -962,13 +962,13 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
{
|
{
|
||||||
if (isFirstClear)
|
if (isFirstClear)
|
||||||
{
|
{
|
||||||
ApplyExpRewards(userDb, quest, userId, questId);
|
ApplyExpRewards(userDb, quest, questId);
|
||||||
ApplyGoldReward(userDb, quest, userId, nowMs);
|
ApplyGoldReward(userDb, quest, nowMs);
|
||||||
ApplyFirstClearPossessions(userDb, firstClearRewardRows, userId, _masterDb);
|
ApplyFirstClearPossessions(userDb, firstClearRewardRows, _masterDb);
|
||||||
ApplyWeaponStoryUnlocks(userDb, questId, userId);
|
ApplyWeaponStoryUnlocks(userDb, questId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDropRewardPossessions(userDb, dropRewardsExtra, userId, _masterDb);
|
ApplyDropRewardPossessions(userDb, dropRewardsExtra, _masterDb);
|
||||||
|
|
||||||
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
||||||
userQuest.ClearCount++;
|
userQuest.ClearCount++;
|
||||||
@@ -987,7 +987,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark all missions as cleared (always)
|
// Mark all missions as cleared (always)
|
||||||
ClearQuestMissions(userDb, questId, userId, nowMs);
|
ClearQuestMissions(userDb, questId, nowMs);
|
||||||
|
|
||||||
FinishExtraQuestResponse response= new() { IsBigWin = isBigWin };
|
FinishExtraQuestResponse response= new() { IsBigWin = isBigWin };
|
||||||
response.DropReward.AddRange(dropRewardsExtra);
|
response.DropReward.AddRange(dropRewardsExtra);
|
||||||
@@ -1218,13 +1218,13 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
{
|
{
|
||||||
if (isFirstClear)
|
if (isFirstClear)
|
||||||
{
|
{
|
||||||
ApplyExpRewards(userDb, quest, userId, questId);
|
ApplyExpRewards(userDb, quest, questId);
|
||||||
ApplyGoldReward(userDb, quest, userId, nowMs);
|
ApplyGoldReward(userDb, quest, nowMs);
|
||||||
ApplyFirstClearPossessions(userDb, firstClearRewardRows, userId, _masterDb);
|
ApplyFirstClearPossessions(userDb, firstClearRewardRows, _masterDb);
|
||||||
ApplyWeaponStoryUnlocks(userDb, questId, userId);
|
ApplyWeaponStoryUnlocks(userDb, questId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDropRewardPossessions(userDb, dropRewardsEvent, userId, _masterDb);
|
ApplyDropRewardPossessions(userDb, dropRewardsEvent, _masterDb);
|
||||||
|
|
||||||
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
userQuest.QuestStateType = (int)QuestStateType.CLEARED;
|
||||||
userQuest.ClearCount++;
|
userQuest.ClearCount++;
|
||||||
@@ -1243,7 +1243,7 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark all missions as cleared (always)
|
// Mark all missions as cleared (always)
|
||||||
ClearQuestMissions(userDb, questId, userId, nowMs);
|
ClearQuestMissions(userDb, questId, nowMs);
|
||||||
|
|
||||||
FinishEventQuestResponse response= new() { IsBigWin = isBigWin };
|
FinishEventQuestResponse response= new() { IsBigWin = isBigWin };
|
||||||
response.DropReward.AddRange(dropRewardsEvent);
|
response.DropReward.AddRange(dropRewardsEvent);
|
||||||
@@ -1335,11 +1335,11 @@ public class QuestService(UserDataStore store, DarkMasterMemoryDatabase masterDb
|
|||||||
for (int i = 0; i < request.SkipCount; i++)
|
for (int i = 0; i < request.SkipCount; i++)
|
||||||
{
|
{
|
||||||
List<QuestReward> iterDrops = BuildDropRewards(quest);
|
List<QuestReward> iterDrops = BuildDropRewards(quest);
|
||||||
ApplyDropRewardPossessions(userDb, iterDrops, userId, _masterDb);
|
ApplyDropRewardPossessions(userDb, iterDrops, _masterDb);
|
||||||
dropRewards.AddRange(iterDrops);
|
dropRewards.AddRange(iterDrops);
|
||||||
|
|
||||||
ApplyGoldReward(userDb, quest, userId, nowMs);
|
ApplyGoldReward(userDb, quest, nowMs);
|
||||||
ApplyExpRewards(userDb, quest, userId, questId);
|
ApplyExpRewards(userDb, quest, questId);
|
||||||
}
|
}
|
||||||
|
|
||||||
userQuest.ClearCount += request.SkipCount;
|
userQuest.ClearCount += request.SkipCount;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class RewardService(UserDataStore store, DarkMasterMemoryDatabase masterD
|
|||||||
List<EntityMBigHuntRewardGroup> items = CollectNewRewards(rewardGroupId, 0, maxScore);
|
List<EntityMBigHuntRewardGroup> items = CollectNewRewards(rewardGroupId, 0, maxScore);
|
||||||
foreach (EntityMBigHuntRewardGroup item in items)
|
foreach (EntityMBigHuntRewardGroup item in items)
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(userDb, userId, item.PossessionType, item.PossessionId, item.Count, _masterDb);
|
PossessionHelper.Apply(userDb, item.PossessionType, item.PossessionId, item.Count, _masterDb);
|
||||||
weeklyRewards.Add(new BigHuntReward
|
weeklyRewards.Add(new BigHuntReward
|
||||||
{
|
{
|
||||||
PossessionType = (int)item.PossessionType,
|
PossessionType = (int)item.PossessionType,
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ public class ShopService(UserDataStore store, DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
foreach (EntityMShopItemContentPossession content in contents)
|
foreach (EntityMShopItemContentPossession content in contents)
|
||||||
{
|
{
|
||||||
GrantShopPossession(userDb, userId, content.PossessionType, content.PossessionId, content.Count * qty);
|
GrantShopPossession(userDb, content.PossessionType, content.PossessionId, content.Count * qty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply side effects (e.g., stamina recovery)
|
// Apply side effects (e.g., stamina recovery)
|
||||||
ApplyContentEffects(userDb, shopItemId, qty, userId, nowMs);
|
ApplyContentEffects(userDb, shopItemId, qty, nowMs);
|
||||||
|
|
||||||
// Track purchase count
|
// Track purchase count
|
||||||
EntityIUserShopItem? shopItem = userDb.EntityIUserShopItem.FirstOrDefault(s => s.ShopItemId == shopItemId);
|
EntityIUserShopItem? shopItem = userDb.EntityIUserShopItem.FirstOrDefault(s => s.ShopItemId == shopItemId);
|
||||||
@@ -145,10 +145,10 @@ public class ShopService(UserDataStore store, DarkMasterMemoryDatabase masterDb)
|
|||||||
|
|
||||||
foreach (EntityMShopItemContentPossession content in contents)
|
foreach (EntityMShopItemContentPossession content in contents)
|
||||||
{
|
{
|
||||||
GrantShopPossession(userDb, userId, content.PossessionType, content.PossessionId, content.Count);
|
GrantShopPossession(userDb, content.PossessionType, content.PossessionId, content.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyContentEffects(userDb, request.ShopItemId, 1, userId, nowMs);
|
ApplyContentEffects(userDb, request.ShopItemId, 1, nowMs);
|
||||||
|
|
||||||
EntityIUserShopItem? shopItem = userDb.EntityIUserShopItem.FirstOrDefault(s => s.ShopItemId == request.ShopItemId);
|
EntityIUserShopItem? shopItem = userDb.EntityIUserShopItem.FirstOrDefault(s => s.ShopItemId == request.ShopItemId);
|
||||||
if (shopItem == null)
|
if (shopItem == null)
|
||||||
@@ -226,7 +226,7 @@ public class ShopService(UserDataStore store, DarkMasterMemoryDatabase masterDb)
|
|||||||
/// Grants a shop possession to the user. For costumes already owned, grants duplication
|
/// Grants a shop possession to the user. For costumes already owned, grants duplication
|
||||||
/// exchange items instead. All other types delegate to PossessionHelper.Apply.
|
/// exchange items instead. All other types delegate to PossessionHelper.Apply.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void GrantShopPossession(DarkUserMemoryDatabase userDb, long userId, PossessionType possessionType, int possessionId, int count)
|
private void GrantShopPossession(DarkUserMemoryDatabase userDb, PossessionType possessionType, int possessionId, int count)
|
||||||
{
|
{
|
||||||
if (possessionType is PossessionType.COSTUME or PossessionType.COSTUME_ENHANCED
|
if (possessionType is PossessionType.COSTUME or PossessionType.COSTUME_ENHANCED
|
||||||
&& userDb.EntityIUserCostume.Any(c => c.CostumeId == possessionId))
|
&& userDb.EntityIUserCostume.Any(c => c.CostumeId == possessionId))
|
||||||
@@ -234,21 +234,21 @@ public class ShopService(UserDataStore store, DarkMasterMemoryDatabase masterDb)
|
|||||||
foreach (EntityMCostumeDuplicationExchangePossessionGroup exchange in _masterDb.EntityMCostumeDuplicationExchangePossessionGroup
|
foreach (EntityMCostumeDuplicationExchangePossessionGroup exchange in _masterDb.EntityMCostumeDuplicationExchangePossessionGroup
|
||||||
.Where(e => e.CostumeId == possessionId))
|
.Where(e => e.CostumeId == possessionId))
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(userDb, userId, exchange.PossessionType, exchange.PossessionId, exchange.Count * count, _masterDb);
|
PossessionHelper.Apply(userDb, exchange.PossessionType, exchange.PossessionId, exchange.Count * count, _masterDb);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PossessionHelper.Apply(userDb, userId, possessionType, possessionId, count, _masterDb);
|
PossessionHelper.Apply(userDb, possessionType, possessionId, count, _masterDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Applies side-effect content(e.g., stamina recovery) from a shop item purchase.</summary>
|
/// <summary>Applies side-effect content(e.g., stamina recovery) from a shop item purchase.</summary>
|
||||||
private void ApplyContentEffects(DarkUserMemoryDatabase userDb, int shopItemId, int qty, long userId, long nowMs)
|
private void ApplyContentEffects(DarkUserMemoryDatabase userDb, int shopItemId, int qty, long nowMs)
|
||||||
{
|
{
|
||||||
List<EntityMShopItemContentEffect> effects = [.. _masterDb.EntityMShopItemContentEffect
|
List<EntityMShopItemContentEffect> effects = [.. _masterDb.EntityMShopItemContentEffect
|
||||||
.Where(e => e.ShopItemId == shopItemId)];
|
.Where(e => e.ShopItemId == shopItemId)];
|
||||||
|
|
||||||
EntityIUserStatus? userStatus = userDb.EntityIUserStatus.FirstOrDefault(s => s.UserId == userId);
|
EntityIUserStatus? userStatus = userDb.EntityIUserStatus.FirstOrDefault(s => s.UserId == userDb.UserId);
|
||||||
if (userStatus == null) { return; }
|
if (userStatus == null) { return; }
|
||||||
|
|
||||||
EntityMUserLevel? levelData = _masterDb.EntityMUserLevel.FirstOrDefault(l => l.UserLevel == userStatus.Level);
|
EntityMUserLevel? levelData = _masterDb.EntityMUserLevel.FirstOrDefault(l => l.UserLevel == userStatus.Level);
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
DarkUserMemoryDatabase userDb = store.GetOrCreate(userId);
|
DarkUserMemoryDatabase userDb = store.GetOrCreate(userId);
|
||||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
UpsertTutorialProgress(userDb, userId, (TutorialType)request.TutorialType, request.ProgressPhase, request.ChoiceId);
|
UpsertTutorialProgress(userDb, (TutorialType)request.TutorialType, request.ProgressPhase, request.ChoiceId);
|
||||||
|
|
||||||
if (request.TutorialType == (int)TutorialType.MENU_FIRST ||
|
if (request.TutorialType == (int)TutorialType.MENU_FIRST ||
|
||||||
request.TutorialType == (int)TutorialType.MENU_SECOND)
|
request.TutorialType == (int)TutorialType.MENU_SECOND)
|
||||||
{
|
{
|
||||||
CreateStarterDeck(userDb, userId);
|
CreateStarterDeck(userDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TutorialChoiceReward> rewards = ApplyTutorialRewards(userDb, userId, (TutorialType)request.TutorialType);
|
List<TutorialChoiceReward> rewards = ApplyTutorialRewards(userDb, (TutorialType)request.TutorialType);
|
||||||
|
|
||||||
SetTutorialProgressResponse response = new();
|
SetTutorialProgressResponse response = new();
|
||||||
response.TutorialChoiceReward.AddRange(rewards);
|
response.TutorialChoiceReward.AddRange(rewards);
|
||||||
@@ -39,14 +39,14 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
long userId = context.GetUserId();
|
long userId = context.GetUserId();
|
||||||
DarkUserMemoryDatabase userDb = store.GetOrCreate(userId);
|
DarkUserMemoryDatabase userDb = store.GetOrCreate(userId);
|
||||||
|
|
||||||
UpsertTutorialProgress(userDb, userId, (TutorialType)request.TutorialType, request.ProgressPhase, choiceId: 0);
|
UpsertTutorialProgress(userDb, (TutorialType)request.TutorialType, request.ProgressPhase, choiceId: 0);
|
||||||
UpsertDeck(userDb, userId, request);
|
UpsertDeck(userDb, request);
|
||||||
|
|
||||||
return Task.FromResult(new SetTutorialProgressAndReplaceDeckResponse());
|
return Task.FromResult(new SetTutorialProgressAndReplaceDeckResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates or updates a tutorial progress record, advancing to the specified phase.</summary>
|
/// <summary>Creates or updates a tutorial progress record, advancing to the specified phase.</summary>
|
||||||
private static void UpsertTutorialProgress(DarkUserMemoryDatabase db, long userId, TutorialType type, int phase, int choiceId)
|
private static void UpsertTutorialProgress(DarkUserMemoryDatabase db, TutorialType type, int phase, int choiceId)
|
||||||
{
|
{
|
||||||
EntityIUserTutorialProgress? existing = db.EntityIUserTutorialProgress
|
EntityIUserTutorialProgress? existing = db.EntityIUserTutorialProgress
|
||||||
.FirstOrDefault(t => t.TutorialType == type);
|
.FirstOrDefault(t => t.TutorialType == type);
|
||||||
@@ -55,7 +55,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
{
|
{
|
||||||
db.EntityIUserTutorialProgress.Add(new EntityIUserTutorialProgress
|
db.EntityIUserTutorialProgress.Add(new EntityIUserTutorialProgress
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
TutorialType = type,
|
TutorialType = type,
|
||||||
ProgressPhase = phase,
|
ProgressPhase = phase,
|
||||||
ChoiceId = choiceId
|
ChoiceId = choiceId
|
||||||
@@ -76,7 +76,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
/// owned costume/weapon/companion. Only runs when no deck 1 character slot exists yet.
|
/// owned costume/weapon/companion. Only runs when no deck 1 character slot exists yet.
|
||||||
/// Idempotent: safe to call multiple times.
|
/// Idempotent: safe to call multiple times.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void CreateStarterDeck(DarkUserMemoryDatabase db, long userId)
|
private static void CreateStarterDeck(DarkUserMemoryDatabase db)
|
||||||
{
|
{
|
||||||
if (db.EntityIUserCostume.Count == 0)
|
if (db.EntityIUserCostume.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
|
|
||||||
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = dcUuid,
|
UserDeckCharacterUuid = dcUuid,
|
||||||
UserCostumeUuid = costumeUuid,
|
UserCostumeUuid = costumeUuid,
|
||||||
MainUserWeaponUuid = weaponUuid,
|
MainUserWeaponUuid = weaponUuid,
|
||||||
@@ -117,9 +117,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
{
|
{
|
||||||
db.EntityIUserDeck.Add(new EntityIUserDeck
|
db.EntityIUserDeck.Add(new EntityIUserDeck
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
DeckType = DeckType.QUEST,
|
|
||||||
UserDeckNumber = 1,
|
|
||||||
UserDeckCharacterUuid01 = dcUuid,
|
UserDeckCharacterUuid01 = dcUuid,
|
||||||
Name = "Loadout 1",
|
Name = "Loadout 1",
|
||||||
Power = 0
|
Power = 0
|
||||||
@@ -137,7 +135,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
{
|
{
|
||||||
db.EntityIUserDeckTypeNote.Add(new EntityIUserDeckTypeNote
|
db.EntityIUserDeckTypeNote.Add(new EntityIUserDeckTypeNote
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
DeckType = DeckType.QUEST,
|
DeckType = DeckType.QUEST,
|
||||||
MaxDeckPower = 0
|
MaxDeckPower = 0
|
||||||
});
|
});
|
||||||
@@ -149,7 +147,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
/// Removes existing EntityIUserDeckCharacter records for the deck, creates fresh ones with new
|
/// Removes existing EntityIUserDeckCharacter records for the deck, creates fresh ones with new
|
||||||
/// UUIDs, and updates EntityIUserDeck to reference the newly generated character UUIDs.
|
/// UUIDs, and updates EntityIUserDeck to reference the newly generated character UUIDs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void UpsertDeck(DarkUserMemoryDatabase db, long userId, SetTutorialProgressAndReplaceDeckRequest request)
|
private static void UpsertDeck(DarkUserMemoryDatabase db, SetTutorialProgressAndReplaceDeckRequest request)
|
||||||
{
|
{
|
||||||
DeckType deckType = (DeckType)request.DeckType;
|
DeckType deckType = (DeckType)request.DeckType;
|
||||||
|
|
||||||
@@ -168,15 +166,15 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
db.EntityIUserDeckSubWeaponGroup.RemoveAll(swg => oldUuids.Contains(swg.UserDeckCharacterUuid));
|
db.EntityIUserDeckSubWeaponGroup.RemoveAll(swg => oldUuids.Contains(swg.UserDeckCharacterUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
string uuid01 = CreateDeckCharacter(db, userId, request.Deck?.Character01);
|
string uuid01 = CreateDeckCharacter(db, request.Deck?.Character01);
|
||||||
string uuid02 = CreateDeckCharacter(db, userId, request.Deck?.Character02);
|
string uuid02 = CreateDeckCharacter(db, request.Deck?.Character02);
|
||||||
string uuid03 = CreateDeckCharacter(db, userId, request.Deck?.Character03);
|
string uuid03 = CreateDeckCharacter(db, request.Deck?.Character03);
|
||||||
|
|
||||||
if (existing is null)
|
if (existing is null)
|
||||||
{
|
{
|
||||||
db.EntityIUserDeck.Add(new EntityIUserDeck
|
db.EntityIUserDeck.Add(new EntityIUserDeck
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
DeckType = deckType,
|
DeckType = deckType,
|
||||||
UserDeckNumber = request.UserDeckNumber,
|
UserDeckNumber = request.UserDeckNumber,
|
||||||
UserDeckCharacterUuid01 = uuid01,
|
UserDeckCharacterUuid01 = uuid01,
|
||||||
@@ -195,7 +193,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates a deck character record from a DeckCharacter slot proto and returns the new UUID.</summary>
|
/// <summary>Creates a deck character record from a DeckCharacter slot proto and returns the new UUID.</summary>
|
||||||
private static string CreateDeckCharacter(DarkUserMemoryDatabase db, long userId, DeckCharacter? slot)
|
private static string CreateDeckCharacter(DarkUserMemoryDatabase db, DeckCharacter? slot)
|
||||||
{
|
{
|
||||||
if (slot is null || string.IsNullOrEmpty(slot.UserCostumeUuid))
|
if (slot is null || string.IsNullOrEmpty(slot.UserCostumeUuid))
|
||||||
{
|
{
|
||||||
@@ -205,7 +203,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
string newUuid = Guid.NewGuid().ToString();
|
string newUuid = Guid.NewGuid().ToString();
|
||||||
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
db.EntityIUserDeckCharacter.Add(new EntityIUserDeckCharacter
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserCostumeUuid = slot.UserCostumeUuid,
|
UserCostumeUuid = slot.UserCostumeUuid,
|
||||||
MainUserWeaponUuid = slot.MainUserWeaponUuid,
|
MainUserWeaponUuid = slot.MainUserWeaponUuid,
|
||||||
@@ -218,7 +216,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
{
|
{
|
||||||
db.EntityIUserDeckCharacterDressupCostume.Add(new EntityIUserDeckCharacterDressupCostume
|
db.EntityIUserDeckCharacterDressupCostume.Add(new EntityIUserDeckCharacterDressupCostume
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
DressupCostumeId = slot.DressupCostumeId
|
DressupCostumeId = slot.DressupCostumeId
|
||||||
});
|
});
|
||||||
@@ -229,7 +227,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
if (string.IsNullOrEmpty(slot.UserPartsUuid[i])) { continue; }
|
if (string.IsNullOrEmpty(slot.UserPartsUuid[i])) { continue; }
|
||||||
db.EntityIUserDeckPartsGroup.Add(new EntityIUserDeckPartsGroup
|
db.EntityIUserDeckPartsGroup.Add(new EntityIUserDeckPartsGroup
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserPartsUuid = slot.UserPartsUuid[i],
|
UserPartsUuid = slot.UserPartsUuid[i],
|
||||||
SortOrder = i + 1
|
SortOrder = i + 1
|
||||||
@@ -241,7 +239,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
if (string.IsNullOrEmpty(slot.SubUserWeaponUuid[i])) { continue; }
|
if (string.IsNullOrEmpty(slot.SubUserWeaponUuid[i])) { continue; }
|
||||||
db.EntityIUserDeckSubWeaponGroup.Add(new EntityIUserDeckSubWeaponGroup
|
db.EntityIUserDeckSubWeaponGroup.Add(new EntityIUserDeckSubWeaponGroup
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = db.UserId,
|
||||||
UserDeckCharacterUuid = newUuid,
|
UserDeckCharacterUuid = newUuid,
|
||||||
UserWeaponUuid = slot.SubUserWeaponUuid[i],
|
UserWeaponUuid = slot.SubUserWeaponUuid[i],
|
||||||
SortOrder = i + 1
|
SortOrder = i + 1
|
||||||
@@ -255,7 +253,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
/// Grants tutorial rewards from master data keyed by tutorial type and returns the reward list
|
/// Grants tutorial rewards from master data keyed by tutorial type and returns the reward list
|
||||||
/// for the response. Each tutorial type may grant companions, gems, items, or other possessions.
|
/// for the response. Each tutorial type may grant companions, gems, items, or other possessions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<TutorialChoiceReward> ApplyTutorialRewards(DarkUserMemoryDatabase db, long userId, TutorialType tutorialType)
|
private List<TutorialChoiceReward> ApplyTutorialRewards(DarkUserMemoryDatabase db, TutorialType tutorialType)
|
||||||
{
|
{
|
||||||
List<EntityMTutorialConsumePossessionGroup> rewardRows = [.. masterDb.EntityMTutorialConsumePossessionGroup
|
List<EntityMTutorialConsumePossessionGroup> rewardRows = [.. masterDb.EntityMTutorialConsumePossessionGroup
|
||||||
.Where(r => r.TutorialType == tutorialType)];
|
.Where(r => r.TutorialType == tutorialType)];
|
||||||
@@ -264,7 +262,7 @@ public class TutorialService(UserDataStore store, DarkMasterMemoryDatabase maste
|
|||||||
|
|
||||||
foreach (EntityMTutorialConsumePossessionGroup row in rewardRows)
|
foreach (EntityMTutorialConsumePossessionGroup row in rewardRows)
|
||||||
{
|
{
|
||||||
PossessionHelper.Apply(db, userId, row.PossessionType, row.PossessionId, row.Count, masterDb);
|
PossessionHelper.Apply(db, row.PossessionType, row.PossessionId, row.Count, masterDb);
|
||||||
|
|
||||||
result.Add(new TutorialChoiceReward
|
result.Add(new TutorialChoiceReward
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
{
|
{
|
||||||
if (exchange.WeaponId == weapon.WeaponId)
|
if (exchange.WeaponId == weapon.WeaponId)
|
||||||
{
|
{
|
||||||
AddConsumableItem(userDb, userId, exchange.ConsumableItemId, exchange.Count);
|
AddConsumableItem(userDb, exchange.ConsumableItemId, exchange.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
|
|
||||||
if (totalGold > 0)
|
if (totalGold > 0)
|
||||||
{
|
{
|
||||||
AddConsumableItem(userDb, userId, _gameConfig.ConsumableItemIdForGold, totalGold);
|
AddConsumableItem(userDb, _gameConfig.ConsumableItemIdForGold, totalGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(new SellResponse());
|
return Task.FromResult(new SellResponse());
|
||||||
@@ -186,7 +186,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
weapon.Exp += totalExp;
|
weapon.Exp += totalExp;
|
||||||
ApplyLevelFromExp(weapon, wm);
|
ApplyLevelFromExp(weapon, wm);
|
||||||
|
|
||||||
CheckWeaponStoryUnlocks(userDb, userId, weapon.WeaponId, weapon.Level);
|
CheckWeaponStoryUnlocks(userDb, weapon.WeaponId, weapon.Level);
|
||||||
|
|
||||||
return Task.FromResult(new EnhanceByMaterialResponse{ IsGreatSuccess = false });
|
return Task.FromResult(new EnhanceByMaterialResponse{ IsGreatSuccess = false });
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
{
|
{
|
||||||
if (exchange.WeaponId == matWeapon.WeaponId)
|
if (exchange.WeaponId == matWeapon.WeaponId)
|
||||||
{
|
{
|
||||||
AddConsumableItem(userDb, userId, exchange.ConsumableItemId, exchange.Count);
|
AddConsumableItem(userDb, exchange.ConsumableItemId, exchange.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
weapon.Exp += totalExp;
|
weapon.Exp += totalExp;
|
||||||
ApplyLevelFromExp(weapon, wm);
|
ApplyLevelFromExp(weapon, wm);
|
||||||
|
|
||||||
CheckWeaponStoryUnlocks(userDb, userId, weapon.WeaponId, weapon.Level);
|
CheckWeaponStoryUnlocks(userDb, weapon.WeaponId, weapon.Level);
|
||||||
|
|
||||||
return Task.FromResult(new EnhanceByWeaponResponse{ IsGreatSuccess = false });
|
return Task.FromResult(new EnhanceByWeaponResponse{ IsGreatSuccess = false });
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
weapon.LimitBreakCount += totalMaterialCount;
|
weapon.LimitBreakCount += totalMaterialCount;
|
||||||
|
|
||||||
// Track the highest limit break count in the weapon note
|
// Track the highest limit break count in the weapon note
|
||||||
UpdateWeaponNote(userDb, userId, weapon);
|
UpdateWeaponNote(userDb, weapon);
|
||||||
|
|
||||||
return Task.FromResult(new LimitBreakByMaterialResponse());
|
return Task.FromResult(new LimitBreakByMaterialResponse());
|
||||||
}
|
}
|
||||||
@@ -583,7 +583,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
{
|
{
|
||||||
if (exchange.WeaponId == matWeapon.WeaponId)
|
if (exchange.WeaponId == matWeapon.WeaponId)
|
||||||
{
|
{
|
||||||
AddConsumableItem(userDb, userId, exchange.ConsumableItemId, exchange.Count);
|
AddConsumableItem(userDb, exchange.ConsumableItemId, exchange.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,7 +609,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
weapon.LimitBreakCount += consumedCount;
|
weapon.LimitBreakCount += consumedCount;
|
||||||
|
|
||||||
// Track the highest limit break count in the weapon note
|
// Track the highest limit break count in the weapon note
|
||||||
UpdateWeaponNote(userDb, userId, weapon);
|
UpdateWeaponNote(userDb, weapon);
|
||||||
|
|
||||||
return Task.FromResult(new LimitBreakByWeaponResponse());
|
return Task.FromResult(new LimitBreakByWeaponResponse());
|
||||||
}
|
}
|
||||||
@@ -712,7 +712,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the evolution unlocks new weapon story pages
|
// Check if the evolution unlocks new weapon story pages
|
||||||
CheckWeaponStoryUnlocks(userDb, userId, evolvedId, weapon.Level);
|
CheckWeaponStoryUnlocks(userDb, evolvedId, weapon.Level);
|
||||||
|
|
||||||
return Task.FromResult(new EvolveResponse());
|
return Task.FromResult(new EvolveResponse());
|
||||||
}
|
}
|
||||||
@@ -883,7 +883,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grants a consumable item to the user, creating the inventory entry if it doesn't exist yet.
|
/// Grants a consumable item to the user, creating the inventory entry if it doesn't exist yet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void AddConsumableItem(DarkUserMemoryDatabase userDb, long userId, int itemId, int count)
|
private static void AddConsumableItem(DarkUserMemoryDatabase userDb, int itemId, int count)
|
||||||
{
|
{
|
||||||
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
foreach (EntityIUserConsumableItem ci in userDb.EntityIUserConsumableItem)
|
||||||
{
|
{
|
||||||
@@ -896,7 +896,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
|
|
||||||
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
userDb.EntityIUserConsumableItem.Add(new EntityIUserConsumableItem
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
ConsumableItemId = itemId,
|
ConsumableItemId = itemId,
|
||||||
Count = count,
|
Count = count,
|
||||||
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
FirstAcquisitionDatetime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||||
@@ -992,7 +992,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the weapon note to track the highest limit break count ever achieved for this weapon.
|
/// Updates the weapon note to track the highest limit break count ever achieved for this weapon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void UpdateWeaponNote(DarkUserMemoryDatabase userDb, long userId, EntityIUserWeapon weapon)
|
private static void UpdateWeaponNote(DarkUserMemoryDatabase userDb, EntityIUserWeapon weapon)
|
||||||
{
|
{
|
||||||
EntityIUserWeaponNote? note = null;
|
EntityIUserWeaponNote? note = null;
|
||||||
foreach (EntityIUserWeaponNote n in userDb.EntityIUserWeaponNote)
|
foreach (EntityIUserWeaponNote n in userDb.EntityIUserWeaponNote)
|
||||||
@@ -1016,7 +1016,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Evaluates weapon story release conditions and unlocks story pages when conditions are met (level reached, evolution, acquisition, etc.).
|
/// Evaluates weapon story release conditions and unlocks story pages when conditions are met (level reached, evolution, acquisition, etc.).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CheckWeaponStoryUnlocks(DarkUserMemoryDatabase userDb, long userId, int weaponId, int level)
|
private void CheckWeaponStoryUnlocks(DarkUserMemoryDatabase userDb, int weaponId, int level)
|
||||||
{
|
{
|
||||||
EntityMWeapon? wm = FindWeaponMaster(weaponId);
|
EntityMWeapon? wm = FindWeaponMaster(weaponId);
|
||||||
if (wm == null || wm.WeaponStoryReleaseConditionGroupId == 0)
|
if (wm == null || wm.WeaponStoryReleaseConditionGroupId == 0)
|
||||||
@@ -1057,7 +1057,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
|
|
||||||
if (shouldUnlock)
|
if (shouldUnlock)
|
||||||
{
|
{
|
||||||
GrantWeaponStoryUnlock(userDb, userId, weaponId, cond.StoryIndex);
|
GrantWeaponStoryUnlock(userDb, weaponId, cond.StoryIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1086,7 +1086,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unlocks a weapon story page, creating the story record if new or advancing the max released story index.
|
/// Unlocks a weapon story page, creating the story record if new or advancing the max released story index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void GrantWeaponStoryUnlock(DarkUserMemoryDatabase userDb, long userId, int weaponId, int storyIndex)
|
private static void GrantWeaponStoryUnlock(DarkUserMemoryDatabase userDb, int weaponId, int storyIndex)
|
||||||
{
|
{
|
||||||
EntityIUserWeaponStory? existing = null;
|
EntityIUserWeaponStory? existing = null;
|
||||||
foreach (EntityIUserWeaponStory ws in userDb.EntityIUserWeaponStory)
|
foreach (EntityIUserWeaponStory ws in userDb.EntityIUserWeaponStory)
|
||||||
@@ -1109,7 +1109,7 @@ public class WeaponService(DarkMasterMemoryDatabase masterDb, UserDataStore stor
|
|||||||
{
|
{
|
||||||
userDb.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory
|
userDb.EntityIUserWeaponStory.Add(new EntityIUserWeaponStory
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userDb.UserId,
|
||||||
WeaponId = weaponId,
|
WeaponId = weaponId,
|
||||||
ReleasedMaxStoryIndex = storyIndex
|
ReleasedMaxStoryIndex = storyIndex
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user