OneShotOneKill/Assets/Script/Server/ServerClass.cs

673 lines
22 KiB
C#
Raw Normal View History

2026-01-07 21:27:42 +00:00
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<int, SD_PC> dic_PC = new Dictionary<int, SD_PC>(); // pcid
// pcid, awaken id
public Dictionary<int, Dictionary<int, SD_PC_Awakening>> dic_PC_Awakening = new Dictionary<int, Dictionary<int, SD_PC_Awakening>>();
public SD_Seal Seal = new SD_Seal();
public SD_Equipment Equipment = new SD_Equipment();
public Dictionary<int, SD_Money> dic_Item = new Dictionary<int, SD_Money>(); // itemid
public Dictionary<int, SD_Card> dic_Card = new Dictionary<int, SD_Card>(); // 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<int, SD_PC_Awakening>());
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<uint> 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<SD_SealData> materials = new List<SD_SealData>();
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<SD_EquipmentData> Get_Equip_Inven(List<eEquipmentParts> types)
{
List<SD_EquipmentData> rtn = new List<SD_EquipmentData>();
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<SD_EquipmentData> list_noequipitems = new List<SD_EquipmentData>
{
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<SD_EquipmentData> Get_EquipItems(int pcid)
{
var rtn = new List<SD_EquipmentData>();
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<eEquipmentParts, bool> dic_SetCheck = new Dictionary<eEquipmentParts, bool>
{
{ 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<int, int> dic_SetCount = new Dictionary<int, int>();
// 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<eStat, SD_EvolutionMax> dic_EvolutionMax = new Dictionary<eStat, SD_EvolutionMax>();
public List<uint> list_equipseal = new List<uint> { 0, 0, 0, 0, 0, 0 }; // 인장 서버 id
public List<uint> list_equipitems = new List<uint>(); // 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<SD_SealData> list_Seal = new List<SD_SealData>();
}
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<SD_EquipmentData> list_item = new List<SD_EquipmentData>();
}
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<ServerMailData> Mail;
}
public class SC_Mail { public List<ServerMailData> 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