using CodeStage.AntiCheat.ObscuredTypes; using System; using System.Collections.Generic; using System.Linq; using static UnityEditor.Progress; #region 게임 최초 실행 시 서버 정보 [Serializable] public class SC_ServerStatus { public int ContentsLock; public string URL_ChatServer, URL_LogServer, URL_CouponServer, HotTime; public DateTime HotTimeStart, HotTimeEnd; } [Serializable] public class SC_Version { public string Version, VersionStatus; } #endregion public class ServerData { // 데이터 정의 public DateTime LastTime; public ObscuredInt _pcid; public int PCID { get { return _pcid; } set { _pcid = value; _pcid.RandomizeCryptoKey(); } } public Dictionary dic_PC = new Dictionary(); // pcid // pcid, awaken id public Dictionary> dic_PC_Awakening = new Dictionary>(); public SD_Seal Seal = new SD_Seal(); public SD_Equipment Equipment = new SD_Equipment(); public Dictionary dic_Item = new Dictionary(); // itemid public Dictionary dic_Card = new Dictionary(); // cardid #region 최초 생성 public ServerData() { LastTime = ServerInfo.ServerTime; PCID = table_pclist.Ins.Get_DataList()[0].n_ID; Add_PC(PCID); } #endregion #region PC public bool IsObtainPC(int id) { return dic_PC.ContainsKey(id); } public int Get_PCLv(int id) { return IsObtainPC(id) ? dic_PC[id].Lv : 0; } public int Get_SelectPCLv() { return IsObtainPC(PCID) ? dic_PC[PCID].Lv : 0; } public void Set_SelectPC(int id) { PCID = id; ServerInfo.Ins.Save(); } void Add_PC(int id) { if (!IsObtainPC(id)) { dic_PC.Add(id, new SD_PC()); ServerInfo.Ins.Save(); } } #endregion #region PC 각성 public int Get_PCAwakenLv(int pcid, int awakeid) { return dic_PC_Awakening.ContainsKey(pcid) ? dic_PC_Awakening[pcid].ContainsKey(awakeid) ? dic_PC_Awakening[pcid][awakeid].Lv : 0 : 0; } public int Get_PCAwakenLv(int awakeid) { foreach (var item in dic_PC_Awakening) { foreach (var item2 in item.Value) { if (item2.Key == awakeid) return item2.Value.Lv; } } return 0; } public void Add_PCAwakenLv(int pcid, int awakeid) { if (!dic_PC_Awakening.ContainsKey(pcid)) dic_PC_Awakening.Add(pcid, new Dictionary()); if (!dic_PC_Awakening[pcid].ContainsKey(awakeid)) dic_PC_Awakening[pcid].Add(awakeid, new SD_PC_Awakening()); ++dic_PC_Awakening[pcid][awakeid].Lv; ServerInfo.Ins.Save(); } #endregion #region PC 진화 public int Get_PCEvolution(int id) { return dic_PC.ContainsKey(id) ? dic_PC[id].Evolution : 0; } public void Add_PCEvolution(int id) { if (dic_PC.ContainsKey(id)) ++dic_PC[id].Evolution; ServerInfo.Ins.Save(); } public int Get_PCEvolutionTestClear(int id) { return dic_PC.ContainsKey(id) ? dic_PC[id].EvolutionTestClear : 0; } public void Add_PCEvolutionTestClear(int id) { if (dic_PC.ContainsKey(id)) ++dic_PC[id].EvolutionTestClear; ServerInfo.Ins.Save(); } #endregion #region PC 한계돌파 public int Get_PCEvolutionMax(int id, eStat stat) { return dic_PC.ContainsKey(id) ? dic_PC[id].Get_EvolutionMax(stat) : 0; } public void Add_PCEvolutionMax(int id, eStat stat) { if (dic_PC.ContainsKey(id)) { dic_PC[id].Add_EvolutionMax(stat); ServerInfo.Ins.Save(); } } #endregion #region PC 인장 public List Get_EquipSeals(int pcid) { return dic_PC.ContainsKey(pcid) ? dic_PC[pcid].list_equipseal : null; } public void Set_EquipSeal(int pcid, int slot, uint sealid = 0) { if (dic_PC.ContainsKey(pcid)) { dic_PC[pcid].list_equipseal[slot] = sealid; ServerInfo.Ins.Save(); } } public void Set_UnEqiupSeal(int pcid, uint sealid) { for (int i = 0; i < dic_PC[pcid].list_equipseal.Count; i++) { if (dic_PC[pcid].list_equipseal[i] == sealid) { dic_PC[pcid].list_equipseal[i] = 0; break; } } ServerInfo.Ins.Save(); } public void Add_Seal(int sealtableid) { Seal.list_Seal.Add(new SD_SealData { ID = Seal.Get_Init_ID(), TableID = sealtableid, Lv = 1 }); ServerInfo.Ins.Save(); } public int Get_SameSealCount(SD_SealData data) { var count = 0; for (int i = 0; i < Seal.list_Seal.Count; i++) { var temp = Seal.list_Seal[i]; if (temp.TableID == data.TableID && temp.Lv == data.Lv && !isEquipSeal(temp.ID)) ++count; } return count; } public bool isEquipSeal(uint sealid) { foreach (var pc in dic_PC.Values) { for (int i = 0; i < pc.list_equipseal.Count; i++) { if (pc.list_equipseal[i] == sealid) return true; } } return false; } public int CanEquipSeal(int pcid, uint sealid, eElement element) { var equippcid = MyValue.sdata.Get_EquipSealPCID(sealid); if (equippcid > 0 && equippcid == pcid) return -1; // 선택한 PC가 착용중 // 착용하고자 하는 슬롯이 잠겨 있거나, 인장과 같은 속성의 슬롯이 다 찼으면 장착 불가 if (MyValue.sdata.Get_CanEquipSealSlotIndex(pcid, element) < 0) return -3; var pcTdata = table_pclist.Ins.Get_Data_orNull(pcid); if (!pcTdata.list_element.Contains(element)) return -2; // 선택한 PC가 착용할 수 없는 속성 if (equippcid > 0 && equippcid != pcid) return 1; // 다른 캐릭터가 장착하고 있음 return 0; // 착용 가능 } public int Get_EquipSealPCID(uint sealid) { foreach (var pc in dic_PC) { for (int i = 0; i < pc.Value.list_equipseal.Count; i++) { if (pc.Value.list_equipseal[i] == sealid) return pc.Key; } } return 0; } public int Get_CanEquipSealSlotIndex(int pcid, eElement element) { if (dic_PC.ContainsKey(pcid)) { var slots = dic_PC[pcid].list_equipseal; var pcTdata = table_pclist.Ins.Get_Data_orNull(pcid); var alv = Get_PCAwakenLv(pcid); for (int i = 0; i < pcTdata.list_slotelement.Count; i++) { var temp = pcTdata.list_slotelement[i]; if (temp == element) { if (slots[i] == 0 && alv >= i) // 잠기지 않은 빈 슬롯 return i; } } } return -1; } public SD_SealData Get_SealData(uint sealid) { return Seal.list_Seal.Find(f=>f.ID == sealid); } public void Mix_Seal(SD_SealData data) { // 1) 장착된 인장은 합성 불가 if (isEquipSeal(data.ID)) { ToastUI.Ins.Set("[Mix_Seal] 합성 실패: 장착 중인 인장은 합성할 수 없습니다."); return; } // 2) 승급 대상 인장 찾기 SD_SealData target = Seal.list_Seal.Find(s => s.ID == data.ID); if (target == null) { ToastUI.Ins.Set("[Mix_Seal] 합성 실패: 대상 인장이 존재하지 않습니다."); return; } // 3) 동일 tableid + 동일 star 의 재료 인장 2개 찾기 (대상은 제외) List materials = new List(); foreach (var s in Seal.list_Seal) { if (s.ID == data.ID) continue; if (s.TableID == data.TableID && s.Lv == data.Lv) materials.Add(s); } if (materials.Count < 2) { ToastUI.Ins.Set("[Mix_Seal] 합성 실패: 동일 인장(star, tableid) 재료가 부족합니다. 필요: 2개"); return; } // 4) 합성 처리 target.Lv = data.Lv + 1; // 재료 2개 삭제 Seal.list_Seal.Remove(materials[0]); Seal.list_Seal.Remove(materials[1]); ToastUI.Ins.Set($"인장 합성 성공! ID:{data.ID}, Lv:{data.Lv - 1} → Lv:{data.Lv}"); ServerInfo.Ins.Save(); } #endregion #region 장비 public List Get_Equip_Inven(List types) { List rtn = new List(); bool isAll = types == null; for (int i = 0; i < Equipment.list_item.Count; i++) { var tdata = table_EquipmentList.Ins.Get_Data(Equipment.list_item[i].TableID); if (isAll || types.Contains(tdata.e_EquipmentType)) rtn.Add(Equipment.list_item[i]); } return rtn; } void Add_Equipment(int tid) { Equipment.list_item.Add(new SD_EquipmentData { ID = Equipment.Get_Init_ID(), TableID = tid, Lv = 0 }); ServerInfo.Ins.Save(); } public void Add_EquipmentLv(uint id, int lv = 1) { var item = Get_Equipment(id); if (item != null) { var edata = table_EquipmentList.Ins.Get_Data(item.TableID); var udata = table_EquipmentUpgrade.Ins.Get_Data(edata.n_Grade); if (item.Lv < udata.n_MaxLv) { item.Lv += lv; ServerInfo.Ins.Save(); } } } List list_noequipitems = new List { new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), new SD_EquipmentData(), }; public List Get_EquipItems(int pcid) { var rtn = new List(); if (!IsObtainPC(pcid)) return list_noequipitems; foreach (var id in dic_PC[pcid].list_equipitems) { if (id == 0) rtn.Add(new SD_EquipmentData()); else rtn.Add(Get_Equipment(id) ?? new SD_EquipmentData()); } return rtn; } public SD_EquipmentData Get_Equipment(uint id) { return Equipment.list_item.Find(f => f.ID == id); } bool TryFindEquippedPC(uint itemId, out int equippedPcid) { foreach (var kv in dic_PC) { if (kv.Value.list_equipitems.Exists(id => id == itemId)) { equippedPcid = kv.Key; return true; } } equippedPcid = -1; return false; } EquipResult CanEquipItem(int pcid, uint itemId) { var serverdata = Equipment.list_item.Find(f=>f.ID == itemId); if (serverdata == null) return EquipResult.NotEnoughEvolution; var tData = table_EquipmentList.Ins.Get_Data(serverdata.TableID); if (MyValue.dic_NeedEvolution.ContainsKey(tData.e_EquipmentType)) { if (MyValue.sdata.Get_PCEvolution(pcid) < MyValue.dic_NeedEvolution[tData.e_EquipmentType]) return EquipResult.NotEnoughEvolution; } if (!TryFindEquippedPC(itemId, out var equippedPcid)) return EquipResult.CanEquip; if (equippedPcid == pcid) return EquipResult.EquippedByMe; return EquipResult.EquippedByOther; } public bool Can_EquipItem(int pcid, uint itemId) { var result = CanEquipItem(pcid, itemId); return result == EquipResult.CanEquip || result == EquipResult.EquippedByOther; } public bool IsObtainItem(int tableid) { return Equipment.list_item.Find(f => f.TableID == tableid) != null; } public bool isEquipItem(uint id) { foreach (var pc in dic_PC.Values) if (pc.list_equipitems.Contains(id)) return true; return false; } public bool isEquipItem_byTableID(int id) { foreach (var pc in dic_PC.Values) { for (int i = 0; i < pc.list_equipitems.Count; i++) { var sid = pc.list_equipitems[i]; var sitem = Equipment.list_item.Find(f => f.ID == sid); if (sitem != null && sitem.TableID == id) return true; } } return false; } public bool isMyEquipItem(int pcid, uint id) { return IsObtainPC(pcid) && dic_PC[pcid].list_equipitems.Contains(id); } public void Set_EquipItem(int pcid, uint sid) { var result = CanEquipItem(pcid, sid); if (result == EquipResult.EquippedByMe) return; // 다른 캐릭터 장착 해제 if (result == EquipResult.EquippedByOther && TryFindEquippedPC(sid, out var otherPcid)) { var otherList = dic_PC[otherPcid].list_equipitems; for (int i = 0; i < otherList.Count; i++) if (otherList[i] == sid) otherList[i] = 0; } var itemData = Get_Equipment(sid); if (itemData == null) return; var tdata = table_EquipmentList.Ins.Get_Data(itemData.TableID); int slotIndex = (int)tdata.e_EquipmentType; dic_PC[pcid].list_equipitems[slotIndex] = sid; ServerInfo.Ins.Save(); } public void Set_UnEquipItem(int pcid, uint itemId) { if (!IsObtainPC(pcid)) return; var equipList = dic_PC[pcid].list_equipitems; for (int i = 0; i < equipList.Count; i++) { if (equipList[i] == itemId) { equipList[i] = 0; ServerInfo.Ins.Save(); return; } } } Dictionary dic_SetCheck = new Dictionary { { eEquipmentParts.Weapon, false }, { eEquipmentParts.SubWeapon, false }, { eEquipmentParts.ArmorTop, false }, { eEquipmentParts.ArmorBottom, false }, { eEquipmentParts.Gloves, false }, { eEquipmentParts.Shoes, false }, { eEquipmentParts.Ring, false }, { eEquipmentParts.Necklace, false } }; public int Get_ObtainSetItemCount(int setid) { var keys = dic_SetCheck.Keys.ToList(); for (int i = 0; i < keys.Count; i++) dic_SetCheck[keys[i]] = false; int count = 0; for (int i = 0; i < Equipment.list_item.Count; i++) { var temp = Equipment.list_item[i]; var tdata = table_EquipmentList.Ins.Get_Data(temp.TableID); if (tdata.n_SetGroupID == setid && !dic_SetCheck[tdata.e_EquipmentType]) { dic_SetCheck[tdata.e_EquipmentType] = true; ++count; } } return count; } public SetEquipmentData Get_EquipSetItemData(int pcid) { if (!IsObtainPC(pcid)) return null; SetEquipmentData data = new SetEquipmentData(); Dictionary dic_SetCount = new Dictionary(); // 1. Count equipped items per set for (int i = 0; i < dic_PC[pcid].list_equipitems.Count; i++) { var equipid = dic_PC[pcid].list_equipitems[i]; if (equipid == 0) continue; var itemdata = Equipment.list_item.Find(f => f.ID == equipid); var equipdata = table_EquipmentList.Ins.Get_Data(itemdata.TableID); if (equipdata.n_SetGroupID > 0) { if (dic_SetCount.ContainsKey(equipdata.n_SetGroupID)) ++dic_SetCount[equipdata.n_SetGroupID]; else dic_SetCount.Add(equipdata.n_SetGroupID, 1); } } // 2. Aggregate Set Bonuses foreach (var item in dic_SetCount) { var setdata = table_EquipmentSetOption.Ins.Get_Data(item.Key); if (setdata != null) data.Add(setdata, item.Value); } return data; } #endregion #region Item public bool Check_EnoughItem(int id, int amount, bool showtoast_ifnotenough = true) { if (Get_ItemAmount(id) >= amount) return true; if (showtoast_ifnotenough) ToastUI.Ins.Set(126); return false; } public int Get_ItemAmount(int id) { return dic_Item.ContainsKey(id) ? dic_Item[id].Amount : 0; } public void Add_Item(int id, int amount) { var itemdata = table_ItemList.Ins.Get_Data_orNull(id); if (itemdata != null) { switch (itemdata.e_ItemType) { case eItem.Goods: if (!dic_Item.ContainsKey(id)) dic_Item.Add(id, new SD_Money()); dic_Item[id].Amount += amount; LobbyTopUI.Ins.Set(); break; case eItem.PC: Add_PC(id); break; case eItem.Seal: for (int i = 0; i < amount; i++) Add_Seal(id); break; case eItem.Equipment: for (int i = 0; i < amount; i++) Add_Equipment(id); break; } ServerInfo.Ins.Save(); } else ToastUI.Ins.Set($"ItemList 테이블에 없는 아이템이어서 추가할 수 없습니다.\n{id}"); } #endregion #region Card public void Add_Card(int cardid) { if (!dic_Card.ContainsKey(cardid)) dic_Card.Add(cardid, new SD_Card()); ++dic_Card[cardid].Amount; } public bool IsGetAllCard() { var lst = table_cardlist.Ins.Get_DataList(); for (int i = 0; i < lst.Count; i++) { if (!dic_Card.ContainsKey(lst[i].n_ID)) return false; } return true; } public bool IsReinforceAllCard(int star) { var lst = table_cardlist.Ins.Get_DataList(); for (int i = 0; i < lst.Count; i++) { if (!dic_Card.ContainsKey(lst[i].n_ID)) return false; if (dic_Card[lst[i].n_ID].Lv < star) return false; } return true; } #endregion } #region 데이터 클래스 public class SD_PC { ObscuredInt _exp; public int Exp { get { return _exp; } set { _exp = value; _exp.RandomizeCryptoKey(); } } ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } ObscuredInt _evolutionStar; public int Evolution { get { return _evolutionStar; } set { _evolutionStar = value; _evolutionStar.RandomizeCryptoKey(); } } ObscuredInt _evolutionClear; public int EvolutionTestClear { get { return _evolutionClear; } set { _evolutionClear = value; _evolutionClear.RandomizeCryptoKey(); } } public Dictionary dic_EvolutionMax = new Dictionary(); public List list_equipseal = new List { 0, 0, 0, 0, 0, 0 }; // 인장 서버 id public List list_equipitems = new List(); // eEquipment 순서 public SD_PC() { Lv = 1; Exp = EvolutionTestClear = Evolution = 0; for (int i = 0; i < 8; i++) list_equipitems.Add(0); } public void Add_EvolutionMax(eStat stat) { if (!dic_EvolutionMax.ContainsKey(stat)) dic_EvolutionMax.Add(stat, new SD_EvolutionMax()); ++dic_EvolutionMax[stat].Lv; } public int Get_EvolutionMax(eStat stat) { return dic_EvolutionMax.ContainsKey(stat) ? dic_EvolutionMax[stat].Lv : 0; } } public class SD_EvolutionMax { ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } public SD_EvolutionMax() { Lv = 0; } } public class SD_PC_Awakening { ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } public SD_PC_Awakening() { Lv = 0; } } public class SD_Seal { ObscuredUInt _id = 0; public uint TotalID { get { return _id; } set { _id = value; _id.RandomizeCryptoKey(); } } public uint Get_Init_ID() { return ++TotalID; } public List list_Seal = new List(); } public class SD_SealData { ObscuredUInt _id; public uint ID { get { return _id; } set { _id = value; _id.RandomizeCryptoKey(); } } ObscuredInt _tid; public int TableID { get { return _tid; } set { _tid = value; _tid.RandomizeCryptoKey(); } } ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } } public class SD_Equipment { ObscuredUInt _id = 0; public uint TotalID { get { return _id; } set { _id = value; _id.RandomizeCryptoKey(); } } public uint Get_Init_ID() { return ++TotalID; } public List list_item = new List(); } public class SD_EquipmentData { ObscuredUInt _id; public uint ID { get { return _id; } set { _id = value; _id.RandomizeCryptoKey(); } } ObscuredInt _tid; public int TableID { get { return _tid; } set { _tid = value; _tid.RandomizeCryptoKey(); } } ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } public void Init() { ID = 0; TableID = Lv = 0; } } public class SD_Money { ObscuredInt _amount; public int Amount { get { return _amount; } set { _amount = value; _amount.RandomizeCryptoKey(); } } } public class SD_Card { ObscuredInt _amount; public int Amount { get { return _amount; } set { _amount = value; _amount.RandomizeCryptoKey(); } } ObscuredInt _lv; public int Lv { get { return _lv; } set { _lv = value; _lv.RandomizeCryptoKey(); } } } public class SD_GuideQuest { ObscuredInt _Step; public int Step { get { return _Step; } set { _Step = value; _Step.RandomizeCryptoKey(); } } protected ObscuredInt _Count; public int Count { get { return _Count; } set { _Count = value; _Count.RandomizeCryptoKey(); } } } #endregion #region 서버 -> 클라 public class SC_CommonResult { public int error; public DateTime time; } public class SC_MyResult { public int result; } public class SC_GetUserInfoResult { public bool isNewUser; public int ReconnectSec; public ServerData UserInfo; public List Mail; } public class SC_Mail { public List Mail; } [Serializable] public class ServerMailData { public string Msg, RemainTime; public int ItemID, Amount, IsShopItem; public DateTime RemnantTime; } public class SC_GuideQuestResult { public int Step; } #endregion