diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4d6d9c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vs/ \ No newline at end of file diff --git a/Assembly-CSharp/Assembly-CSharp.csproj b/Assembly-CSharp/Assembly-CSharp.csproj index 878a7d5..c67a7dc 100644 --- a/Assembly-CSharp/Assembly-CSharp.csproj +++ b/Assembly-CSharp/Assembly-CSharp.csproj @@ -7,9 +7,10 @@ Library 7.3 Assembly-CSharp - v2.0 + v3.5 4 True + AnyCPU @@ -27,6 +28,9 @@ true + ..\..\BfLauncher\BrickForce_Data\Managed\ + + ..\..\Brick-Force\BrickForce_Data\Managed\ @@ -726,6 +730,15 @@ + + + + + + + + + @@ -736,50 +749,52 @@ + + - - False - bin\Debug\Assembly-CSharp-firstpass.dll + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\Assembly-CSharp.dll - - False - bin\Debug\Assembly-UnityScript.dll + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\Assembly-CSharp-firstpass.dll - - False - bin\Debug\Assembly-UnityScript-firstpass.dll + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\Assembly-UnityScript-firstpass.dll - - False - bin\Debug\Boo.Lang.dll + + ..\..\BfLauncher\ICSharpCode.SharpZipLib.dll - - False - bin\Debug\Mono.Security.dll + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\Mono.Security.dll - bin\Debug\System.dll + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\System.dll - bin\Debug\System.Core.dll + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\System.Core.dll - - False - ..\..\Brick-Force\BrickForce_Data\Managed\UnityEngine.dll + + + + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\UnityEngine.dll - - False - bin\Debug\UnityScript.Lang.dll + + ..\..\..\Brick-Force-1.1.0\Brick-Force\BrickForce_Data\Managed\UnityScript.Lang.dll + + + + - copy /Y "$(TargetPath)" "G:\bf rewrite\Brick-Force 2\BrickForce_Data\Managed\Assembly-CSharp.dll" -copy /Y "$(TargetPath)" "G:\bf rewrite\Brick-Force 3\BrickForce_Data\Managed\Assembly-CSharp.dll" + + \ No newline at end of file diff --git a/Assembly-CSharp/BackConfirmDialog.cs b/Assembly-CSharp/BackConfirmDialog.cs index b98773d..3c406cd 100644 --- a/Assembly-CSharp/BackConfirmDialog.cs +++ b/Assembly-CSharp/BackConfirmDialog.cs @@ -112,9 +112,18 @@ public override bool DoDialog() if (GlobalVars.Instance.MyButton(new Rect(GlobalVars.Instance.ScreenRect.width / 2f - 110f, size.y - sizeOk.y - 25f, sizeOk.x, sizeOk.y), StringMgr.Instance.Get("SAVE"), "BtnAction") || GlobalVars.Instance.IsReturnPressed()) { result = true; - GetCopyRight(); - ThumbnailToPNG(); - CSNetManager.Instance.Sock.SendCS_SAVE_REQ(umi.Slot, ThumbnailToPNG()); + + bool copy = GetCopyRight(); + ThumbnailToPNG(); + //if umi does not exist, its a new map + if (copy) + { + CSNetManager.Instance.Sock.SendCS_SAVE_REQ(umi.Slot, ThumbnailToPNG()); + } else + { + CSNetManager.Instance.Sock.SendCS_SAVE_REQ(0, ThumbnailToPNG()); + } + //CSNetManager.Instance.Sock.SendCS_SAVE_REQ(umi.Slot, ThumbnailToPNG()); BackToScene(); } if (GlobalVars.Instance.MyButton(new Rect(GlobalVars.Instance.ScreenRect.width / 2f + 10f, size.y - sizeOk.y - 25f, sizeOk.x, sizeOk.y), StringMgr.Instance.Get("CANCEL"), "BtnAction") || GlobalVars.Instance.IsReturnPressed()) diff --git a/Assembly-CSharp/BndMatch.cs b/Assembly-CSharp/BndMatch.cs index 1fbc82f..faf0416 100644 --- a/Assembly-CSharp/BndMatch.cs +++ b/Assembly-CSharp/BndMatch.cs @@ -259,9 +259,17 @@ private void Start() private void StartLoad() { GC.Collect(); - BrickManager.Instance.userMap = new UserMap(); - CSNetManager.Instance.Sock.SendCS_CACHE_BRICK_REQ(); - } + UserMap userMap = new UserMap(); + if (userMap.Load(RoomManager.Instance.CurMap)) + { + BrickManager.Instance.userMap = userMap; + } + else + { + BrickManager.Instance.userMap = new UserMap(); + CSNetManager.Instance.Sock.SendCS_CACHE_BRICK_REQ(); + } + } private void ResetGameStuff() { diff --git a/Assembly-CSharp/BndTimer.cs b/Assembly-CSharp/BndTimer.cs index 5f43194..3346675 100644 --- a/Assembly-CSharp/BndTimer.cs +++ b/Assembly-CSharp/BndTimer.cs @@ -44,10 +44,11 @@ public bool IsBuildPhase public static int PackTimerOption(int build, int battle, int rpt) { - build /= 60; + build /= 60; battle /= 60; - return (build << 16) | (battle << 8) | rpt; - } + return (build << 16) | (battle << 8) | rpt; + //TESTING: return (1 << 16) | (1 << 8) | 2; + } public static int BuildPhaseTime(int timerOpt) { @@ -73,10 +74,13 @@ public void ResetTimer() public void ShiftPhase(bool buildPhase) { - if (buildPhase) + Debug.LogWarning("BndTimer: ShiftPhase to isBuildPhase: " + buildPhase); + if (buildPhase) { - repeat--; - } + Debug.LogWarning("BndTimer: reduce repeat: " + repeat); + repeat--; + Debug.LogWarning("BndTimer: new repeat: " + repeat); + } isBuildPhase = buildPhase; remain = ((!isBuildPhase) ? BattlePhaseTime(RoomManager.Instance.TimeLimit) : BuildPhaseTime(RoomManager.Instance.TimeLimit)); } @@ -88,6 +92,7 @@ private void Start() isBuildPhase = true; remain = BuildPhaseTime(RoomManager.Instance.TimeLimit); repeat = Repeat(RoomManager.Instance.TimeLimit); + Debug.LogWarning("repeatAtStart of BNDTimer: " + repeat); GameObject gameObject = GameObject.Find("Me"); if (null == gameObject) { @@ -142,13 +147,17 @@ private void Update() play++; if (play % 60 == 0) { + CSNetManager.Instance.Sock.SendCS_STACK_POINT_REQ(); } + //Debug.Log("[VERBOSE] BndTimerUpdate: remain: " + remain); if (remain < 0) { remain = 0; - ShiftPhase(!isBuildPhase); - CSNetManager.Instance.Sock.SendCS_BND_SHIFT_PHASE_REQ(repeat, isBuildPhase); + Debug.LogWarning("BndTimer: ShiftPhase from isBuildPhase: " + isBuildPhase); + ShiftPhase(!isBuildPhase); + Debug.LogWarning("BndTimer: SendShiftPhaseReq repeat: " + repeat + " isBuildPhase: " + isBuildPhase); + CSNetManager.Instance.Sock.SendCS_BND_SHIFT_PHASE_REQ(repeat, isBuildPhase); } else { diff --git a/Assembly-CSharp/CSVLoader.cs b/Assembly-CSharp/CSVLoader.cs index 21c8f45..05d1c37 100644 --- a/Assembly-CSharp/CSVLoader.cs +++ b/Assembly-CSharp/CSVLoader.cs @@ -244,7 +244,53 @@ private void _SecuredLoadFromBinaryReader(BinaryReader reader) _noCols = num2; } - public bool SecuredLoad(string pathName) + public void SecuredLoadAndSave(String pathName, String targetPath) + { + SecuredLoad(pathName); + File.WriteAllText(targetPath, ""); + FileStream fileStream = File.Open(targetPath, FileMode.Create, FileAccess.Write); + StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.ASCII); + streamWriter.BaseStream.Seek(0L, SeekOrigin.Begin); + streamWriter.WriteLine(_rows.Count); + for (int i = 0; i < _rows.Count; i++) + { + string line = ""; + string[] array = _rows[i]; + for (int j = 0; j < array.Length; j++) + { + if(j == array.Length - 1) + { + line += array[j]; + } else { + line += array[j] + ","; + } + + } + streamWriter.WriteLine(line); + } + streamWriter.Close(); + fileStream.Close(); + } + + public void LoadAndSecuredSave(String pathName, String targetPath) + { + FileStream fileStream = File.OpenRead(pathName); + StreamReader streamReader = new StreamReader(fileStream, Encoding.ASCII); + _rows = new List(); + streamReader.BaseStream.Seek(0L, SeekOrigin.Begin); + int num = Int32.Parse(streamReader.ReadLine()); + for (int i = 0; i < _rows.Count; i++) + { + string text = streamReader.ReadLine(); + string[] array = text.Split(','); + _rows.Add(array); + } + streamReader.Close(); + fileStream.Close(); + SecuredSave(targetPath); + } + + public bool SecuredLoad(string pathName) { pathName += ".cooked"; try @@ -322,7 +368,8 @@ public bool Save(string pathName, string header = "x\tCode") FileStream fileStream = File.Open(pathName, FileMode.Create, FileAccess.Write); StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.ASCII); streamWriter.BaseStream.Seek(0L, SeekOrigin.Begin); - streamWriter.WriteLine(header); + if (header != "") + streamWriter.WriteLine(header); for (int row = 0; row < Rows; row++) { string rowString = ""; diff --git a/Assembly-CSharp/CaptureTheFlagMatch.cs b/Assembly-CSharp/CaptureTheFlagMatch.cs index ccbbf74..ce83fd9 100644 --- a/Assembly-CSharp/CaptureTheFlagMatch.cs +++ b/Assembly-CSharp/CaptureTheFlagMatch.cs @@ -427,6 +427,7 @@ private void OnPicked(int seq) else { GameObject gameObject = BrickManManager.Instance.Get(seq); + Debug.Log(gameObject); if (gameObject != null) { Transform[] componentsInChildren = gameObject.GetComponentsInChildren(); diff --git a/Assembly-CSharp/CreateRoomDialog.cs b/Assembly-CSharp/CreateRoomDialog.cs index f2f66be..b519afc 100644 --- a/Assembly-CSharp/CreateRoomDialog.cs +++ b/Assembly-CSharp/CreateRoomDialog.cs @@ -282,7 +282,7 @@ public class CreateRoomDialog : Dialog private Color txtMainClr = Color.white; - private byte umiSlot; + private int umiSlot; private bool[] IsSupportClanMode; @@ -569,7 +569,7 @@ public bool InitDialog4TeamMatch(int map, ushort modeMask) return true; } - public bool InitDialog4MapEditorNew(byte slot) + public bool InitDialog4MapEditorNew(int slot) { curModeMask = 32767; InitDialog(); @@ -586,7 +586,7 @@ public bool InitDialog4MapEditorNew(byte slot) return true; } - public bool InitDialog4MapEditorLoad(byte slot) + public bool InitDialog4MapEditorLoad(int slot) { curModeMask = 32767; InitDialog(); @@ -2065,16 +2065,44 @@ private bool DoCreator() viewRect.height += crdMapOffset.y * (float)(num - 1); } umiScrollPosition = GUI.BeginScrollView(crdUserMapRect, umiScrollPosition, viewRect); - for (int i = 0; i < num; i++) + for (int i = 0; i < num; i++) { for (int j = 0; j < 3; j++) { int num2 = 3 * i + j; - if (num2 < umi.Length) + if (num2 < umi.Length) { - Texture2D texture2D = null; - texture2D = ((umi[num2].Alias.Length <= 0) ? emptySlot : ((!(umi[num2].Thumbnail == null)) ? umi[num2].Thumbnail : nonAvailable)); - Rect rect = new Rect((float)j * (crdMapSize.x + crdMapOffset.x), (float)i * (crdMapSize.y + crdMapOffset.y), crdMapSize.x, crdMapSize.y); + Texture2D texture2D = emptySlot; + //wrapped with try catch to catch that anoying nullpointer, this gets called like every frame but atleast the map loads + try + { + if (umi[num2] == null || num2 == 0) + { + texture2D = emptySlot; + } + else + { + if (umi[num2].Alias.Length <= 0 || umi[num2].regMap.Alias.Length <= 0) + { + texture2D = emptySlot; + } + else + { + texture2D = umi[num2].Thumbnail; + } + + if (texture2D == null) + { + texture2D = nonAvailable; + } + } + } + catch (NullReferenceException ex) + { + Debug.LogError($"NullReferenceException encountered: {ex.Message}"); + texture2D = nonAvailable; // Assign a default value to ensure stability + } + Rect rect = new Rect((float)j * (crdMapSize.x + crdMapOffset.x), (float)i * (crdMapSize.y + crdMapOffset.y), crdMapSize.x, crdMapSize.y); Rect position = new Rect(rect.x, rect.y, rect.width, rect.width); TextureUtil.DrawTexture(position, texture2D, ScaleMode.StretchToFill); if (GlobalVars.Instance.MyButton(rect, string.Empty, (!umi[num2].IsPremium) ? "BoxMapSelectBorder" : "BoxMapSelectBorderPremium") && (!umi[num2].IsPremium || flag)) diff --git a/Assembly-CSharp/MsgBody.cs b/Assembly-CSharp/MsgBody.cs index ca0e5b2..f0e7086 100644 --- a/Assembly-CSharp/MsgBody.cs +++ b/Assembly-CSharp/MsgBody.cs @@ -78,6 +78,15 @@ public bool Write(string val) return Copy(bytes); } + public bool Write(byte[] val) + { + if (!Write(val.Length)) + { + return false; + } + return Copy(val); + } + public bool Write(int val) { MemoryStream memoryStream = new MemoryStream(); @@ -170,6 +179,20 @@ public bool Read(out string val) return true; } + public bool Read(out byte[] val) + { + val = null; + if (!Read(out int val2)) + { + return false; + } + + val = new byte[val2]; + Array.Copy(_buffer, _offset, val, 0, val2); + _offset += val2; + return true; + } + public bool Read(out int val) { val = 0; diff --git a/Assembly-CSharp/P2PManager.cs b/Assembly-CSharp/P2PManager.cs index a8dde0e..735d053 100644 --- a/Assembly-CSharp/P2PManager.cs +++ b/Assembly-CSharp/P2PManager.cs @@ -866,10 +866,9 @@ private void Update() processedReliableIndex = meta; } } + flag = true; if (flag) { - //Debug.Log("P2P: " + p2PMsg2Handle._id); - switch (p2PMsg2Handle._id) { case 26: @@ -1140,301 +1139,6 @@ private void Update() } } - private void HandleMessages() - { - if (sock != null && recv != null && readQueue != null) - { - lock (this) - { - while (readQueue.Count > 0) - { - P2PMsg2Handle p2PMsg2Handle = (P2PMsg2Handle)readQueue.Peek(); - ushort meta = p2PMsg2Handle._meta; - bool flag = true; - if (meta != 65535) - { - SendPEER_RELIABLE_ACK(meta); - if (processedReliableIndex >= meta) - { - flag = false; - } - else - { - processedReliableIndex = meta; - } - } - if (flag) - { - switch (p2PMsg2Handle._id) - { - case 26: - HandlePEER_INITIATE(p2PMsg2Handle._msg); - break; - case 2: - HandlePEER_MOVE(p2PMsg2Handle._msg); - break; - case 5: - HandlePEER_THROW(p2PMsg2Handle._msg); - break; - case 6: - HandlePEER_SWAP_WEAPON(p2PMsg2Handle._msg); - break; - case 7: - HandlePEER_RELOAD(p2PMsg2Handle._msg); - break; - case 8: - HandlePEER_FIRE(p2PMsg2Handle._msg); - break; - case 9: - HandlePEER_SHOOT(p2PMsg2Handle._msg); - break; - case 10: - HandlePEER_DIE(p2PMsg2Handle._msg); - break; - case 11: - HandlePEER_RESPAWN(p2PMsg2Handle._msg); - break; - case 12: - HandlePEER_SLASH(p2PMsg2Handle._msg); - break; - case 13: - HandlePEER_PIERCE(p2PMsg2Handle._msg); - break; - case 14: - HandlePEER_PROJECTILE(p2PMsg2Handle._msg); - break; - case 15: - HandlePEER_BOMBED(p2PMsg2Handle._msg); - break; - case 16: - HandlePEER_PROJECTILE_FLY(p2PMsg2Handle._msg); - break; - case 17: - HandlePEER_PROJECTILE_KABOOM(p2PMsg2Handle._msg); - break; - case 18: - HandlePEER_PING(p2PMsg2Handle._msg); - break; - case 21: - HandlePEER_BRICK_HITPOINT(p2PMsg2Handle._msg); - break; - case 22: - HandlePEER_COMPOSE(p2PMsg2Handle._msg); - break; - case 23: - HandlePEER_WEAPON_STATUS(p2PMsg2Handle._msg); - break; - case 24: - SendRandezvousPing(); - break; - case 25: - HandlePEER_RANDEZVOUS_PONG(p2PMsg2Handle._msg); - break; - case 27: - HandlePEER_RELIABLE_ACK(p2PMsg2Handle._msg); - break; - case 28: - HandlePEER_FALL_DOWN(p2PMsg2Handle._msg); - break; - case 29: - HandlePEER_CANNON_MOVE(p2PMsg2Handle._msg); - break; - case 30: - HandlePEER_CANNON_FIRE(p2PMsg2Handle._msg); - break; - case 31: - HandlePEER_HIT_BRICK(p2PMsg2Handle._msg); - break; - case 32: - HandlePEER_HIT_BRICKMAN(p2PMsg2Handle._msg); - break; - case 34: - HandlePEER_ENABLE_HANDBOMB(p2PMsg2Handle._msg); - break; - case 20: - HandlePEER_PRIVATE_SHAKE(p2PMsg2Handle._msg); - break; - case 4: - HandlePEER_PUBLIC_SHAKE(p2PMsg2Handle._msg); - break; - case 36: - HandlePEER_RELAY_SHAKE(p2PMsg2Handle._msg); - break; - case 19: - HandlePEER_PRIVATE_HAND(p2PMsg2Handle._msg, p2PMsg2Handle._recvFrom); - break; - case 3: - HandlePEER_PUBLIC_HAND(p2PMsg2Handle._msg, p2PMsg2Handle._recvFrom); - break; - case 35: - HandlePEER_RELAY_HAND(p2PMsg2Handle._msg, p2PMsg2Handle._recvFrom); - break; - case 37: - HandlePEER_MON_GEN(p2PMsg2Handle._msg); - break; - case 38: - HandlePEER_MON_DIE(p2PMsg2Handle._msg); - break; - case 39: - HandlePEER_MON_MOVE(p2PMsg2Handle._msg); - break; - case 43: - HandlePEER_MON_HIT(p2PMsg2Handle._msg); - break; - case 44: - HandlePEER_SPECTATOR(p2PMsg2Handle._msg); - break; - case 47: - HandlePEER_BLAST_TIME(p2PMsg2Handle._msg); - break; - case 48: - HandlePEER_HIT_IMPACT(p2PMsg2Handle._msg); - break; - case 50: - HandlePEER_INSTALLING_BOMB(p2PMsg2Handle._msg); - break; - case 51: - HandlePEER_UNINSTALLING_BOMB(p2PMsg2Handle._msg); - break; - - - case 52: - SendP2pStatus(); - break; - case 53: - HandlePEER_DIR(p2PMsg2Handle._msg); - break; - case 54: - HandlePEER_CONSUME(p2PMsg2Handle._msg); - break; - case 55: - HandlePEER_UNINVINCIBLE(p2PMsg2Handle._msg); - break; - case 56: - HandlePEER_NUMWAVE(p2PMsg2Handle._msg); - break; - case 57: - HandlePEER_MON_ADDPOINT(p2PMsg2Handle._msg); - break; - case 58: - HandlePEER_DF_HEALER(p2PMsg2Handle._msg); - break; - case 59: - HandlePEER_DF_SELFHEAL(p2PMsg2Handle._msg); - break; - case 60: - HandlePEER_HP(p2PMsg2Handle._msg); - break; - case 61: - HandlePEER_BIG_WPN_FIRE(p2PMsg2Handle._msg); - break; - case 62: - HandlePEER_BIG_WPN_FLY(p2PMsg2Handle._msg); - break; - case 63: - HandlePEER_BIG_WPN_KABOOM(p2PMsg2Handle._msg); - break; - case 64: - HandlePEER_BOOST(p2PMsg2Handle._msg); - break; - case 65: - HandlePEER_SENSEBEAM(p2PMsg2Handle._msg); - break; - case 66: - HandlePEER_CONNECTION_STATUS(p2PMsg2Handle._msg); - break; - case 68: - HandlePEER_RANDEZVOUS_STATUS(p2PMsg2Handle._msg); - break; - case 69: - HandlePEER_BIG_FIRE(p2PMsg2Handle._msg); - break; - case 70: - HandlePEER_PORTAL(p2PMsg2Handle._msg); - break; - case 71: - HandlePEER_BRICK_ANIM(p2PMsg2Handle._msg); - break; - case 72: - HandlePEER_INVISIBLILITY(p2PMsg2Handle._msg); - break; - case 73: - HandlePEER_FIRE_NEW(p2PMsg2Handle._msg); - break; - case 74: - HandlePEER_HIT_BRICK_NEW(p2PMsg2Handle._msg); - break; - case 75: - HandlePEER_MON_HIT_NEW(p2PMsg2Handle._msg); - break; - case 76: - HandlePEER_HIT_BRICKMAN_NEW(p2PMsg2Handle._msg); - break; - case 77: - HandlePEER_HIT_IMPACT_NEW(p2PMsg2Handle._msg); - break; - case 78: - HandlePEER_MOVE_W(p2PMsg2Handle._msg); - break; - case 79: - HandlePEER_FIRE_ACTION_W(p2PMsg2Handle._msg); - break; - case 80: - HandlePEER_FIRE_W(p2PMsg2Handle._msg); - break; - case 81: - HandlePEER_DIR_W(p2PMsg2Handle._msg); - break; - case 82: - HandlePEER_HIT_BRICKMAN_W(p2PMsg2Handle._msg); - break; - case 83: - HandlePEER_CREATE_ACTIVE_ITEM(p2PMsg2Handle._msg); - break; - case 84: - HandlePEER_EAT_ACTIVE_ITEM_REQ(p2PMsg2Handle._msg); - break; - case 85: - HandlePEER_EAT_ACTIVE_ITEM_ACK(p2PMsg2Handle._msg); - break; - case 86: - HandlePEER_GUN_ANIM(p2PMsg2Handle._msg); - break; - case 87: - HandlePEER_STATE_FEVER(p2PMsg2Handle._msg); - break; - case 88: - HandlePEER_USE_ACTIVE_ITEM(p2PMsg2Handle._msg); - break; - case 89: - HandlePEER_BLACKHOLE_EFF(p2PMsg2Handle._msg); - break; - case 90: - HandlePEER_BUNGEE_BREAK_INTO_REQ(p2PMsg2Handle._msg); - break; - case 91: - HandlePEER_BUNGEE_BREAK_INTO_ACK(p2PMsg2Handle._msg); - break; - case 92: - HandlePEER_BUNGEE_BREAK_INTO_ACTIVEITEM_LIST(p2PMsg2Handle._msg); - break; - case 93: - HandlePEER_BRICK_ANIM_CROSSFADE(p2PMsg2Handle._msg); - break; - case 94: - HandlePEER_TRAIN_ROTATE(p2PMsg2Handle._msg); - break; - default: - Debug.LogError("Unknown msg encountered " + p2PMsg2Handle._id); - break; - } - } - readQueue.Dequeue(); - } - } - } - } - public Peer[] ToArray() { List list = new List(); diff --git a/Assembly-CSharp/RegMap.cs b/Assembly-CSharp/RegMap.cs index c1b8371..d162dc3 100644 --- a/Assembly-CSharp/RegMap.cs +++ b/Assembly-CSharp/RegMap.cs @@ -10,13 +10,13 @@ public class RegMap private int ver = 3; - private int map = -1; + public int map = -1; private string developer; private string alias; - private DateTime regDate; + public DateTime regDate; private ushort modeMask; diff --git a/Assembly-CSharp/RegMapManager.cs b/Assembly-CSharp/RegMapManager.cs index 6c61714..4dc81f7 100644 --- a/Assembly-CSharp/RegMapManager.cs +++ b/Assembly-CSharp/RegMapManager.cs @@ -230,7 +230,15 @@ public void Add(RegMap regMap) } } - public bool Del(int map) + public void UpdateMap(RegMap regMap) + { + if (dicRegMap.ContainsKey(regMap.Map)) + { + dicRegMap[regMap.Map] = regMap; + } + } + + public bool Del(int map) { if (!dicRegMap.ContainsKey(map)) { @@ -241,6 +249,7 @@ public bool Del(int map) private void Start() { + //This loads all regmap files string path = Path.Combine(Application.dataPath, "Resources/Cache"); if (!Directory.Exists(path)) { diff --git a/Assembly-CSharp/RenameMapDlg.cs b/Assembly-CSharp/RenameMapDlg.cs index 36a9eb0..7c18226 100644 --- a/Assembly-CSharp/RenameMapDlg.cs +++ b/Assembly-CSharp/RenameMapDlg.cs @@ -78,7 +78,7 @@ public override bool DoDialog() } if (GlobalVars.Instance.MyButton(crdOk, StringMgr.Instance.Get("OK"), "BtnAction") && CheckAlias()) { - CSNetManager.Instance.Sock.SendCS_CHANGE_USERMAP_ALIAS_REQ((sbyte)userMap.Slot, newMapAlias); + CSNetManager.Instance.Sock.SendCS_CHANGE_USERMAP_ALIAS_REQ(userMap.Slot, newMapAlias); result = true; } Rect rc = new Rect(size.x - 44f, 5f, 34f, 34f); diff --git a/Assembly-CSharp/Room.cs b/Assembly-CSharp/Room.cs index b6619c8..6e111fc 100644 --- a/Assembly-CSharp/Room.cs +++ b/Assembly-CSharp/Room.cs @@ -128,7 +128,7 @@ public enum ROOM_STATUS private bool locked; - private int no; + public int no; private int squad; @@ -136,7 +136,7 @@ public enum ROOM_STATUS private string title; - private ROOM_TYPE type; + public ROOM_TYPE type; private ROOM_STATUS status; diff --git a/Assembly-CSharp/SelectUserMapDlg.cs b/Assembly-CSharp/SelectUserMapDlg.cs index 9a5db4b..d0a0d51 100644 --- a/Assembly-CSharp/SelectUserMapDlg.cs +++ b/Assembly-CSharp/SelectUserMapDlg.cs @@ -42,7 +42,7 @@ public class SelectUserMapDlg : Dialog private Vector2 umiScrollPosition = Vector2.zero; - private byte umiSlot; + private int umiSlot; private float lastClickTime; diff --git a/Assembly-CSharp/ShooterTools.cs b/Assembly-CSharp/ShooterTools.cs index 31b1eb0..1a45c03 100644 --- a/Assembly-CSharp/ShooterTools.cs +++ b/Assembly-CSharp/ShooterTools.cs @@ -7,7 +7,7 @@ public class ShooterTools : MonoBehaviour public ShooterTool[] desc; - private ShooterTool[] tools; + public ShooterTool[] tools; private Vector2 crdToolSize = new Vector2(64f, 74f); diff --git a/Assembly-CSharp/ShopManager.cs b/Assembly-CSharp/ShopManager.cs index fb6c47d..0e1e1bd 100644 --- a/Assembly-CSharp/ShopManager.cs +++ b/Assembly-CSharp/ShopManager.cs @@ -5,7 +5,7 @@ public class ShopManager : MonoBehaviour { - private Dictionary dic; + public Dictionary dic; private Dictionary cache; @@ -84,7 +84,7 @@ private IEnumerator LoadFromWWW() } } - private bool LoadFromLocalFileSystem() + public bool LoadFromLocalFileSystem() { string text = Path.Combine(Application.dataPath, "Resources"); if (!Directory.Exists(text)) @@ -96,7 +96,7 @@ private bool LoadFromLocalFileSystem() string text3 = Path.Combine(text, "Template/shopCategory.txt"); CSVLoader cSVLoader = new CSVLoader(); CSVLoader cSVLoader2 = new CSVLoader(); - if (Application.platform == RuntimePlatform.WindowsEditor || !cSVLoader.SecuredLoad(text2)) + if (Application.platform == RuntimePlatform.WindowsEditor || !cSVLoader.Load(text2)) { if (!cSVLoader.Load(text2)) { @@ -171,7 +171,7 @@ private void ParseData(CSVLoader csvShopCat, CSVLoader csvShop) } else { - dic[Value13].AddPrice(Value14, Value15, Value16, Value17, Value18, 0, 0, 0, 0, 0, 0, 314816281); + dic[Value13].AddPrice(Value14, Value15, Value16, Value17, Value18, 0, 1, 0, 0, 0, 0, 314816281); } } } diff --git a/Assembly-CSharp/SockTcp.cs b/Assembly-CSharp/SockTcp.cs index 68ffac1..2333b70 100644 --- a/Assembly-CSharp/SockTcp.cs +++ b/Assembly-CSharp/SockTcp.cs @@ -7,7 +7,6 @@ using System.Net.Sockets; using UnityEngine; using wlic; - public class SockTcp { private const int REQ_SUCCESS = 0; @@ -1446,7 +1445,8 @@ public void Update() while (_readQueue != null && _readQueue.Count > 0) { Msg2Handle msg2Handle = (Msg2Handle)_readQueue.Peek(); - if (!ClientExtension.instance.HandleMessage(msg2Handle)) + + if (!ClientExtension.instance.HandleMessage(msg2Handle)) switch (msg2Handle._id) { case 2: @@ -3115,8 +3115,11 @@ public void SendCS_APPLY_CLAN_REQ(int clan, string clanName) public void SendCS_BND_SHIFT_PHASE_REQ(int repeat, bool isBuildPhase) { + Debug.LogWarning("Send BND # Req"); MsgBody msgBody = new MsgBody(); + Debug.LogWarning(repeat); msgBody.Write(repeat); + Debug.LogWarning(isBuildPhase); msgBody.Write(isBuildPhase); Say(349, msgBody); } @@ -3623,7 +3626,7 @@ public void SendCS_TIMER_REQ(int remainTime, int playTime) Say(65, msgBody); } - public void SendCS_CHANGE_USERMAP_ALIAS_REQ(sbyte slot, string alias) + public void SendCS_CHANGE_USERMAP_ALIAS_REQ(int slot, string alias) { MsgBody msgBody = new MsgBody(); msgBody.Write(slot); @@ -3770,7 +3773,8 @@ public void SendCS_BREAK_INTO_REQ() } } - public void SendCS_SAVE_REQ(byte slot, byte[] thumbnail) + //Hooked + public void SendCS_SAVE_REQ(int slot, byte[] thumbnail) { MsgBody msgBody = new MsgBody(); msgBody.Write(slot); @@ -3782,7 +3786,8 @@ public void SendCS_SAVE_REQ(byte slot, byte[] thumbnail) Say(39, msgBody); } - public void SendCS_REGISTER_REQ(byte slot, ushort modeMask, int regHow, int point, int downloadFee, byte[] thumbnail, string msgEval) + //Hooked + public void SendCS_REGISTER_REQ(int slot, ushort modeMask, int regHow, int point, int downloadFee, byte[] thumbnail, string msgEval) { MsgBody msgBody = new MsgBody(); msgBody.Write(slot); @@ -4619,7 +4624,7 @@ private void HandleCS_SAVE_ACK(MsgBody msg) MessageBoxMgr.Instance.AddMessage(string.Format(StringMgr.Instance.Get("SAVE_FAIL"), userMapInfo.Alias)); } } - } + } private void HandleCS_ROOM_CONFIG_ACK(MsgBody msg) { @@ -6197,7 +6202,7 @@ private void HandleCS_SET_STATUS_ACK(MsgBody msg) private void HandleCS_COPYRIGHT_ACK(MsgBody msg) { msg.Read(out int val); - msg.Read(out byte val2); + msg.Read(out int val2); UserMapInfoManager.Instance.master = val; if (val == MyInfoManager.Instance.Seq) { @@ -7180,12 +7185,17 @@ private void HandleCS_REBUY_ITEM_ACK(MsgBody msg) private void HandleCS_BUY_ITEM_ACK(MsgBody msg) { + // val = sequence (unique key) + // val2 = code + // val3 = remain (time in days) + // val4 = premium 0 || 1 + // val5 = durability msg.Read(out long val); msg.Read(out string val2); msg.Read(out int val3); msg.Read(out sbyte val4); msg.Read(out int val5); - if (val >= 0) + if (val >= 0) { MyInfoManager.Instance.BuyItem(val, val2, val3, val4, val5); TItem tItem = TItemManager.Instance.Get(val2); @@ -9050,24 +9060,26 @@ private void HandleCS_CLAN_MATCH_HALF_TIME_ACK(MsgBody msg) private void HandleCS_BND_SHIFT_PHASE_ACK(MsgBody msg) { - msg.Read(out int val); - msg.Read(out bool val2); + msg.Read(out int repeat); + msg.Read(out bool isBuildPhase); GameObject gameObject = GameObject.Find("Main"); if (null != gameObject) { - gameObject.BroadcastMessage("OnRoundEnd", val); + Debug.LogWarning(repeat); + gameObject.BroadcastMessage("OnRoundEnd", repeat); if (RoomManager.Instance.Master != MyInfoManager.Instance.Seq) { BndTimer component = gameObject.GetComponent(); if (null != component) { - component.ShiftPhase(val2); + Debug.LogWarning("Shift Phase not host"); + component.ShiftPhase(isBuildPhase); } } } if (MyInfoManager.Instance.BndModeDesc != null) { - MyInfoManager.Instance.BndModeDesc.buildPhase = val2; + MyInfoManager.Instance.BndModeDesc.buildPhase = isBuildPhase; } } @@ -9429,6 +9441,7 @@ private void HandleCS_CTF_PICK_FLAG_ACK(MsgBody msg) BrickManManager.Instance.haveFlagSeq = val; BrickManManager.Instance.bSendTcpCheckOnce = false; GameObject gameObject = GameObject.Find("Main"); + if (null != gameObject) { gameObject.BroadcastMessage("OnPicked", val); @@ -10357,7 +10370,7 @@ private void HandleCS_USER_MAP_ACK(MsgBody msg) } for (int i = 0; i < val2; i++) { - msg.Read(out byte val3); + msg.Read(out int val3); msg.Read(out string val4); msg.Read(out int val5); msg.Read(out int val6); @@ -11558,6 +11571,7 @@ public void SendCS_MISSION_POINT_REQ(int redPoint, int bluePoint) private void HandleCS_BND_STATUS_ACK(MsgBody msg) { + Debug.LogWarning("BND Status ACK"); msg.Read(out bool val); MyInfoManager.Instance.BndModeDesc = new BuildNDestroyModeDesc(); MyInfoManager.Instance.BndModeDesc.buildPhase = val; @@ -12090,7 +12104,10 @@ private void HandleCS_ZOMBIE_END_ACK(MsgBody msg) msg.Read(out int val13); msg.Read(out long val14); list.Add(new ResultUnitZombie(val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14)); - } + // Debug log for this client's data + Debug.Log($"Info Recieced Player {i + 1}: isRed={val2}, Seq={val3}, Name={val4}, Kills={val5}, Deaths={val6}, Assists={val7}, " + + $"Score={val8}, Points={val9}, XP={val10}, Mission={val11}, PrevXP={val12}, NextXP={val13}, Buff={val14}"); + } list.Sort((ResultUnitZombie prev, ResultUnitZombie next) => prev.Compare(next)); RoomManager.Instance.RU = list.ToArray(); RoomManager.Instance.endCode = 0; diff --git a/Assembly-CSharp/TItemManager.cs b/Assembly-CSharp/TItemManager.cs index 5457c12..0966836 100644 --- a/Assembly-CSharp/TItemManager.cs +++ b/Assembly-CSharp/TItemManager.cs @@ -890,6 +890,8 @@ private bool LoadWeaponFromLocalFileSystem() Debug.LogError("ERROR, Load success " + text2 + " but save secured failed"); } } + + //cSVLoader.Save("weapon.txt"); ParseWeapon(cSVLoader); return true; } diff --git a/Assembly-CSharp/TWeapon.cs b/Assembly-CSharp/TWeapon.cs index 2319aaa..45b691d 100644 --- a/Assembly-CSharp/TWeapon.cs +++ b/Assembly-CSharp/TWeapon.cs @@ -13,19 +13,14 @@ public enum CATEGORY SPECIAL } - private GameObject prefab; + private GameObject prefab; // Main prefab (game object) of the weapon + private GameObject prefab11; // Alternative prefab of the weapon + public string bone; // Bone associated with the weapon + public int cat; // Weapon category index + public int durabilityMax; // Maximum durability of the weapon + public bool IsTwoHands; // Flag indicating if the weapon requires both hands - private GameObject prefab11; - - public string bone; - - public int cat; - - public int durabilityMax; - - public bool IsTwoHands; - - private static string[] categories = new string[7] + private static string[] categories = new string[7] { "heavy", "assault", @@ -52,7 +47,9 @@ public TWeapon(string itemCode, string itemName, string itemBone, GameObject ite durabilityMax = itemDurabilityMax; } - public GameObject CurPrefab() + // Returns the current prefab of the weapon + // Check developer options and age restrictions to determine which prefab to return + public GameObject CurPrefab() { if (BuildOption.Instance.IsDeveloper && BuildOption.Instance.Props.MyAge < 12 && prefab11 != null) { @@ -65,7 +62,8 @@ public GameObject CurPrefab() return prefab; } - public static int String2WeaponCategory(string category) + // Converts a string category to an integer index + public static int String2WeaponCategory(string category) { for (int i = 0; i < categories.Length; i++) { @@ -78,12 +76,14 @@ public static int String2WeaponCategory(string category) return -1; } - public Weapon.TYPE GetWeaponType() + // Gets the weapon type based on the slot value + public Weapon.TYPE GetWeaponType() { return (Weapon.TYPE)(slot - 2); } - public static int GetDiscountRatio(int lv) + // Calculates and returns the discount ratio based on the provided level + public static int GetDiscountRatio(int lv) { if (lv >= 5) { @@ -104,7 +104,8 @@ public static int GetDiscountRatio(int lv) return 0; } - public int GetDiscountRatio() + // Calculates and returns the discount ratio based on the weapon category and player's XP values + public int GetDiscountRatio() { int result = 0; switch (cat) diff --git a/Assembly-CSharp/TooltipProperty.cs b/Assembly-CSharp/TooltipProperty.cs index 719dfda..3009793 100644 --- a/Assembly-CSharp/TooltipProperty.cs +++ b/Assembly-CSharp/TooltipProperty.cs @@ -1439,6 +1439,7 @@ private void DoGunProperty(TWeapon tWeapon, Gun gun, Scope scope, Aim aim) } GUI.color = color; outputy = titley; + LabelUtil.TextOut(new Vector2(outputx, outputy), (num8 + num17).ToString("0.##") + "%" + str, "MiniLabel", Color.white, GlobalVars.txtEmptyColor, TextAnchor.MiddleCenter); LabelUtil.TextOut(new Vector2(outputx, outputy + 20f), (num14 + num18).ToString("0.##") + "%" + str2, "MiniLabel", Color.white, GlobalVars.txtEmptyColor, TextAnchor.MiddleCenter); LabelUtil.TextOut(new Vector2(outputx, outputy + 40f), (num10 + num19).ToString("0.##") + "%" + str3, "MiniLabel", Color.white, GlobalVars.txtEmptyColor, TextAnchor.MiddleCenter); diff --git a/Assembly-CSharp/UserMap.cs b/Assembly-CSharp/UserMap.cs index a2d3751..59801be 100644 --- a/Assembly-CSharp/UserMap.cs +++ b/Assembly-CSharp/UserMap.cs @@ -15,7 +15,7 @@ public class UserMap public int crc; - private Dictionary dic; + public Dictionary dic; private BrickInst[,,] geometry; @@ -87,7 +87,7 @@ public UserMap() Clear(); } - private bool IsDefenseBrick(int seq) + private bool IsDefenseBrick(int seq) { if (seq == 134 || seq == 135 || seq == 136) { @@ -209,7 +209,7 @@ public bool Save(string fileName, int mapIndex, int skyboxIndex) return true; } - public void CalcCRC(int seq, byte template) + public void CalcCRC(int seq, byte template) { crc ^= seq + template; } @@ -328,7 +328,7 @@ public void Save(int mapIndex, int skyboxIndex) { string fileName = Path.Combine(text, "downloaded" + mapIndex + ".geometry"); Save(fileName, mapIndex, skyboxIndex); - } + } } public void CacheDone(int mapIndex, int skyboxIndex) diff --git a/Assembly-CSharp/UserMapInfo.cs b/Assembly-CSharp/UserMapInfo.cs index e06ddba..96a5d25 100644 --- a/Assembly-CSharp/UserMapInfo.cs +++ b/Assembly-CSharp/UserMapInfo.cs @@ -4,7 +4,7 @@ public class UserMapInfo { - private byte slot; + public int slot; private string alias; @@ -16,10 +16,21 @@ public class UserMapInfo private Texture2D thumbnail; + public RegMap regMap; //added to support editing of existing maps + public Texture2D Thumbnail { get { + if (regMap == null) + { + Debug.LogError("REGMAP IS NULL"); + return null; + } + if (regMap.Thumbnail != null) + { + return regMap.Thumbnail; + } if (null == thumbnail && alias.Length > 0 && lastModified.Year > 1971) { ThumbnailDownloader.Instance.Enqueue(isUserMap: true, slot); @@ -32,7 +43,7 @@ public Texture2D Thumbnail } } - public byte Slot => slot; + public int Slot => slot; public string Alias { @@ -84,22 +95,32 @@ public sbyte Premium } } - public UserMapInfo(byte _slot, sbyte _premium) + public UserMapInfo(int _slot, sbyte _premium) { slot = _slot; alias = string.Empty; - thumbnail = null; premium = _premium; + + if (slot > 0) + AssignRegMap(RegMapManager.Instance.Get(slot)); } - public UserMapInfo(byte _slot, string _alias, int _brickCount, DateTime _lastModified, sbyte _premium) + public UserMapInfo(int _slot, string _alias, int _brickCount, DateTime _lastModified, sbyte _premium) { slot = _slot; alias = _alias; brickCount = _brickCount; lastModified = _lastModified; - thumbnail = null; premium = _premium; + + if (slot > 0) + AssignRegMap(RegMapManager.Instance.Get(slot)); + } + + //added to support editing of existing maps + public void AssignRegMap(RegMap _regMap) + { + regMap = _regMap; } public void VerifySavedData() @@ -191,7 +212,7 @@ private bool Load(string fileName) { FileStream input = File.Open(fileName, FileMode.Open, FileAccess.Read); BinaryReader binaryReader = new BinaryReader(input); - slot = binaryReader.ReadByte(); + slot = binaryReader.ReadInt32(); alias = binaryReader.ReadString(); brickCount = binaryReader.ReadInt32(); int year = binaryReader.ReadInt32(); diff --git a/Assembly-CSharp/UserMapInfoManager.cs b/Assembly-CSharp/UserMapInfoManager.cs index b27385c..bb99196 100644 --- a/Assembly-CSharp/UserMapInfoManager.cs +++ b/Assembly-CSharp/UserMapInfoManager.cs @@ -6,7 +6,7 @@ public class UserMapInfoManager : MonoBehaviour { public int master = -1; - private SortedList listUMI; + private SortedList listUMI; private Dictionary dicRegMap; @@ -14,7 +14,7 @@ public class UserMapInfoManager : MonoBehaviour private string curMapName = string.Empty; - private byte curSlot = byte.MaxValue; + private int curSlot = int.MaxValue; private static UserMapInfoManager _instance; @@ -36,7 +36,7 @@ public string CurMapName } } - public byte CurSlot + public int CurSlot { get { @@ -189,16 +189,16 @@ private void OnApplicationQuit() private void Awake() { - listUMI = new SortedList(); + listUMI = new SortedList(); dicRegMap = new Dictionary(); cacheRegMap = new List(); UnityEngine.Object.DontDestroyOnLoad(this); } - public void VerifyCurMapName(byte slot) + public void VerifyCurMapName(int slot) { curSlot = slot; - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Key == slot) { @@ -207,7 +207,7 @@ public void VerifyCurMapName(byte slot) } } - public void CreateBuildMode(byte slot, string alias) + public void CreateBuildMode(int slot, string alias) { curSlot = slot; curMapName = alias; @@ -238,7 +238,7 @@ public void CacheRegMapBrickDone(bool regMapExisting) public void Verify() { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.BrickCount == 0) { @@ -253,7 +253,7 @@ private void Update() public void VerifySavedData() { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { item.Value.VerifySavedData(); } @@ -262,12 +262,12 @@ public void VerifySavedData() public void Clear() { listUMI.Clear(); - curSlot = byte.MaxValue; + curSlot = int.MaxValue; } - public void SetThumbnail(byte slot, Texture2D thumbnail) + public void SetThumbnail(int slot, Texture2D thumbnail) { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Slot == slot) { @@ -278,7 +278,7 @@ public void SetThumbnail(byte slot, Texture2D thumbnail) } } - public void Remove(byte key) + public void Remove(int key) { if (listUMI.ContainsKey(key)) { @@ -288,8 +288,8 @@ public void Remove(byte key) public void ValidateEmpty() { - List list = new List(); - foreach (KeyValuePair item in listUMI) + List list = new List(); + foreach (KeyValuePair item in listUMI) { if (item.Value.Alias.Length <= 0) { @@ -307,7 +307,7 @@ public void ValidateEmpty() num = 0; } num2 += MyInfoManager.Instance.ExtraSlots; - foreach (KeyValuePair item2 in listUMI) + foreach (KeyValuePair item2 in listUMI) { if (item2.Value.IsPremium) { @@ -326,7 +326,7 @@ public void ValidateEmpty() { num2 = 0; } - byte b = 1; + int b = 1; while (num2 > 0 && b < 200) { UserMapInfo userMapInfo = Get(b); @@ -335,9 +335,9 @@ public void ValidateEmpty() num2--; listUMI.Add(b, new UserMapInfo(b, 0)); } - b = (byte)(b + 1); + b = (int)(b + 1); } - byte b2 = 1; + int b2 = 1; while (num > 0 && b2 < 200) { UserMapInfo userMapInfo2 = Get(b2); @@ -346,13 +346,13 @@ public void ValidateEmpty() num--; listUMI.Add(b2, new UserMapInfo(b2, 1)); } - b2 = (byte)(b2 + 1); + b2 = (int)(b2 + 1); } } - public void AddOrUpdate(byte slot, string alias, int brickCount, DateTime lastModified, sbyte premium) + public void AddOrUpdate(int slot, string alias, int brickCount, DateTime lastModified, sbyte premium) { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Slot == slot) { @@ -377,9 +377,9 @@ public void AddOrUpdate(byte slot, string alias, int brickCount, DateTime lastMo } } - public UserMapInfo Get(byte slot) + public UserMapInfo Get(int slot) { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Slot == slot) { @@ -391,7 +391,7 @@ public UserMapInfo Get(byte slot) public bool HaveUserMap() { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Alias.Length > 0) { @@ -403,7 +403,7 @@ public bool HaveUserMap() public bool HaveEmptyUserMap() { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Alias.Length <= 0) { @@ -415,7 +415,7 @@ public bool HaveEmptyUserMap() public UserMapInfo GetCur() { - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (item.Value.Slot == curSlot) { @@ -429,7 +429,7 @@ public UserMapInfo[] ToArray() { UserMapInfo[] array = new UserMapInfo[listUMI.Count]; int num = 0; - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { array[num++] = item.Value; } @@ -442,7 +442,7 @@ public UserMapInfo[] ToArray(int page) int num2 = (page - 1) * 12; int num3 = 0; List list = new List(); - foreach (KeyValuePair item in listUMI) + foreach (KeyValuePair item in listUMI) { if (num3 >= 12) { diff --git a/Assembly-CSharp/WeaponModifier.cs b/Assembly-CSharp/WeaponModifier.cs index 5c01e0d..d900534 100644 --- a/Assembly-CSharp/WeaponModifier.cs +++ b/Assembly-CSharp/WeaponModifier.cs @@ -7,7 +7,7 @@ public class WeaponModifier : MonoBehaviour private Dictionary dicEx; - private static WeaponModifier _instance; + public static WeaponModifier _instance; public static WeaponModifier Instance { @@ -21,6 +21,7 @@ public static WeaponModifier Instance Debug.LogError("ERROR, Fail to get the WeaponModifier Instance"); } } + return _instance; } } diff --git a/Assembly-CSharp/ZombieMatch.cs b/Assembly-CSharp/ZombieMatch.cs index 77e2a6d..17414cd 100644 --- a/Assembly-CSharp/ZombieMatch.cs +++ b/Assembly-CSharp/ZombieMatch.cs @@ -443,6 +443,7 @@ private void UpdateZombieStatusNoti() deltaTime4ZombieStatus += Time.deltaTime; if (deltaTime4ZombieStatus > 1f && MyInfoManager.Instance.Seq == RoomManager.Instance.Master) { + deltaTime4ZombieStatus = 0f; CSNetManager.Instance.Sock.SendCS_ZOMBIE_STATUS_REQ((int)step, (int)deltaTime4ZombieMatch, countDown4SetPositionPhase); } } @@ -566,7 +567,7 @@ private void OnMatchRestarted() private void OnZombieStatus(ZombieStatus zs) { countDown4SetPositionPhase = zs._cntDn; - deltaTime4ZombieMatch = (float)zs._time; + deltaTime4ZombieMatch = (float)zs._time; step = (STEP)zs._status; } } diff --git a/Assembly-CSharp/_Emulator/Config.cs b/Assembly-CSharp/_Emulator/Config.cs index 8b8bc12..7006a06 100644 --- a/Assembly-CSharp/_Emulator/Config.cs +++ b/Assembly-CSharp/_Emulator/Config.cs @@ -1,4 +1,7 @@ -using System; +using _Emulator.JSON; +using System; +using System.Collections.Generic; +using System.IO; using UnityEngine; namespace _Emulator @@ -6,7 +9,7 @@ namespace _Emulator class Config { public static Config instance; - public CSVLoader csv; + public JsonObject configData; public Color crosshairColor = Color.green; public float crosshairHue = 90f; @@ -24,44 +27,62 @@ public Config() { LoadConfigFromDisk(); } - public void SaveConfigToDisk(string path = "Config\\Config.csv") + public void SaveConfigToDisk(string path = "Config\\Config.json") { - csv.SetValue("host_ip", ClientExtension.instance.hostIP); - csv.SetValue("debug_handle", ServerEmulator.instance.debugHandle); - csv.SetValue("debug_send", ServerEmulator.instance.debugSend); - csv.SetValue("debug_ping", ServerEmulator.instance.debugPing); - csv.SetValue("crosshair_r", crosshairColor.r); - csv.SetValue("crosshair_g", crosshairColor.g); - csv.SetValue("crosshair_b", crosshairColor.b); - csv.SetValue("usk_textures", uskTextures); - csv.SetValue("axis_ratio", axisRatio); - csv.SetValue("one_client_per_ip", oneClientPerIP); - csv.SetValue("block_connections", blockConnections); - csv.SetValue("auto_clear_dead_clients", autoClearDeadClients); - csv.SetValue("max_connections", maxConnections); - csv.Save(path, "Option\tValue"); + using (var writer = new StreamWriter(path)) + { + var jsonWriter = new JsonWriter(writer); + configData = new JsonObject + { + { "host_ip", ClientExtension.instance.hostIP }, + { "debug_handle", ServerEmulator.instance.debugHandle }, + { "debug_send", ServerEmulator.instance.debugSend }, + { "debug_ping", ServerEmulator.instance.debugPing }, + { "crosshair_r", crosshairColor.r }, + { "crosshair_g", crosshairColor.g }, + { "crosshair_b", crosshairColor.b }, + { "usk_textures", uskTextures }, + { "axis_ratio", axisRatio }, + { "one_client_per_ip", oneClientPerIP }, + { "block_connections", blockConnections }, + { "auto_clear_dead_clients", autoClearDeadClients }, + { "max_connections", maxConnections } + }; + jsonWriter.WriteObject(configData); + } } - public void LoadConfigFromDisk(string path = "Config\\Config.csv") + public void LoadConfigFromDisk(string path = "Config\\Config.json") { - csv = new CSVLoader(); - csv.Load(path); - ClientExtension.instance.hostIP = csv.GetValue("host_ip"); - ServerEmulator.instance.debugHandle = csv.GetValue("debug_handle"); - ServerEmulator.instance.debugSend = csv.GetValue("debug_send"); - ServerEmulator.instance.debugPing = csv.GetValue("debug_ping"); - crosshairColor.r = csv.GetValue("crosshair_r"); - crosshairColor.g = csv.GetValue("crosshair_g"); - crosshairColor.b = csv.GetValue("crosshair_b"); + if (!File.Exists(path)) + { + Debug.LogWarning("Config file not found. Using default values."); + SaveConfigToDisk(); + return; + } + + using (var reader = new StreamReader(path)) + { + var jsonReader = new JsonReader(reader); + configData = jsonReader.ReadObject(); + } + + ClientExtension.instance.hostIP = configData.Get("host_ip"); + ServerEmulator.instance.debugHandle = configData.Get("debug_handle"); + ServerEmulator.instance.debugSend = configData.Get("debug_send"); + ServerEmulator.instance.debugPing = configData.Get("debug_ping"); + crosshairColor.r = configData.Get("crosshair_r"); + crosshairColor.g = configData.Get("crosshair_g"); + crosshairColor.b = configData.Get("crosshair_b"); Utils.RGBToHSV(crosshairColor, out float H, out float S, out float V); crosshairHue = H * 360f; - uskTextures = csv.GetValue("usk_textures"); + uskTextures = configData.Get("usk_textures"); oldUskTextures = !uskTextures; - axisRatio = csv.GetValue("axis_ratio"); - oneClientPerIP = csv.GetValue("one_client_per_ip"); - blockConnections = csv.GetValue("block_connections"); - autoClearDeadClients = csv.GetValue("auto_clear_dead_clients"); - maxConnections = csv.GetValue("max_connections"); + axisRatio = configData.Get("axis_ratio"); + oneClientPerIP = configData.Get("one_client_per_ip"); + blockConnections = configData.Get("block_connections"); + autoClearDeadClients = configData.Get("auto_clear_dead_clients"); + maxConnections = configData.Get("max_connections"); ApplyUskTextures(); } diff --git a/Assembly-CSharp/_Emulator/DATA/shop.txt b/Assembly-CSharp/_Emulator/DATA/shop.txt new file mode 100644 index 0000000..1eec21e --- /dev/null +++ b/Assembly-CSharp/_Emulator/DATA/shop.txt @@ -0,0 +1,1238 @@ +itemCode, duration, forcepoints, brickpoint, tokens, discount +aaa,1000000,1000,0,4000,0 +aab,1000000,2000,0,4000,0 +aac,1000000,3000,0,4000,0 +aad,1000000,4000,0,4000,0 +aae,1000000,5000,0,4000,0 +aaf,1000000,6000,0,4000,0 +aag,1000000,7000,0,4000,0 +aah,1000000,8000,0,4000,0 +aai,1000000,9000,0,4000,0 +aaj,1000000,10000,0,4000,0 +aak,1000000,11000,0,4000,0 +aal,1000000,12000,0,4000,0 +aam,1000000,13000,0,4000,0 +aan,1000000,14000,0,4000,0 +aao,1000000,15000,0,4000,0 +aap,1000000,16000,0,4000,0 +aaq,1000000,17000,0,4000,0 +aar,1000000,18000,0,4000,0 +aas,1000000,19000,0,4000,0 +aat,1000000,20000,0,4000,0 +aau,1000000,5000,0,4000,0 +aav,1000000,5000,0,4000,0 +aaw,1000000,5000,0,4000,0 +aax,1000000,5000,0,4000,0 +aay,1000000,5000,0,4000,0 +aaz,1000000,5000,0,4000,0 +aba,1000000,5000,0,4000,0 +abb,1000000,5000,0,4000,0 +abc,1000000,5000,0,4000,0 +abd,1000000,5000,0,4000,0 +abe,1000000,5000,0,4000,0 +abf,1000000,5000,0,4000,0 +abg,1000000,5000,0,4000,0 +abh,1000000,5000,0,4000,0 +abi,1000000,5000,0,4000,0 +abj,1000000,5000,0,4000,0 +abk,1000000,5000,0,4000,0 +abl,1000000,5000,0,4000,0 +abm,1000000,5000,0,4000,0 +abn,1000000,5000,0,4000,0 +abo,1000000,5000,0,4000,0 +abp,1000000,5000,0,4000,0 +abq,1000000,5000,0,4000,0 +abr,1000000,5000,0,4000,0 +abs,1000000,5000,0,4000,0 +abt,1000000,5000,0,4000,0 +abu,1000000,5000,0,4000,0 +abv,1000000,5000,0,4000,0 +abw,1000000,5000,0,4000,0 +abx,1000000,5000,0,4000,0 +aby,1000000,5000,0,4000,0 +abz,1000000,5000,0,4000,0 +aca,1000000,5000,0,4000,0 +acb,1000000,5000,0,4000,0 +acc,1000000,5000,0,4000,0 +acd,1000000,5000,0,4000,0 +ace,1000000,5000,0,4000,0 +acf,1000000,5000,0,4000,0 +acg,1000000,5000,0,4000,0 +ach,1000000,5000,0,4000,0 +aci,1000000,5000,0,4000,0 +acj,1000000,5000,0,4000,0 +ack,1000000,5000,0,4000,0 +acl,1000000,5000,0,4000,0 +acm,1000000,5000,0,4000,0 +acn,1000000,5000,0,4000,0 +aco,1000000,5000,0,4000,0 +acp,1000000,5000,0,4000,0 +acq,1000000,5000,0,4000,0 +acr,1000000,5000,0,4000,0 +acs,1000000,5000,0,4000,0 +act,1000000,5000,0,4000,0 +acu,1000000,5000,0,4000,0 +acv,1000000,5000,0,4000,0 +acw,1000000,5000,0,4000,0 +acx,1000000,5000,0,4000,0 +acy,1000000,5000,0,4000,0 +acz,1000000,5000,0,4000,0 +ada,1000000,5000,0,4000,0 +adb,1000000,5000,0,4000,0 +adc,1000000,5000,0,4000,0 +add,1000000,5000,0,4000,0 +ade,1000000,5000,0,4000,0 +adf,1000000,5000,0,4000,0 +adg,1000000,5000,0,4000,0 +adh,1000000,5000,0,4000,0 +adi,1000000,5000,0,4000,0 +adj,1000000,5000,0,4000,0 +adk,1000000,5000,0,4000,0 +adl,1000000,5000,0,4000,0 +adm,1000000,5000,0,4000,0 +adn,1000000,5000,0,4000,0 +ado,1000000,5000,0,4000,0 +adp,1000000,5000,0,4000,0 +adq,1000000,5000,0,4000,0 +adr,1000000,5000,0,4000,0 +ads,1000000,5000,0,4000,0 +adt,1000000,5000,0,4000,0 +adu,1000000,5000,0,4000,0 +adw,1000000,5000,0,4000,0 +adx,1000000,5000,0,4000,0 +ady,1000000,5000,0,4000,0 +adz,1000000,5000,0,4000,0 +aea,1000000,5000,0,4000,0 +aeb,1000000,5000,0,4000,0 +aec,1000000,5000,0,4000,0 +aed,1000000,5000,0,4000,0 +aee,1000000,5000,0,4000,0 +aef,1000000,5000,0,4000,0 +aeg,1000000,5000,0,4000,0 +aeh,1000000,5000,0,4000,0 +aei,1000000,5000,0,4000,0 +aej,1000000,5000,0,4000,0 +aek,1000000,5000,0,4000,0 +ael,1000000,5000,0,4000,0 +aem,1000000,5000,0,4000,0 +aen,1000000,5000,0,4000,0 +aeo,1000000,5000,0,4000,0 +aep,1000000,5000,0,4000,0 +aeq,1000000,5000,0,4000,0 +aer,1000000,5000,0,4000,0 +aes,1000000,5000,0,4000,0 +aet,1000000,5000,0,4000,0 +aeu,1000000,5000,0,4000,0 +aew,1000000,5000,0,4000,0 +aex,1000000,5000,0,4000,0 +aey,1000000,5000,0,4000,0 +aez,1000000,5000,0,4000,0 +afa,1000000,5000,0,4000,0 +aff,1000000,5000,0,4000,0 +afg,1000000,5000,0,4000,0 +afh,1000000,5000,0,4000,0 +afi,1000000,5000,0,4000,0 +afj,1000000,5000,0,4000,0 +afk,1000000,5000,0,4000,0 +afl,1000000,5000,0,4000,0 +afm,1000000,5000,0,4000,0 +afb,1000000,5000,0,4000,0 +afc,1000000,5000,0,4000,0 +afd,1000000,5000,0,4000,0 +afe,1000000,5000,0,4000,0 +afo,1000000,5000,0,4000,0 +afp,1000000,5000,0,4000,0 +afq,1000000,5000,0,4000,0 +afr,1000000,5000,0,4000,0 +afs,1000000,5000,0,4000,0 +aft,1000000,5000,0,4000,0 +afu,1000000,5000,0,4000,0 +afw,1000000,5000,0,4000,0 +afx,1000000,5000,0,4000,0 +afy,1000000,5000,0,4000,0 +afz,1000000,5000,0,4000,0 +aga,1000000,5000,0,4000,0 +agb,1000000,5000,0,4000,0 +agc,1000000,5000,0,4000,0 +agd,1000000,5000,0,4000,0 +age,1000000,5000,0,4000,0 +agf,1000000,5000,0,4000,0 +agg,1000000,5000,0,4000,0 +agh,1000000,5000,0,4000,0 +agi,1000000,5000,0,4000,0 +agj,1000000,5000,0,4000,0 +agk,1000000,5000,0,4000,0 +agl,1000000,5000,0,4000,0 +agm,1000000,5000,0,4000,0 +agn,1000000,5000,0,4000,0 +ago,1000000,5000,0,4000,0 +agp,1000000,5000,0,4000,0 +agq,1000000,5000,0,4000,0 +agr,1000000,5000,0,4000,0 +ags,1000000,5000,0,4000,0 +agt,1000000,5000,0,4000,0 +agu,1000000,5000,0,4000,0 +agv,1000000,5000,0,4000,0 +agw,1000000,5000,0,4000,0 +agx,1000000,5000,0,4000,0 +agy,1000000,5000,0,4000,0 +agz,1000000,5000,0,4000,0 +aha,1000000,5000,0,4000,0 +ahb,1000000,5000,0,4000,0 +ahc,1000000,5000,0,4000,0 +ahd,1000000,5000,0,4000,0 +ahe,1000000,5000,0,4000,0 +ahf,1000000,5000,0,4000,0 +ahg,1000000,5000,0,4000,0 +ahh,1000000,5000,0,4000,0 +ahi,1000000,5000,0,4000,0 +ahj,1000000,5000,0,4000,0 +ahk,1000000,5000,0,4000,0 +ahl,1000000,5000,0,4000,0 +ahm,1000000,5000,0,4000,0 +ahn,1000000,5000,0,4000,0 +aho,1000000,5000,0,4000,0 +ahp,1000000,5000,0,4000,0 +ahq,1000000,5000,0,4000,0 +ahr,1000000,5000,0,4000,0 +ahs,1000000,5000,0,4000,0 +aht,1000000,5000,0,4000,0 +ahu,1000000,5000,0,4000,0 +ahv,1000000,5000,0,4000,0 +ahw,1000000,5000,0,4000,0 +ahx,1000000,5000,0,4000,0 +ahy,1000000,5000,0,4000,0 +ahz,1000000,5000,0,4000,0 +aia,1000000,5000,0,4000,0 +aib,1000000,5000,0,4000,0 +aic,1000000,5000,0,4000,0 +aid,1000000,5000,0,4000,0 +aie,1000000,5000,0,4000,0 +aif,1000000,5000,0,4000,0 +aig,1000000,5000,0,4000,0 +aih,1000000,5000,0,4000,0 +aii,1000000,5000,0,4000,0 +aij,1000000,5000,0,4000,0 +aik,1000000,5000,0,4000,0 +ail,1000000,5000,0,4000,0 +aim,1000000,5000,0,4000,0 +ain,1000000,5000,0,4000,0 +aio,1000000,5000,0,4000,0 +aip,1000000,5000,0,4000,0 +aiq,1000000,5000,0,4000,0 +air,1000000,5000,0,4000,0 +ais,1000000,5000,0,4000,0 +ait,1000000,5000,0,4000,0 +aiu,1000000,5000,0,4000,0 +aiv,1000000,5000,0,4000,0 +aiw,1000000,5000,0,4000,0 +aix,1000000,5000,0,4000,0 +aiy,1000000,5000,0,4000,0 +aiz,1000000,5000,0,4000,0 +aja,1000000,5000,0,4000,0 +ajb,1000000,5000,0,4000,0 +ajc,1000000,5000,0,4000,0 +ajd,1000000,5000,0,4000,0 +aje,1000000,5000,0,4000,0 +ajf,1000000,5000,0,4000,0 +ajg,1000000,5000,0,4000,0 +ajh,1000000,5000,0,4000,0 +aji,1000000,5000,0,4000,0 +ajj,1000000,5000,0,4000,0 +ajk,1000000,5000,0,4000,0 +ajl,1000000,5000,0,4000,0 +ajm,1000000,5000,0,4000,0 +ajn,1000000,5000,0,4000,0 +ajo,1000000,5000,0,4000,0 +ajp,1000000,5000,0,4000,0 +ajq,1000000,5000,0,4000,0 +ajr,1000000,5000,0,4000,0 +ajs,1000000,5000,0,4000,0 +ajt,1000000,5000,0,4000,0 +aju,1000000,5000,0,4000,0 +ajv,1000000,5000,0,4000,0 +ajw,1000000,5000,0,4000,0 +ajx,1000000,5000,0,4000,0 +ajy,1000000,5000,0,4000,0 +ajz,1000000,5000,0,4000,0 +aka,1000000,5000,0,4000,0 +akb,1000000,5000,0,4000,0 +akc,1000000,5000,0,4000,0 +akd,1000000,5000,0,4000,0 +ake,1000000,5000,0,4000,0 +akf,1000000,5000,0,4000,0 +akg,1000000,5000,0,4000,0 +akh,1000000,5000,0,4000,0 +aki,1000000,5000,0,4000,0 +akj,1000000,5000,0,4000,0 +akk,1000000,5000,0,4000,0 +akl,1000000,5000,0,4000,0 +akm,1000000,5000,0,4000,0 +akn,1000000,5000,0,4000,0 +ako,1000000,5000,0,4000,0 +akp,1000000,5000,0,4000,0 +akq,1000000,5000,0,4000,0 +akr,1000000,5000,0,4000,0 +aks,1000000,5000,0,4000,0 +akt,1000000,5000,0,4000,0 +waa,1000000,1,0,4000,0 +wab,1000000,2,0,4000,0 +wad,1000000,3,0,4000,0 +wae,1000000,4,0,4000,0 +waf,1000000,5,0,4000,0 +wag,1000000,6,0,4000,0 +wah,1000000,7,0,4000,0 +wai,1000000,8,0,4000,0 +waj,1000000,9,0,4000,0 +wak,1000000,10,0,4000,0 +wal,1000000,11,0,4000,0 +wao,1000000,12,0,4000,0 +wap,1000000,13,0,4000,0 +waq,1000000,14,0,4000,0 +war,1000000,15,0,4000,0 +was,1000000,16,0,4000,0 +wat,1000000,17,0,4000,0 +wau,1000000,18,0,4000,0 +wav,1000000,19,0,4000,0 +waw,1000000,20,0,4000,0 +wax,1000000,21,0,4000,0 +way,1000000,22,0,4000,0 +waz,1000000,23,0,4000,0 +wbb,1000000,25,0,4000,0 +wbc,1000000,5000,0,4000,0 +wbd,1000000,6969,0,4000,0 +wbe,1000000,5000,0,4000,0 +wbf,1000000,5000,0,4000,0 +wbg,1000000,5000,0,4000,0 +wbh,1000000,5000,0,4000,0 +wbi,1000000,5000,0,4000,0 +wbj,1000000,5000,0,4000,0 +wbk,1000000,5000,0,4000,0 +wbl,1000000,5000,0,4000,0 +wbm,1000000,5000,0,4000,0 +wbn,1000000,5000,0,4000,0 +wbo,1000000,5000,0,4000,0 +wbp,1000000,5000,0,4000,0 +wbq,1000000,5000,0,4000,0 +wbr,1000000,5000,0,4000,0 +wbs,1000000,5000,0,4000,0 +wbt,1000000,5000,0,4000,0 +wbu,1000000,5000,0,4000,0 +wbv,1000000,5000,0,4000,0 +wbw,1000000,5000,0,4000,0 +wbx,1000000,5000,0,4000,0 +wbz,1000000,5000,0,4000,0 +wca,1000000,5000,0,4000,0 +wcb,1000000,5000,0,4000,0 +wcc,1000000,5000,0,4000,0 +wcd,1000000,5000,0,4000,0 +wce,1000000,5000,0,4000,0 +wcf,1000000,5000,0,4000,0 +wcg,1000000,5000,0,4000,0 +wch,1000000,5000,0,4000,0 +wci,1000000,5000,0,4000,0 +wcj,1000000,5000,0,4000,0 +wck,1000000,5000,0,4000,0 +wcl,1000000,5000,0,4000,0 +wcm,1000000,5000,0,4000,0 +wcn,1000000,5000,0,4000,0 +wco,1000000,5000,0,4000,0 +wcp,1000000,5000,0,4000,0 +wcq,1000000,5000,0,4000,0 +wcr,1000000,5000,0,4000,0 +wcs,1000000,5000,0,4000,0 +wct,1000000,5000,0,4000,0 +wcu,1000000,5000,0,4000,0 +wcv,1000000,5000,0,4000,0 +wcw,1000000,5000,0,4000,0 +wcx,1000000,5000,0,4000,0 +wcy,1000000,5000,0,4000,0 +wcz,1000000,5000,0,4000,0 +wda,1000000,5000,0,4000,0 +wdb,1000000,5000,0,4000,0 +wdc,1000000,5000,0,4000,0 +wdd,1000000,5000,0,4000,0 +wde,1000000,5000,0,4000,0 +wdf,1000000,5000,0,4000,0 +wdg,1000000,5000,0,4000,0 +wdh,1000000,5000,0,4000,0 +wdi,1000000,5000,0,4000,0 +wdj,1000000,5000,0,4000,0 +wdk,1000000,5000,0,4000,0 +wdl,1000000,5000,0,4000,0 +wdm,1000000,5000,0,4000,0 +wdn,1000000,5000,0,4000,0 +wdo,1000000,5000,0,4000,0 +wdp,1000000,5000,0,4000,0 +wdq,1000000,5000,0,4000,0 +wdr,1000000,5000,0,4000,0 +wds,1000000,5000,0,4000,0 +wdt,1000000,5000,0,4000,0 +wdu,1000000,5000,0,4000,0 +wdw,1000000,5000,0,4000,0 +wdx,1000000,5000,0,4000,0 +wdy,1000000,5000,0,4000,0 +wdz,1000000,5000,0,4000,0 +wea,1000000,5000,0,4000,0 +web,1000000,5000,0,4000,0 +wec,1000000,5000,0,4000,0 +wed,1000000,5000,0,4000,0 +wee,1000000,5000,0,4000,0 +wef,1000000,5000,0,4000,0 +weg,1000000,5000,0,4000,0 +weh,1000000,5000,0,4000,0 +wei,1000000,5000,0,4000,0 +wej,1000000,5000,0,4000,0 +wek,1000000,5000,0,4000,0 +wem,1000000,5000,0,4000,0 +wen,1000000,5000,0,4000,0 +wel,1000000,5000,0,4000,0 +weo,1000000,5000,0,4000,0 +wep,1000000,5000,0,4000,0 +weq,1000000,5000,0,4000,0 +wew,1000000,5000,0,4000,0 +wex,1000000,5000,0,4000,0 +wey,1000000,5000,0,4000,0 +wez,1000000,5000,0,4000,0 +wfa,1000000,5000,0,4000,0 +wfb,1000000,5000,0,4000,0 +wfc,1000000,5000,0,4000,0 +weu,1000000,5000,0,4000,0 +wes,1000000,5000,0,4000,0 +wet,1000000,5000,0,4000,0 +wer,1000000,5000,0,4000,0 +wev,1000000,5000,0,4000,0 +wfd,1000000,5000,0,4000,0 +wfe,1000000,5000,0,4000,0 +wff,1000000,5000,0,4000,0 +wfg,1000000,5000,0,4000,0 +wfh,1000000,5000,0,4000,0 +wfi,1000000,5000,0,4000,0 +wfj,1000000,5000,0,4000,0 +wfk,1000000,5000,0,4000,0 +wfl,1000000,5000,0,4000,0 +wfm,1000000,5000,0,4000,0 +wfn,1000000,5000,0,4000,0 +wfo,1000000,5000,0,4000,0 +wfp,1000000,5000,0,4000,0 +wfq,1000000,5000,0,4000,0 +wfr,1000000,5000,0,4000,0 +wfs,1000000,5000,0,4000,0 +wft,1000000,5000,0,4000,0 +wfu,1000000,5000,0,4000,0 +wfv,1000000,5000,0,4000,0 +wfw,1000000,5000,0,4000,0 +wfx,1000000,5000,0,4000,0 +wfy,1000000,5000,0,4000,0 +wfz,1000000,5000,0,4000,0 +wga,1000000,5000,0,4000,0 +wgb,1000000,5000,0,4000,0 +wgc,1000000,5000,0,4000,0 +wgd,1000000,5000,0,4000,0 +wge,1000000,5000,0,4000,0 +wgf,1000000,5000,0,4000,0 +wgg,1000000,5000,0,4000,0 +wgh,1000000,5000,0,4000,0 +wgi,1000000,5000,0,4000,0 +wgj,1000000,5000,0,4000,0 +wgk,1000000,5000,0,4000,0 +wgl,1000000,5000,0,4000,0 +wgm,1000000,5000,0,4000,0 +wgn,1000000,5000,0,4000,0 +wgo,1000000,5000,0,4000,0 +wgp,1000000,5000,0,4000,0 +wgq,1000000,5000,0,4000,0 +wgr,1000000,5000,0,4000,0 +wgs,1000000,5000,0,4000,0 +wgt,1000000,5000,0,4000,0 +wgu,1000000,5000,0,4000,0 +wgv,1000000,5000,0,4000,0 +wgw,1000000,5000,0,4000,0 +wgx,1000000,5000,0,4000,0 +wgy,1000000,5000,0,4000,0 +wgz,1000000,5000,0,4000,0 +wha,1000000,5000,0,4000,0 +whb,1000000,5000,0,4000,0 +whc,1000000,5000,0,4000,0 +whd,1000000,5000,0,4000,0 +whe,1000000,5000,0,4000,0 +whf,1000000,5000,0,4000,0 +whg,1000000,5000,0,4000,0 +whh,1000000,5000,0,4000,0 +whi,1000000,5000,0,4000,0 +whj,1000000,5000,0,4000,0 +whk,1000000,5000,0,4000,0 +whl,1000000,5000,0,4000,0 +whm,1000000,5000,0,4000,0 +whn,1000000,5000,0,4000,0 +who,1000000,5000,0,4000,0 +whp,1000000,5000,0,4000,0 +whq,1000000,5000,0,4000,0 +whr,1000000,5000,0,4000,0 +whs,1000000,5000,0,4000,0 +wht,1000000,5000,0,4000,0 +whu,1000000,5000,0,4000,0 +whv,1000000,5000,0,4000,0 +whw,1000000,5000,0,4000,0 +whx,1000000,5000,0,4000,0 +why,1000000,5000,0,4000,0 +whz,1000000,5000,0,4000,0 +wia,1000000,5000,0,4000,0 +wib,1000000,5000,0,4000,0 +wic,1000000,5000,0,4000,0 +wid,1000000,5000,0,4000,0 +wie,1000000,5000,0,4000,0 +wif,1000000,5000,0,4000,0 +wig,1000000,5000,0,4000,0 +wih,1000000,5000,0,4000,0 +wii,1000000,5000,0,4000,0 +wij,1000000,5000,0,4000,0 +wik,1000000,5000,0,4000,0 +wil,1000000,5000,0,4000,0 +wim,1000000,5000,0,4000,0 +win,1000000,5000,0,4000,0 +wio,1000000,5000,0,4000,0 +wip,1000000,5000,0,4000,0 +wiq,1000000,5000,0,4000,0 +wir,1000000,5000,0,4000,0 +wis,1000000,5000,0,4000,0 +wit,1000000,5000,0,4000,0 +wiu,1000000,5000,0,4000,0 +wiv,1000000,5000,0,4000,0 +wiw,1000000,5000,0,4000,0 +wix,1000000,5000,0,4000,0 +wiy,1000000,5000,0,4000,0 +wiz,1000000,5000,0,4000,0 +wja,1000000,5000,0,4000,0 +wjb,1000000,5000,0,4000,0 +wjc,1000000,5000,0,4000,0 +wjd,1000000,5000,0,4000,0 +wje,1000000,5000,0,4000,0 +wjf,1000000,5000,0,4000,0 +wjg,1000000,5000,0,4000,0 +wjh,1000000,5000,0,4000,0 +wji,1000000,5000,0,4000,0 +wjj,1000000,5000,0,4000,0 +wjk,1000000,5000,0,4000,0 +wjl,1000000,5000,0,4000,0 +wjm,1000000,5000,0,4000,0 +wjn,1000000,5000,0,4000,0 +wjo,1000000,5000,0,4000,0 +wjp,1000000,5000,0,4000,0 +wjq,1000000,5000,0,4000,0 +wjr,1000000,5000,0,4000,0 +wjs,1000000,5000,0,4000,0 +wjt,1000000,5000,0,4000,0 +wju,1000000,5000,0,4000,0 +wjv,1000000,5000,0,4000,0 +wjw,1000000,5000,0,4000,0 +wjx,1000000,5000,0,4000,0 +wjy,1000000,5000,0,4000,0 +wjz,1000000,5000,0,4000,0 +wka,1000000,5000,0,4000,0 +wkb,1000000,5000,0,4000,0 +wkc,1000000,5000,0,4000,0 +wkd,1000000,5000,0,4000,0 +wke,1000000,5000,0,4000,0 +wkf,1000000,5000,0,4000,0 +wkg,1000000,5000,0,4000,0 +wkh,1000000,5000,0,4000,0 +wki,1000000,5000,0,4000,0 +wkj,1000000,5000,0,4000,0 +wkk,1000000,5000,0,4000,0 +wkl,1000000,5000,0,4000,0 +wkm,1000000,5000,0,4000,0 +wkn,1000000,5000,0,4000,0 +wko,1000000,5000,0,4000,0 +wkp,1000000,5000,0,4000,0 +wkq,1000000,5000,0,4000,0 +wkr,1000000,5000,0,4000,0 +wks,1000000,5000,0,4000,0 +wkt,1000000,5000,0,4000,0 +wku,1000000,5000,0,4000,0 +wkv,1000000,5000,0,4000,0 +wkw,1000000,5000,0,4000,0 +wkx,1000000,5000,0,4000,0 +wky,1000000,5000,0,4000,0 +wkz,1000000,5000,0,4000,0 +wla,1000000,5000,0,4000,0 +wlb,1000000,5000,0,4000,0 +wlc,1000000,5000,0,4000,0 +wld,1000000,5000,0,4000,0 +wle,1000000,5000,0,4000,0 +wlf,1000000,5000,0,4000,0 +wlg,1000000,5000,0,4000,0 +wlh,1000000,5000,0,4000,0 +wli,1000000,5000,0,4000,0 +wlj,1000000,5000,0,4000,0 +wlk,1000000,5000,0,4000,0 +wll,1000000,5000,0,4000,0 +wlm,1000000,5000,0,4000,0 +wln,1000000,5000,0,4000,0 +wlo,1000000,5000,0,4000,0 +wlp,1000000,5000,0,4000,0 +wlq,1000000,5000,0,4000,0 +wlr,1000000,5000,0,4000,0 +wls,1000000,5000,0,4000,0 +wlt,1000000,5000,0,4000,0 +wlu,1000000,5000,0,4000,0 +wlv,1000000,5000,0,4000,0 +wlw,1000000,5000,0,4000,0 +wlx,1000000,5000,0,4000,0 +wly,1000000,5000,0,4000,0 +wlz,1000000,5000,0,4000,0 +wma,1000000,5000,0,4000,0 +wmb,1000000,5000,0,4000,0 +wmc,1000000,5000,0,4000,0 +wmd,1000000,5000,0,4000,0 +wme,1000000,5000,0,4000,0 +wmf,1000000,5000,0,4000,0 +wmg,1000000,5000,0,4000,0 +wmh,1000000,5000,0,4000,0 +wmi,1000000,5000,0,4000,0 +wmj,1000000,5000,0,4000,0 +wmk,1000000,5000,0,4000,0 +wml,1000000,5000,0,4000,0 +wmm,1000000,5000,0,4000,0 +wmn,1000000,5000,0,4000,0 +wmo,1000000,5000,0,4000,0 +wmp,1000000,5000,0,4000,0 +wmq,1000000,5000,0,4000,0 +wmr,1000000,5000,0,4000,0 +wms,1000000,5000,0,4000,0 +wmt,1000000,5000,0,4000,0 +wmu,1000000,5000,0,4000,0 +wmv,1000000,5000,0,4000,0 +wmw,1000000,5000,0,4000,0 +wmx,1000000,5000,0,4000,0 +wmy,1000000,5000,0,4000,0 +wmz,1000000,5000,0,4000,0 +wna,1000000,5000,0,4000,0 +wnb,1000000,5000,0,4000,0 +wnc,1000000,5000,0,4000,0 +wnd,1000000,5000,0,4000,0 +wne,1000000,5000,0,4000,0 +wnf,1000000,5000,0,4000,0 +wng,1000000,5000,0,4000,0 +wnh,1000000,5000,0,4000,0 +wni,1000000,5000,0,4000,0 +wnj,1000000,5000,0,4000,0 +wnk,1000000,5000,0,4000,0 +wnl,1000000,5000,0,4000,0 +wnm,1000000,5000,0,4000,0 +wnn,1000000,5000,0,4000,0 +wno,1000000,5000,0,4000,0 +wnp,1000000,5000,0,4000,0 +wnq,1000000,5000,0,4000,0 +wnr,1000000,5000,0,4000,0 +wns,1000000,5000,0,4000,0 +wnt,1000000,5000,0,4000,0 +wnu,1000000,5000,0,4000,0 +wnv,1000000,5000,0,4000,0 +wnw,1000000,5000,0,4000,0 +wnx,1000000,5000,0,4000,0 +wny,1000000,5000,0,4000,0 +wnz,1000000,5000,0,4000,0 +woa,1000000,5000,0,4000,0 +wob,1000000,5000,0,4000,0 +woc,1000000,5000,0,4000,0 +wod,1000000,5000,0,4000,0 +woe,1000000,5000,0,4000,0 +wof,1000000,5000,0,4000,0 +wog,1000000,5000,0,4000,0 +woh,1000000,5000,0,4000,0 +woi,1000000,5000,0,4000,0 +woj,1000000,5000,0,4000,0 +wok,1000000,5000,0,4000,0 +wol,1000000,5000,0,4000,0 +wom,1000000,5000,0,4000,0 +won,1000000,5000,0,4000,0 +woo,1000000,5000,0,4000,0 +wop,1000000,5000,0,4000,0 +woq,1000000,5000,0,4000,0 +wor,1000000,5000,0,4000,0 +wos,1000000,5000,0,4000,0 +wot,1000000,5000,0,4000,0 +wou,1000000,5000,0,4000,0 +wov,1000000,5000,0,4000,0 +a01,1000000,5000,0,4000,0 +a02,1000000,5000,0,4000,0 +a03,1000000,5000,0,4000,0 +a04,1000000,5000,0,4000,0 +a05,1000000,5000,0,4000,0 +a06,1000000,5000,0,4000,0 +a07,1000000,5000,0,4000,0 +a08,1000000,5000,0,4000,0 +a09,1000000,5000,0,4000,0 +a10,1000000,5000,0,4000,0 +a11,1000000,5000,0,4000,0 +a12,1000000,5000,0,4000,0 +a13,1000000,5000,0,4000,0 +a14,1000000,5000,0,4000,0 +a15,1000000,5000,0,4000,0 +a16,1000000,5000,0,4000,0 +a17,1000000,5000,0,4000,0 +a18,1000000,5000,0,4000,0 +a19,1000000,5000,0,4000,0 +a20,1000000,5000,0,4000,0 +a21,1000000,5000,0,4000,0 +a22,1000000,5000,0,4000,0 +a23,1000000,5000,0,4000,0 +a24,1000000,5000,0,4000,0 +a25,1000000,5000,0,4000,0 +a26,1000000,5000,0,4000,0 +a27,1000000,5000,0,4000,0 +a28,1000000,5000,0,4000,0 +a29,1000000,5000,0,4000,0 +a30,1000000,5000,0,4000,0 +a31,1000000,5000,0,4000,0 +a32,1000000,5000,0,4000,0 +a33,1000000,5000,0,4000,0 +a34,1000000,5000,0,4000,0 +a35,1000000,5000,0,4000,0 +a36,1000000,5000,0,4000,0 +a37,1000000,5000,0,4000,0 +a38,1000000,5000,0,4000,0 +a39,1000000,5000,0,4000,0 +a40,1000000,5000,0,4000,0 +a41,1000000,5000,0,4000,0 +a42,1000000,5000,0,4000,0 +a43,1000000,5000,0,4000,0 +a44,1000000,5000,0,4000,0 +a45,1000000,5000,0,4000,0 +a46,1000000,5000,0,4000,0 +a47,1000000,5000,0,4000,0 +a48,1000000,5000,0,4000,0 +a49,1000000,5000,0,4000,0 +a50,1000000,5000,0,4000,0 +a51,1000000,5000,0,4000,0 +a52,1000000,5000,0,4000,0 +a53,1000000,5000,0,4000,0 +a54,1000000,5000,0,4000,0 +a55,1000000,5000,0,4000,0 +a56,1000000,5000,0,4000,0 +a57,1000000,5000,0,4000,0 +a58,1000000,5000,0,4000,0 +a59,1000000,5000,0,4000,0 +a60,1000000,5000,0,4000,0 +a61,1000000,5000,0,4000,0 +a62,1000000,5000,0,4000,0 +a63,1000000,5000,0,4000,0 +a64,1000000,5000,0,4000,0 +a65,1000000,5000,0,4000,0 +a66,1000000,5000,0,4000,0 +a67,1000000,5000,0,4000,0 +a68,1000000,5000,0,4000,0 +a69,1000000,5000,0,4000,0 +a70,1000000,5000,0,4000,0 +a71,1000000,5000,0,4000,0 +a72,1000000,5000,0,4000,0 +a73,1000000,5000,0,4000,0 +a74,1000000,5000,0,4000,0 +a75,1000000,5000,0,4000,0 +a76,1000000,5000,0,4000,0 +a78,1000000,5000,0,4000,0 +a79,1000000,5000,0,4000,0 +a80,1000000,5000,0,4000,0 +a81,1000000,5000,0,4000,0 +a82,1000000,5000,0,4000,0 +a83,1000000,5000,0,4000,0 +a84,1000000,5000,0,4000,0 +a85,1000000,5000,0,4000,0 +a86,1000000,5000,0,4000,0 +a87,1000000,5000,0,4000,0 +a88,1000000,5000,0,4000,0 +a89,1000000,5000,0,4000,0 +a90,1000000,5000,0,4000,0 +a91,1000000,5000,0,4000,0 +a92,1000000,5000,0,4000,0 +a93,1000000,5000,0,4000,0 +a94,1000000,5000,0,4000,0 +a95,1000000,5000,0,4000,0 +a96,1000000,5000,0,4000,0 +a97,1000000,5000,0,4000,0 +a98,1000000,5000,0,4000,0 +a99,1000000,5000,0,4000,0 +aa1,1000000,5000,0,4000,0 +aa2,1000000,5000,0,4000,0 +aa3,1000000,5000,0,4000,0 +aa4,1000000,5000,0,4000,0 +aa5,1000000,5000,0,4000,0 +aa6,1000000,5000,0,4000,0 +aa7,1000000,5000,0,4000,0 +aa8,1000000,5000,0,4000,0 +aa9,1000000,5000,0,4000,0 +ab1,1000000,5000,0,4000,0 +ab2,1000000,5000,0,4000,0 +ab3,1000000,5000,0,4000,0 +ab4,1000000,5000,0,4000,0 +ab5,1000000,5000,0,4000,0 +ab6,1000000,5000,0,4000,0 +ab7,1000000,5000,0,4000,0 +ab8,1000000,5000,0,4000,0 +ab9,1000000,5000,0,4000,0 +ac1,1000000,5000,0,4000,0 +ac2,1000000,5000,0,4000,0 +ac3,1000000,5000,0,4000,0 +ac4,1000000,5000,0,4000,0 +ac5,1000000,5000,0,4000,0 +ac6,1000000,5000,0,4000,0 +ac7,1000000,5000,0,4000,0 +ac8,1000000,5000,0,4000,0 +ac9,1000000,5000,0,4000,0 +ad1,1000000,5000,0,4000,0 +ad2,1000000,5000,0,4000,0 +ad3,1000000,5000,0,4000,0 +ad4,1000000,5000,0,4000,0 +ad5,1000000,5000,0,4000,0 +ad6,1000000,5000,0,4000,0 +ad7,1000000,5000,0,4000,0 +ad8,1000000,5000,0,4000,0 +ad9,1000000,5000,0,4000,0 +ae1,1000000,5000,0,4000,0 +ae2,1000000,5000,0,4000,0 +ae3,1000000,5000,0,4000,0 +ae4,1000000,5000,0,4000,0 +ae5,1000000,5000,0,4000,0 +ae6,1000000,5000,0,4000,0 +ae7,1000000,5000,0,4000,0 +ae8,1000000,5000,0,4000,0 +ae9,1000000,5000,0,4000,0 +af1,1000000,5000,0,4000,0 +af2,1000000,5000,0,4000,0 +af3,1000000,5000,0,4000,0 +af4,1000000,5000,0,4000,0 +af5,1000000,5000,0,4000,0 +af6,1000000,5000,0,4000,0 +af7,1000000,5000,0,4000,0 +af8,1000000,5000,0,4000,0 +af9,1000000,5000,0,4000,0 +af0,1000000,5000,0,4000,0 +ag1,1000000,5000,0,4000,0 +ag2,1000000,5000,0,4000,0 +ag3,1000000,5000,0,4000,0 +ag4,1000000,5000,0,4000,0 +ag5,1000000,5000,0,4000,0 +ag6,1000000,5000,0,4000,0 +ag7,1000000,5000,0,4000,0 +ag8,1000000,5000,0,4000,0 +ag9,1000000,5000,0,4000,0 +ag0,1000000,5000,0,4000,0 +ah1,1000000,5000,0,4000,0 +ah2,1000000,5000,0,4000,0 +ah3,1000000,5000,0,4000,0 +ah4,1000000,5000,0,4000,0 +ah5,1000000,5000,0,4000,0 +ah6,1000000,5000,0,4000,0 +ah7,1000000,5000,0,4000,0 +ah8,1000000,5000,0,4000,0 +ah9,1000000,5000,0,4000,0 +ah0,1000000,5000,0,4000,0 +ai1,1000000,5000,0,4000,0 +ai2,1000000,5000,0,4000,0 +ai3,1000000,5000,0,4000,0 +ai4,1000000,5000,0,4000,0 +ai5,1000000,5000,0,4000,0 +ai6,1000000,5000,0,4000,0 +ai7,1000000,5000,0,4000,0 +ai8,1000000,5000,0,4000,0 +ai9,1000000,5000,0,4000,0 +ai0,1000000,5000,0,4000,0 +aj1,1000000,5000,0,4000,0 +aj2,1000000,5000,0,4000,0 +aj3,1000000,5000,0,4000,0 +aj4,1000000,5000,0,4000,0 +aj5,1000000,5000,0,4000,0 +aj6,1000000,5000,0,4000,0 +aj7,1000000,5000,0,4000,0 +aj8,1000000,5000,0,4000,0 +aj9,1000000,5000,0,4000,0 +aj0,1000000,5000,0,4000,0 +ak1,1000000,5000,0,4000,0 +ak2,1000000,5000,0,4000,0 +ak3,1000000,5000,0,4000,0 +ak4,1000000,5000,0,4000,0 +ak5,1000000,5000,0,4000,0 +ak6,1000000,5000,0,4000,0 +ak7,1000000,5000,0,4000,0 +ak8,1000000,5000,0,4000,0 +ak9,1000000,5000,0,4000,0 +ak0,1000000,5000,0,4000,0 +al1,1000000,5000,0,4000,0 +al2,1000000,5000,0,4000,0 +al3,1000000,5000,0,4000,0 +al4,1000000,5000,0,4000,0 +al5,1000000,5000,0,4000,0 +al6,1000000,5000,0,4000,0 +al7,1000000,5000,0,4000,0 +al8,1000000,5000,0,4000,0 +al9,1000000,5000,0,4000,0 +al0,1000000,5000,0,4000,0 +an1,1000000,5000,0,4000,0 +an2,1000000,5000,0,4000,0 +an3,1000000,5000,0,4000,0 +an4,1000000,5000,0,4000,0 +an5,1000000,5000,0,4000,0 +an6,1000000,5000,0,4000,0 +an7,1000000,5000,0,4000,0 +an8,1000000,5000,0,4000,0 +an9,1000000,5000,0,4000,0 +an0,1000000,5000,0,4000,0 +am7,1000000,5000,0,4000,0 +am8,1000000,5000,0,4000,0 +am9,1000000,5000,0,4000,0 +am0,1000000,5000,0,4000,0 +ao1,1000000,5000,0,4000,0 +ao2,1000000,5000,0,4000,0 +ao3,1000000,5000,0,4000,0 +ao4,1000000,5000,0,4000,0 +ao5,1000000,5000,0,4000,0 +ao6,1000000,5000,0,4000,0 +am1,1000000,5000,0,4000,0 +am2,1000000,5000,0,4000,0 +am3,1000000,5000,0,4000,0 +am4,1000000,5000,0,4000,0 +am5,1000000,5000,0,4000,0 +am6,1000000,5000,0,4000,0 +ao7,1000000,5000,0,4000,0 +ao8,1000000,5000,0,4000,0 +ao9,1000000,5000,0,4000,0 +ao0,1000000,5000,0,4000,0 +ap1,1000000,5000,0,4000,0 +ap2,1000000,5000,0,4000,0 +ap3,1000000,5000,0,4000,0 +ap4,1000000,5000,0,4000,0 +ap5,1000000,5000,0,4000,0 +ap6,1000000,5000,0,4000,0 +ap7,1000000,5000,0,4000,0 +ap8,1000000,5000,0,4000,0 +ap9,1000000,5000,0,4000,0 +ap0,1000000,5000,0,4000,0 +aq1,1000000,5000,0,4000,0 +aq2,1000000,5000,0,4000,0 +aq3,1000000,5000,0,4000,0 +aq4,1000000,5000,0,4000,0 +aq5,1000000,5000,0,4000,0 +aq6,1000000,5000,0,4000,0 +aq7,1000000,5000,0,4000,0 +aq8,1000000,5000,0,4000,0 +aq9,1000000,5000,0,4000,0 +ar0,1000000,5000,0,4000,0 +ar1,1000000,5000,0,4000,0 +ar2,1000000,5000,0,4000,0 +ar3,1000000,5000,0,4000,0 +ar4,1000000,5000,0,4000,0 +ar5,1000000,5000,0,4000,0 +ar6,1000000,5000,0,4000,0 +ar7,1000000,5000,0,4000,0 +ar8,1000000,5000,0,4000,0 +ar9,1000000,5000,0,4000,0 +as0,1000000,5000,0,4000,0 +as1,1000000,5000,0,4000,0 +as2,1000000,5000,0,4000,0 +as3,1000000,5000,0,4000,0 +as4,1000000,5000,0,4000,0 +as5,1000000,5000,0,4000,0 +as6,1000000,5000,0,4000,0 +as7,1000000,5000,0,4000,0 +as8,1000000,5000,0,4000,0 +as9,1000000,5000,0,4000,0 +at0,1000000,5000,0,4000,0 +at1,1000000,5000,0,4000,0 +at2,1000000,5000,0,4000,0 +at3,1000000,5000,0,4000,0 +at4,1000000,5000,0,4000,0 +at5,1000000,5000,0,4000,0 +at6,1000000,5000,0,4000,0 +at7,1000000,5000,0,4000,0 +at8,1000000,5000,0,4000,0 +at9,1000000,5000,0,4000,0 +au0,1000000,5000,0,4000,0 +au1,1000000,5000,0,4000,0 +au2,1000000,5000,0,4000,0 +au3,1000000,5000,0,4000,0 +au4,1000000,5000,0,4000,0 +au5,1000000,5000,0,4000,0 +au6,1000000,5000,0,4000,0 +au7,1000000,5000,0,4000,0 +au8,1000000,5000,0,4000,0 +au9,1000000,5000,0,4000,0 +av0,1000000,5000,0,4000,0 +av1,1000000,5000,0,4000,0 +av2,1000000,5000,0,4000,0 +av3,1000000,5000,0,4000,0 +av4,1000000,5000,0,4000,0 +av5,1000000,5000,0,4000,0 +av6,1000000,5000,0,4000,0 +av7,1000000,5000,0,4000,0 +av8,1000000,5000,0,4000,0 +av9,1000000,5000,0,4000,0 +aw0,1000000,5000,0,4000,0 +aw1,1000000,5000,0,4000,0 +aw2,1000000,5000,0,4000,0 +aw3,1000000,5000,0,4000,0 +aw4,1000000,5000,0,4000,0 +aw5,1000000,5000,0,4000,0 +aw6,1000000,5000,0,4000,0 +aw7,1000000,5000,0,4000,0 +aw8,1000000,5000,0,4000,0 +aw9,1000000,5000,0,4000,0 +ax0,1000000,5000,0,4000,0 +ax1,1000000,5000,0,4000,0 +ax2,1000000,5000,0,4000,0 +ax3,1000000,5000,0,4000,0 +ax4,1000000,5000,0,4000,0 +ax5,1000000,5000,0,4000,0 +ax6,1000000,5000,0,4000,0 +ax7,1000000,5000,0,4000,0 +ax8,1000000,5000,0,4000,0 +ax9,1000000,5000,0,4000,0 +ay0,1000000,5000,0,4000,0 +ay1,1000000,5000,0,4000,0 +ay2,1000000,5000,0,4000,0 +ay3,1000000,5000,0,4000,0 +ay4,1000000,5000,0,4000,0 +ay5,1000000,5000,0,4000,0 +ay6,1000000,5000,0,4000,0 +ay7,1000000,5000,0,4000,0 +ay8,1000000,5000,0,4000,0 +ay9,1000000,5000,0,4000,0 +az0,1000000,5000,0,4000,0 +az1,1000000,5000,0,4000,0 +az2,1000000,5000,0,4000,0 +az3,1000000,5000,0,4000,0 +az4,1000000,5000,0,4000,0 +az5,1000000,5000,0,4000,0 +az6,1000000,5000,0,4000,0 +az7,1000000,5000,0,4000,0 +az8,1000000,5000,0,4000,0 +az9,1000000,5000,0,4000,0 +e01,1000000,5000,0,4000,0 +e02,1000000,5000,0,4000,0 +e03,1000000,5000,0,4000,0 +e04,1000000,5000,0,4000,0 +e05,1000000,5000,0,4000,0 +e06,1000000,5000,0,4000,0 +e07,1000000,5000,0,4000,0 +e08,1000000,5000,0,4000,0 +e09,1000000,5000,0,4000,0 +e10,1000000,5000,0,4000,0 +e11,1000000,5000,0,4000,0 +e12,1000000,5000,0,4000,0 +e13,1000000,5000,0,4000,0 +e14,1000000,5000,0,4000,0 +e15,1000000,5000,0,4000,0 +e16,1000000,5000,0,4000,0 +e17,1000000,5000,0,4000,0 +e18,1000000,5000,0,4000,0 +e19,1000000,5000,0,4000,0 +e20,1000000,5000,0,4000,0 +e21,1000000,5000,0,4000,0 +e22,1000000,5000,0,4000,0 +e23,1000000,5000,0,4000,0 +e24,1000000,5000,0,4000,0 +e25,1000000,5000,0,4000,0 +e26,1000000,5000,0,4000,0 +e27,1000000,5000,0,4000,0 +e28,1000000,5000,0,4000,0 +e29,1000000,5000,0,4000,0 +e30,1000000,5000,0,4000,0 +e31,1000000,5000,0,4000,0 +e32,1000000,5000,0,4000,0 +e33,1000000,5000,0,4000,0 +e34,1000000,5000,0,4000,0 +e35,1000000,5000,0,4000,0 +e36,1000000,5000,0,4000,0 +e37,1000000,5000,0,4000,0 +e38,1000000,5000,0,4000,0 +e39,1000000,5000,0,4000,0 +e40,1000000,5000,0,4000,0 +e41,1000000,5000,0,4000,0 +e42,1000000,5000,0,4000,0 +e43,1000000,5000,0,4000,0 +e44,1000000,5000,0,4000,0 +e45,1000000,5000,0,4000,0 +e46,1000000,5000,0,4000,0 +e47,1000000,5000,0,4000,0 +e48,1000000,5000,0,4000,0 +e49,1000000,5000,0,4000,0 +e50,1000000,5000,0,4000,0 +e51,1000000,5000,0,4000,0 +e52,1000000,5000,0,4000,0 +e53,1000000,5000,0,4000,0 +e54,1000000,5000,0,4000,0 +e55,1000000,5000,0,4000,0 +e56,1000000,5000,0,4000,0 +e57,1000000,5000,0,4000,0 +e58,1000000,5000,0,4000,0 +e59,1000000,5000,0,4000,0 +e60,1000000,5000,0,4000,0 +e61,1000000,5000,0,4000,0 +e62,1000000,5000,0,4000,0 +e63,1000000,5000,0,4000,0 +e64,1000000,5000,0,4000,0 +e65,1000000,5000,0,4000,0 +e66,1000000,5000,0,4000,0 +e67,1000000,5000,0,4000,0 +e68,1000000,5000,0,4000,0 +e69,1000000,5000,0,4000,0 +e70,1000000,5000,0,4000,0 +e71,1000000,5000,0,4000,0 +e72,1000000,5000,0,4000,0 +e73,1000000,5000,0,4000,0 +e74,1000000,5000,0,4000,0 +e75,1000000,5000,0,4000,0 +e76,1000000,5000,0,4000,0 +e77,1000000,5000,0,4000,0 +e78,1000000,5000,0,4000,0 +e79,1000000,5000,0,4000,0 +e80,1000000,5000,0,4000,0 +e81,1000000,5000,0,4000,0 +e82,1000000,5000,0,4000,0 +e83,1000000,5000,0,4000,0 +e84,1000000,5000,0,4000,0 +e85,1000000,5000,0,4000,0 +e86,1000000,5000,0,4000,0 +e87,1000000,5000,0,4000,0 +e88,1000000,5000,0,4000,0 +e89,1000000,5000,0,4000,0 +e90,1000000,5000,0,4000,0 +e91,1000000,5000,0,4000,0 +e92,1000000,5000,0,4000,0 +e93,1000000,5000,0,4000,0 +e94,1000000,5000,0,4000,0 +e95,1000000,5000,0,4000,0 +e96,1000000,5000,0,4000,0 +e97,1000000,5000,0,4000,0 +e98,1000000,5000,0,4000,0 +e99,1000000,5000,0,4000,0 +ea0,1000000,5000,0,4000,0 +ea1,1000000,5000,0,4000,0 +ea2,1000000,5000,0,4000,0 +ea3,1000000,5000,0,4000,0 +ea4,1000000,5000,0,4000,0 +ea5,1000000,5000,0,4000,0 +ea6,1000000,5000,0,4000,0 +ea7,1000000,5000,0,4000,0 +ea8,1000000,5000,0,4000,0 +ea9,1000000,5000,0,4000,0 +eb0,1000000,5000,0,4000,0 +eb1,1000000,5000,0,4000,0 +eb2,1000000,5000,0,4000,0 +eb3,1000000,5000,0,4000,0 +eb4,1000000,5000,0,4000,0 +eb5,1000000,5000,0,4000,0 +eb6,1000000,5000,0,4000,0 +eb7,1000000,5000,0,4000,0 +eb8,1000000,5000,0,4000,0 +eb9,1000000,5000,0,4000,0 +ec0,1000000,5000,0,4000,0 +ec1,1000000,5000,0,4000,0 +ec2,1000000,5000,0,4000,0 +ec3,1000000,5000,0,4000,0 +ec4,1000000,5000,0,4000,0 +ec5,1000000,5000,0,4000,0 +ec6,1000000,5000,0,4000,0 +ec7,1000000,5000,0,4000,0 +ec8,1000000,5000,0,4000,0 +ec9,1000000,5000,0,4000,0 +ed0,1000000,5000,0,4000,0 +ed1,1000000,5000,0,4000,0 +ed2,1000000,5000,0,4000,0 +ed3,1000000,5000,0,4000,0 +ed4,1000000,5000,0,4000,0 +ed5,1000000,5000,0,4000,0 +ed6,1000000,5000,0,4000,0 +ed7,1000000,5000,0,4000,0 +ed8,1000000,5000,0,4000,0 +ed9,1000000,5000,0,4000,0 +ee0,1000000,5000,0,4000,0 +ee1,1000000,5000,0,4000,0 +ee2,1000000,5000,0,4000,0 +ee3,1000000,5000,0,4000,0 +ee4,1000000,5000,0,4000,0 +ee5,1000000,5000,0,4000,0 +ee6,1000000,5000,0,4000,0 +c01,1000000,5000,0,4000,0 +c02,1000000,5000,0,4000,0 +c03,1000000,5000,0,4000,0 +c04,1000000,5000,0,4000,0 +c05,1000000,5000,0,4000,0 +c06,1000000,5000,0,4000,0 +c07,1000000,5000,0,4000,0 +c08,1000000,5000,0,4000,0 +c09,1000000,5000,0,4000,0 +c10,1000000,5000,0,4000,0 +c11,1000000,5000,0,4000,0 +c12,1000000,5000,0,4000,0 +c13,1000000,5000,0,4000,0 +c14,1000000,5000,0,4000,0 +c15,1000000,5000,0,4000,0 +c16,1000000,5000,0,4000,0 +c17,1000000,5000,0,4000,0 +c18,1000000,5000,0,4000,0 +s01,1,5000,0,4000,0 +s05,1000000,5000,0,4000,0 +s06,1000000,5000,0,4000,0 +s08,1000000,5000,0,4000,0 +s09,1000000,5000,0,4000,0 +s10,1000000,5000,0,4000,0 +s11,1000000,5000,0,4000,0 +s12,1000000,5000,0,4000,0 +s13,1000000,5000,0,4000,0 +s14,1000000,5000,0,4000,0 +s15,1000000,5000,0,4000,0 +s16,1000000,5000,0,4000,0 +s17,1000000,5000,0,4000,0 +s18,1000000,5000,0,4000,0 +s19,1000000,5000,0,4000,0 +s20,1000000,5000,0,4000,0 +s21,1000000,5000,0,4000,0 +s23,1000000,5000,0,4000,0 +s24,1000000,5000,0,4000,0 +s25,1,5000,0,4000,0 +s80,1,0,0,10,0 +s80,10,0,0,100,0 +s80,100,0,0,1000,0 +s82,1,5000,0,4000,0 +s83,1,5000,0,4000,0 +s84,1,0,0,5,0 +s84,10,0,0,50,0 +s84,100,0,0,500,0 +s85,1,0,0,20,0 +s85,10,0,0,200,0 +s85,100,0,0,2000,0 +s86,1,5000,0,4000,0 +s87,1,5000,0,4000,0 +s88,1,5000,0,4000,0 +s89,1,5000,0,4000,0 +s90,1,0,0,1,0 +s91,1,0,0,1,0 +s92,1000000,5000,0,4000,0 +s93,1,0,0,2,0 +s94,1,0,0,1,0 +s95,1,0,0,1000,0 +s95,10,0,0,10000,0 +s95,100,0,0,100000,0 +s96,1000000,5000,0,4000,0 +s97,1,5000,0,4000,0 +s98,1,5000,0,4000,0 +s99,1,5000,0,4000,0 +sa0,1,5000,0,4000,0 +sa1,1,5000,0,4000,0 +sa2,1,5000,0,4000,0 +sa3,1,5000,0,4000,0 +sa4,1,5000,0,4000,0 +sa5,1,5000,0,4000,0 +u01,1,5000,0,4000,0 +u02,1,5000,0,4000,0 +u03,1,5000,0,4000,0 +u04,1,5000,0,4000,0 +u05,1,5000,0,4000,0 +u06,1,5000,0,4000,0 +u07,1,5000,0,4000,0 +u08,1,5000,0,4000,0 +u09,1,5000,0,4000,0 +u10,1,5000,0,4000,0 +u11,1,5000,0,4000,0 +u12,1,5000,0,4000,0 \ No newline at end of file diff --git a/Assembly-CSharp/_Emulator/DATA/shopCategory.txt b/Assembly-CSharp/_Emulator/DATA/shopCategory.txt new file mode 100644 index 0000000..21cc23d --- /dev/null +++ b/Assembly-CSharp/_Emulator/DATA/shopCategory.txt @@ -0,0 +1,1231 @@ +itemCode,isNew,isHot,isVisible,starRate,isSpecialOffer,isOfferOnce,isGiftable,ispromo,rebuyInvisible,minimumForcePointLevel,minimumTokenLevel +aaa,0,0,1,100,0,0,1,0,0,0,0 +aab,0,0,1,100,0,0,1,0,0,0,0 +aac,0,0,1,100,0,0,1,0,0,0,0 +aad,0,0,1,100,0,0,1,0,0,0,0 +aae,0,0,1,100,0,0,1,0,0,0,0 +aaf,0,0,1,100,0,0,1,0,0,0,0 +aag,0,0,1,100,0,0,1,0,0,0,0 +aah,0,0,1,100,0,0,1,0,0,0,0 +aai,0,0,1,100,0,0,1,0,0,0,0 +aaj,0,0,1,100,0,0,1,0,0,0,0 +aak,0,0,1,100,0,0,1,0,0,0,0 +aal,0,0,1,100,0,0,1,0,0,0,0 +aam,0,0,1,100,0,0,1,0,0,0,0 +aan,0,0,1,100,0,0,1,0,0,0,0 +aao,0,0,1,100,0,0,1,0,0,0,0 +aap,0,0,1,100,0,0,1,0,0,0,0 +aaq,0,0,1,100,0,0,1,0,0,0,0 +aar,0,0,1,100,0,0,1,0,0,0,0 +aas,0,0,1,100,0,0,1,0,0,0,0 +aat,0,0,1,100,0,0,1,0,0,0,0 +aau,0,0,1,100,0,0,1,0,0,0,0 +aav,0,0,1,100,0,0,1,0,0,0,0 +aaw,0,0,1,100,0,0,1,0,0,0,0 +aax,0,0,1,100,0,0,1,0,0,0,0 +aay,0,0,1,100,0,0,1,0,0,0,0 +aaz,0,0,1,100,0,0,1,0,0,0,0 +aba,0,0,1,100,0,0,1,0,0,0,0 +abb,0,0,1,100,0,0,1,0,0,0,0 +abc,0,0,1,100,0,0,1,0,0,0,0 +abd,0,0,1,100,0,0,1,0,0,0,0 +abe,0,0,1,100,0,0,1,0,0,0,0 +abf,0,0,1,100,0,0,1,0,0,0,0 +abg,0,0,1,100,0,0,1,0,0,0,0 +abh,0,0,1,100,0,0,1,0,0,0,0 +abi,0,0,1,100,0,0,1,0,0,0,0 +abj,0,0,1,100,0,0,1,0,0,0,0 +abk,0,0,1,100,0,0,1,0,0,0,0 +abl,0,0,1,100,0,0,1,0,0,0,0 +abm,0,0,1,100,0,0,1,0,0,0,0 +abn,0,0,1,100,0,0,1,0,0,0,0 +abo,0,0,1,100,0,0,1,0,0,0,0 +abp,0,0,1,100,0,0,1,0,0,0,0 +abq,0,0,1,100,0,0,1,0,0,0,0 +abr,0,0,1,100,0,0,1,0,0,0,0 +abs,0,0,1,100,0,0,1,0,0,0,0 +abt,0,0,1,100,0,0,1,0,0,0,0 +abu,0,0,1,100,0,0,1,0,0,0,0 +abv,0,0,1,100,0,0,1,0,0,0,0 +abw,0,0,1,100,0,0,1,0,0,0,0 +abx,0,0,1,100,0,0,1,0,0,0,0 +aby,0,0,1,100,0,0,1,0,0,0,0 +abz,0,0,1,100,0,0,1,0,0,0,0 +aca,0,0,1,100,0,0,1,0,0,0,0 +acb,0,0,1,100,0,0,1,0,0,0,0 +acc,0,0,1,100,0,0,1,0,0,0,0 +acd,0,0,1,100,0,0,1,0,0,0,0 +ace,0,0,1,100,0,0,1,0,0,0,0 +acf,0,0,1,100,0,0,1,0,0,0,0 +acg,0,0,1,100,0,0,1,0,0,0,0 +ach,0,0,1,100,0,0,1,0,0,0,0 +aci,0,0,1,100,0,0,1,0,0,0,0 +acj,0,0,1,100,0,0,1,0,0,0,0 +ack,0,0,1,100,0,0,1,0,0,0,0 +acl,0,0,1,100,0,0,1,0,0,0,0 +acm,0,0,1,100,0,0,1,0,0,0,0 +acn,0,0,1,100,0,0,1,0,0,0,0 +aco,0,0,1,100,0,0,1,0,0,0,0 +acp,0,0,1,100,0,0,1,0,0,0,0 +acq,0,0,1,100,0,0,1,0,0,0,0 +acr,0,0,1,100,0,0,1,0,0,0,0 +acs,0,0,1,100,0,0,1,0,0,0,0 +act,0,0,1,100,0,0,1,0,0,0,0 +acu,0,0,1,100,0,0,1,0,0,0,0 +acv,0,0,1,100,0,0,1,0,0,0,0 +acw,0,0,1,100,0,0,1,0,0,0,0 +acx,0,0,1,100,0,0,1,0,0,0,0 +acy,0,0,1,100,0,0,1,0,0,0,0 +acz,0,0,1,100,0,0,1,0,0,0,0 +ada,0,0,1,100,0,0,1,0,0,0,0 +adb,0,0,1,100,0,0,1,0,0,0,0 +adc,0,0,1,100,0,0,1,0,0,0,0 +add,0,0,1,100,0,0,1,0,0,0,0 +ade,0,0,1,100,0,0,1,0,0,0,0 +adf,0,0,1,100,0,0,1,0,0,0,0 +adg,0,0,1,100,0,0,1,0,0,0,0 +adh,0,0,1,100,0,0,1,0,0,0,0 +adi,0,0,1,100,0,0,1,0,0,0,0 +adj,0,0,1,100,0,0,1,0,0,0,0 +adk,0,0,1,100,0,0,1,0,0,0,0 +adl,0,0,1,100,0,0,1,0,0,0,0 +adm,0,0,1,100,0,0,1,0,0,0,0 +adn,0,0,1,100,0,0,1,0,0,0,0 +ado,0,0,1,100,0,0,1,0,0,0,0 +adp,0,0,1,100,0,0,1,0,0,0,0 +adq,0,0,1,100,0,0,1,0,0,0,0 +adr,0,0,1,100,0,0,1,0,0,0,0 +ads,0,0,1,100,0,0,1,0,0,0,0 +adt,0,0,1,100,0,0,1,0,0,0,0 +adu,0,0,1,100,0,0,1,0,0,0,0 +adw,0,0,1,100,0,0,1,0,0,0,0 +adx,0,0,1,100,0,0,1,0,0,0,0 +ady,0,0,1,100,0,0,1,0,0,0,0 +adz,0,0,1,100,0,0,1,0,0,0,0 +aea,0,0,1,100,0,0,1,0,0,0,0 +aeb,0,0,1,100,0,0,1,0,0,0,0 +aec,0,0,1,100,0,0,1,0,0,0,0 +aed,0,0,1,100,0,0,1,0,0,0,0 +aee,0,0,1,100,0,0,1,0,0,0,0 +aef,0,0,1,100,0,0,1,0,0,0,0 +aeg,0,0,1,100,0,0,1,0,0,0,0 +aeh,0,0,1,100,0,0,1,0,0,0,0 +aei,0,0,1,100,0,0,1,0,0,0,0 +aej,0,0,1,100,0,0,1,0,0,0,0 +aek,0,0,1,100,0,0,1,0,0,0,0 +ael,0,0,1,100,0,0,1,0,0,0,0 +aem,0,0,1,100,0,0,1,0,0,0,0 +aen,0,0,1,100,0,0,1,0,0,0,0 +aeo,0,0,1,100,0,0,1,0,0,0,0 +aep,0,0,1,100,0,0,1,0,0,0,0 +aeq,0,0,1,100,0,0,1,0,0,0,0 +aer,0,0,1,100,0,0,1,0,0,0,0 +aes,0,0,1,100,0,0,1,0,0,0,0 +aet,0,0,1,100,0,0,1,0,0,0,0 +aeu,0,0,1,100,0,0,1,0,0,0,0 +aew,0,0,1,100,0,0,1,0,0,0,0 +aex,0,0,1,100,0,0,1,0,0,0,0 +aey,0,0,1,100,0,0,1,0,0,0,0 +aez,0,0,1,100,0,0,1,0,0,0,0 +afa,0,0,1,100,0,0,1,0,0,0,0 +aff,0,0,1,100,0,0,1,0,0,0,0 +afg,0,0,1,100,0,0,1,0,0,0,0 +afh,0,0,1,100,0,0,1,0,0,0,0 +afi,0,0,1,100,0,0,1,0,0,0,0 +afj,0,0,1,100,0,0,1,0,0,0,0 +afk,0,0,1,100,0,0,1,0,0,0,0 +afl,0,0,1,100,0,0,1,0,0,0,0 +afm,0,0,1,100,0,0,1,0,0,0,0 +afb,0,0,1,100,0,0,1,0,0,0,0 +afc,0,0,1,100,0,0,1,0,0,0,0 +afd,0,0,1,100,0,0,1,0,0,0,0 +afe,0,0,1,100,0,0,1,0,0,0,0 +afo,0,0,1,100,0,0,1,0,0,0,0 +afp,0,0,1,100,0,0,1,0,0,0,0 +afq,0,0,1,100,0,0,1,0,0,0,0 +afr,0,0,1,100,0,0,1,0,0,0,0 +afs,0,0,1,100,0,0,1,0,0,0,0 +aft,0,0,1,100,0,0,1,0,0,0,0 +afu,0,0,1,100,0,0,1,0,0,0,0 +afw,0,0,1,100,0,0,1,0,0,0,0 +afx,0,0,1,100,0,0,1,0,0,0,0 +afy,0,0,1,100,0,0,1,0,0,0,0 +afz,0,0,1,100,0,0,1,0,0,0,0 +aga,0,0,1,100,0,0,1,0,0,0,0 +agb,0,0,1,100,0,0,1,0,0,0,0 +agc,0,0,1,100,0,0,1,0,0,0,0 +agd,0,0,1,100,0,0,1,0,0,0,0 +age,0,0,1,100,0,0,1,0,0,0,0 +agf,0,0,1,100,0,0,1,0,0,0,0 +agg,0,0,1,100,0,0,1,0,0,0,0 +agh,0,0,1,100,0,0,1,0,0,0,0 +agi,0,0,1,100,0,0,1,0,0,0,0 +agj,0,0,1,100,0,0,1,0,0,0,0 +agk,0,0,1,100,0,0,1,0,0,0,0 +agl,0,0,1,100,0,0,1,0,0,0,0 +agm,0,0,1,100,0,0,1,0,0,0,0 +agn,0,0,1,100,0,0,1,0,0,0,0 +ago,0,0,1,100,0,0,1,0,0,0,0 +agp,0,0,1,100,0,0,1,0,0,0,0 +agq,0,0,1,100,0,0,1,0,0,0,0 +agr,0,0,1,100,0,0,1,0,0,0,0 +ags,0,0,1,100,0,0,1,0,0,0,0 +agt,0,0,1,100,0,0,1,0,0,0,0 +agu,0,0,1,100,0,0,1,0,0,0,0 +agv,0,0,1,100,0,0,1,0,0,0,0 +agw,0,0,1,100,0,0,1,0,0,0,0 +agx,0,0,1,100,0,0,1,0,0,0,0 +agy,0,0,1,100,0,0,1,0,0,0,0 +agz,0,0,1,100,0,0,1,0,0,0,0 +aha,0,0,1,100,0,0,1,0,0,0,0 +ahb,0,0,1,100,0,0,1,0,0,0,0 +ahc,0,0,1,100,0,0,1,0,0,0,0 +ahd,0,0,1,100,0,0,1,0,0,0,0 +ahe,0,0,1,100,0,0,1,0,0,0,0 +ahf,0,0,1,100,0,0,1,0,0,0,0 +ahg,0,0,1,100,0,0,1,0,0,0,0 +ahh,0,0,1,100,0,0,1,0,0,0,0 +ahi,0,0,1,100,0,0,1,0,0,0,0 +ahj,0,0,1,100,0,0,1,0,0,0,0 +ahk,0,0,1,100,0,0,1,0,0,0,0 +ahl,0,0,1,100,0,0,1,0,0,0,0 +ahm,0,0,1,100,0,0,1,0,0,0,0 +ahn,0,0,1,100,0,0,1,0,0,0,0 +aho,0,0,1,100,0,0,1,0,0,0,0 +ahp,0,0,1,100,0,0,1,0,0,0,0 +ahq,0,0,1,100,0,0,1,0,0,0,0 +ahr,0,0,1,100,0,0,1,0,0,0,0 +ahs,0,0,1,100,0,0,1,0,0,0,0 +aht,0,0,1,100,0,0,1,0,0,0,0 +ahu,0,0,1,100,0,0,1,0,0,0,0 +ahv,0,0,1,100,0,0,1,0,0,0,0 +ahw,0,0,1,100,0,0,1,0,0,0,0 +ahx,0,0,1,100,0,0,1,0,0,0,0 +ahy,0,0,1,100,0,0,1,0,0,0,0 +ahz,0,0,1,100,0,0,1,0,0,0,0 +aia,0,0,1,100,0,0,1,0,0,0,0 +aib,0,0,1,100,0,0,1,0,0,0,0 +aic,0,0,1,100,0,0,1,0,0,0,0 +aid,0,0,1,100,0,0,1,0,0,0,0 +aie,0,0,1,100,0,0,1,0,0,0,0 +aif,0,0,1,100,0,0,1,0,0,0,0 +aig,0,0,1,100,0,0,1,0,0,0,0 +aih,0,0,1,100,0,0,1,0,0,0,0 +aii,0,0,1,100,0,0,1,0,0,0,0 +aij,0,0,1,100,0,0,1,0,0,0,0 +aik,0,0,1,100,0,0,1,0,0,0,0 +ail,0,0,1,100,0,0,1,0,0,0,0 +aim,0,0,1,100,0,0,1,0,0,0,0 +ain,0,0,1,100,0,0,1,0,0,0,0 +aio,0,0,1,100,0,0,1,0,0,0,0 +aip,0,0,1,100,0,0,1,0,0,0,0 +aiq,0,0,1,100,0,0,1,0,0,0,0 +air,0,0,1,100,0,0,1,0,0,0,0 +ais,0,0,1,100,0,0,1,0,0,0,0 +ait,0,0,1,100,0,0,1,0,0,0,0 +aiu,0,0,1,100,0,0,1,0,0,0,0 +aiv,0,0,1,100,0,0,1,0,0,0,0 +aiw,0,0,1,100,0,0,1,0,0,0,0 +aix,0,0,1,100,0,0,1,0,0,0,0 +aiy,0,0,1,100,0,0,1,0,0,0,0 +aiz,0,0,1,100,0,0,1,0,0,0,0 +aja,0,0,1,100,0,0,1,0,0,0,0 +ajb,0,0,1,100,0,0,1,0,0,0,0 +ajc,0,0,1,100,0,0,1,0,0,0,0 +ajd,0,0,1,100,0,0,1,0,0,0,0 +aje,0,0,1,100,0,0,1,0,0,0,0 +ajf,0,0,1,100,0,0,1,0,0,0,0 +ajg,0,0,1,100,0,0,1,0,0,0,0 +ajh,0,0,1,100,0,0,1,0,0,0,0 +aji,0,0,1,100,0,0,1,0,0,0,0 +ajj,0,0,1,100,0,0,1,0,0,0,0 +ajk,0,0,1,100,0,0,1,0,0,0,0 +ajl,0,0,1,100,0,0,1,0,0,0,0 +ajm,0,0,1,100,0,0,1,0,0,0,0 +ajn,0,0,1,100,0,0,1,0,0,0,0 +ajo,0,0,1,100,0,0,1,0,0,0,0 +ajp,0,0,1,100,0,0,1,0,0,0,0 +ajq,0,0,1,100,0,0,1,0,0,0,0 +ajr,0,0,1,100,0,0,1,0,0,0,0 +ajs,0,0,1,100,0,0,1,0,0,0,0 +ajt,0,0,1,100,0,0,1,0,0,0,0 +aju,0,0,1,100,0,0,1,0,0,0,0 +ajv,0,0,1,100,0,0,1,0,0,0,0 +ajw,0,0,1,100,0,0,1,0,0,0,0 +ajx,0,0,1,100,0,0,1,0,0,0,0 +ajy,0,0,1,100,0,0,1,0,0,0,0 +ajz,0,0,1,100,0,0,1,0,0,0,0 +aka,0,0,1,100,0,0,1,0,0,0,0 +akb,0,0,1,100,0,0,1,0,0,0,0 +akc,0,0,1,100,0,0,1,0,0,0,0 +akd,0,0,1,100,0,0,1,0,0,0,0 +ake,0,0,1,100,0,0,1,0,0,0,0 +akf,0,0,1,100,0,0,1,0,0,0,0 +akg,0,0,1,100,0,0,1,0,0,0,0 +akh,0,0,1,100,0,0,1,0,0,0,0 +aki,0,0,1,100,0,0,1,0,0,0,0 +akj,0,0,1,100,0,0,1,0,0,0,0 +akk,0,0,1,100,0,0,1,0,0,0,0 +akl,0,0,1,100,0,0,1,0,0,0,0 +akm,0,0,1,100,0,0,1,0,0,0,0 +akn,0,0,1,100,0,0,1,0,0,0,0 +ako,0,0,1,100,0,0,1,0,0,0,0 +akp,0,0,1,100,0,0,1,0,0,0,0 +akq,0,0,1,100,0,0,1,0,0,0,0 +akr,0,0,1,100,0,0,1,0,0,0,0 +aks,0,0,1,100,0,0,1,0,0,0,0 +akt,0,0,1,100,0,0,1,0,0,0,0 +waa,0,0,1,100,0,0,1,0,0,0,0 +wab,0,0,1,100,0,0,1,0,0,0,0 +wad,0,0,1,100,0,0,1,0,0,0,0 +wae,0,0,1,100,0,0,1,0,0,0,0 +waf,0,0,1,100,0,0,1,0,0,0,0 +wag,0,0,1,100,0,0,1,0,0,0,0 +wah,0,0,1,100,0,0,1,0,0,0,0 +wai,0,0,1,100,0,0,1,0,0,0,0 +waj,0,0,1,100,0,0,1,0,0,0,0 +wak,0,0,1,100,0,0,1,0,0,0,0 +wal,0,0,1,100,0,0,1,0,0,0,0 +wao,0,0,1,100,0,0,1,0,0,0,0 +wap,0,0,1,100,0,0,1,0,0,0,0 +waq,0,0,1,100,0,0,1,0,0,0,0 +war,0,0,1,100,0,0,1,0,0,0,0 +was,0,0,1,100,0,0,1,0,0,0,0 +wat,0,0,1,100,0,0,1,0,0,0,0 +wau,0,0,1,100,0,0,1,0,0,0,0 +wav,0,0,1,100,0,0,1,0,0,0,0 +waw,0,0,1,100,0,0,1,0,0,0,0 +wax,0,0,1,100,0,0,1,0,0,0,0 +way,0,0,1,100,0,0,1,0,0,0,0 +waz,0,0,1,100,0,0,1,0,0,0,0 +wbb,0,0,1,100,0,0,1,0,0,0,0 +wbc,0,0,1,100,0,0,1,0,0,0,0 +wbd,1,0,1,120,0,0,1,0,0,0,0 +wbe,0,0,1,100,0,0,1,0,0,0,0 +wbf,0,0,1,100,0,0,1,0,0,0,0 +wbg,0,0,1,100,0,0,1,0,0,0,0 +wbh,0,0,1,100,0,0,1,0,0,0,0 +wbi,0,0,1,100,0,0,1,0,0,0,0 +wbj,0,0,1,100,0,0,1,0,0,0,0 +wbk,0,0,1,100,0,0,1,0,0,0,0 +wbl,0,0,1,100,0,0,1,0,0,0,0 +wbm,0,0,1,100,0,0,1,0,0,0,0 +wbn,0,0,1,100,0,0,1,0,0,0,0 +wbo,0,0,1,100,0,0,1,0,0,0,0 +wbp,0,0,1,100,0,0,1,0,0,0,0 +wbq,0,0,1,100,0,0,1,0,0,0,0 +wbr,0,0,1,100,0,0,1,0,0,0,0 +wbs,0,0,1,100,0,0,1,0,0,0,0 +wbt,0,0,1,100,0,0,1,0,0,0,0 +wbu,0,0,1,100,0,0,1,0,0,0,0 +wbv,0,0,1,100,0,0,1,0,0,0,0 +wbw,0,0,1,100,0,0,1,0,0,0,0 +wbx,0,0,1,100,0,0,1,0,0,0,0 +wbz,0,0,1,100,0,0,1,0,0,0,0 +wca,0,0,1,100,0,0,1,0,0,0,0 +wcb,0,0,1,100,0,0,1,0,0,0,0 +wcc,0,0,1,100,0,0,1,0,0,0,0 +wcd,0,0,1,100,0,0,1,0,0,0,0 +wce,0,0,1,100,0,0,1,0,0,0,0 +wcf,0,0,1,100,0,0,1,0,0,0,0 +wcg,0,0,1,100,0,0,1,0,0,0,0 +wch,0,0,1,100,0,0,1,0,0,0,0 +wci,0,0,1,100,0,0,1,0,0,0,0 +wcj,0,0,1,100,0,0,1,0,0,0,0 +wck,0,0,1,100,0,0,1,0,0,0,0 +wcl,0,0,1,100,0,0,1,0,0,0,0 +wcm,0,0,1,100,0,0,1,0,0,0,0 +wcn,0,0,1,100,0,0,1,0,0,0,0 +wco,0,0,1,100,0,0,1,0,0,0,0 +wcp,0,0,1,100,0,0,1,0,0,0,0 +wcq,0,0,1,100,0,0,1,0,0,0,0 +wcr,0,0,1,100,0,0,1,0,0,0,0 +wcs,0,0,1,100,0,0,1,0,0,0,0 +wct,0,0,1,100,0,0,1,0,0,0,0 +wcu,0,0,1,100,0,0,1,0,0,0,0 +wcv,0,0,1,100,0,0,1,0,0,0,0 +wcw,0,0,1,100,0,0,1,0,0,0,0 +wcx,0,0,1,100,0,0,1,0,0,0,0 +wcy,0,0,1,100,0,0,1,0,0,0,0 +wcz,0,0,1,100,0,0,1,0,0,0,0 +wda,0,0,1,100,0,0,1,0,0,0,0 +wdb,0,0,1,100,0,0,1,0,0,0,0 +wdc,0,0,1,100,0,0,1,0,0,0,0 +wdd,0,0,1,100,0,0,1,0,0,0,0 +wde,0,0,1,100,0,0,1,0,0,0,0 +wdf,0,0,1,100,0,0,1,0,0,0,0 +wdg,0,0,1,100,0,0,1,0,0,0,0 +wdh,0,0,1,100,0,0,1,0,0,0,0 +wdi,0,0,1,100,0,0,1,0,0,0,0 +wdj,0,0,1,100,0,0,1,0,0,0,0 +wdk,0,0,1,100,0,0,1,0,0,0,0 +wdl,0,0,1,100,0,0,1,0,0,0,0 +wdm,0,0,1,100,0,0,1,0,0,0,0 +wdn,0,0,1,100,0,0,1,0,0,0,0 +wdo,0,0,1,100,0,0,1,0,0,0,0 +wdp,0,0,1,100,0,0,1,0,0,0,0 +wdq,0,0,1,100,0,0,1,0,0,0,0 +wdr,0,0,1,100,0,0,1,0,0,0,0 +wds,0,0,1,100,0,0,1,0,0,0,0 +wdt,0,0,1,100,0,0,1,0,0,0,0 +wdu,0,0,1,100,0,0,1,0,0,0,0 +wdw,0,0,1,100,0,0,1,0,0,0,0 +wdx,0,0,1,100,0,0,1,0,0,0,0 +wdy,0,0,1,100,0,0,1,0,0,0,0 +wdz,0,0,1,100,0,0,1,0,0,0,0 +wea,0,0,1,100,0,0,1,0,0,0,0 +web,0,0,1,100,0,0,1,0,0,0,0 +wec,0,0,1,100,0,0,1,0,0,0,0 +wed,0,0,1,100,0,0,1,0,0,0,0 +wee,0,0,1,100,0,0,1,0,0,0,0 +wef,0,0,1,100,0,0,1,0,0,0,0 +weg,0,0,1,100,0,0,1,0,0,0,0 +weh,0,0,1,100,0,0,1,0,0,0,0 +wei,0,0,1,100,0,0,1,0,0,0,0 +wej,0,0,1,100,0,0,1,0,0,0,0 +wek,0,0,1,100,0,0,1,0,0,0,0 +wem,0,0,1,100,0,0,1,0,0,0,0 +wen,0,0,1,100,0,0,1,0,0,0,0 +wel,0,0,1,100,0,0,1,0,0,0,0 +weo,0,0,1,100,0,0,1,0,0,0,0 +wep,0,0,1,100,0,0,1,0,0,0,0 +weq,0,0,1,100,0,0,1,0,0,0,0 +wew,0,0,1,100,0,0,1,0,0,0,0 +wex,0,0,1,100,0,0,1,0,0,0,0 +wey,0,0,1,100,0,0,1,0,0,0,0 +wez,0,0,1,100,0,0,1,0,0,0,0 +wfa,0,0,1,100,0,0,1,0,0,0,0 +wfb,0,0,1,100,0,0,1,0,0,0,0 +wfc,0,0,1,100,0,0,1,0,0,0,0 +weu,0,0,1,100,0,0,1,0,0,0,0 +wes,0,0,1,100,0,0,1,0,0,0,0 +wet,0,0,1,100,0,0,1,0,0,0,0 +wer,0,0,1,100,0,0,1,0,0,0,0 +wev,0,0,1,100,0,0,1,0,0,0,0 +wfd,0,0,1,100,0,0,1,0,0,0,0 +wfe,0,0,1,100,0,0,1,0,0,0,0 +wff,0,0,1,100,0,0,1,0,0,0,0 +wfg,0,0,1,100,0,0,1,0,0,0,0 +wfh,0,0,1,100,0,0,1,0,0,0,0 +wfi,0,0,1,100,0,0,1,0,0,0,0 +wfj,0,0,1,100,0,0,1,0,0,0,0 +wfk,0,0,1,100,0,0,1,0,0,0,0 +wfl,0,0,1,100,0,0,1,0,0,0,0 +wfm,0,0,1,100,0,0,1,0,0,0,0 +wfn,0,0,1,100,0,0,1,0,0,0,0 +wfo,0,0,1,100,0,0,1,0,0,0,0 +wfp,0,0,1,100,0,0,1,0,0,0,0 +wfq,0,0,1,100,0,0,1,0,0,0,0 +wfr,0,0,1,100,0,0,1,0,0,0,0 +wfs,0,0,1,100,0,0,1,0,0,0,0 +wft,0,0,1,100,0,0,1,0,0,0,0 +wfu,0,0,1,100,0,0,1,0,0,0,0 +wfv,0,0,1,100,0,0,1,0,0,0,0 +wfw,0,0,1,100,0,0,1,0,0,0,0 +wfx,0,0,1,100,0,0,1,0,0,0,0 +wfy,0,0,1,100,0,0,1,0,0,0,0 +wfz,0,0,1,100,0,0,1,0,0,0,0 +wga,0,0,1,100,0,0,1,0,0,0,0 +wgb,0,0,1,100,0,0,1,0,0,0,0 +wgc,0,0,1,100,0,0,1,0,0,0,0 +wgd,0,0,1,100,0,0,1,0,0,0,0 +wge,0,0,1,100,0,0,1,0,0,0,0 +wgf,0,0,1,100,0,0,1,0,0,0,0 +wgg,0,0,1,100,0,0,1,0,0,0,0 +wgh,0,0,1,100,0,0,1,0,0,0,0 +wgi,0,0,1,100,0,0,1,0,0,0,0 +wgj,0,0,1,100,0,0,1,0,0,0,0 +wgk,0,0,1,100,0,0,1,0,0,0,0 +wgl,0,0,1,100,0,0,1,0,0,0,0 +wgm,0,0,1,100,0,0,1,0,0,0,0 +wgn,0,0,1,100,0,0,1,0,0,0,0 +wgo,0,0,1,100,0,0,1,0,0,0,0 +wgp,0,0,1,100,0,0,1,0,0,0,0 +wgq,0,0,1,100,0,0,1,0,0,0,0 +wgr,0,0,1,100,0,0,1,0,0,0,0 +wgs,0,0,1,100,0,0,1,0,0,0,0 +wgt,0,0,1,100,0,0,1,0,0,0,0 +wgu,0,0,1,100,0,0,1,0,0,0,0 +wgv,0,0,1,100,0,0,1,0,0,0,0 +wgw,0,0,1,100,0,0,1,0,0,0,0 +wgx,0,0,1,100,0,0,1,0,0,0,0 +wgy,0,0,1,100,0,0,1,0,0,0,0 +wgz,0,0,1,100,0,0,1,0,0,0,0 +wha,0,0,1,100,0,0,1,0,0,0,0 +whb,0,0,1,100,0,0,1,0,0,0,0 +whc,0,0,1,100,0,0,1,0,0,0,0 +whd,0,0,1,100,0,0,1,0,0,0,0 +whe,0,0,1,100,0,0,1,0,0,0,0 +whf,0,0,1,100,0,0,1,0,0,0,0 +whg,0,0,1,100,0,0,1,0,0,0,0 +whh,0,0,1,100,0,0,1,0,0,0,0 +whi,0,0,1,100,0,0,1,0,0,0,0 +whj,0,0,1,100,0,0,1,0,0,0,0 +whk,0,0,1,100,0,0,1,0,0,0,0 +whl,0,0,1,100,0,0,1,0,0,0,0 +whm,0,0,1,100,0,0,1,0,0,0,0 +whn,0,0,1,100,0,0,1,0,0,0,0 +who,0,0,1,100,0,0,1,0,0,0,0 +whp,0,0,1,100,0,0,1,0,0,0,0 +whq,0,0,1,100,0,0,1,0,0,0,0 +whr,0,0,1,100,0,0,1,0,0,0,0 +whs,0,0,1,100,0,0,1,0,0,0,0 +wht,0,0,1,100,0,0,1,0,0,0,0 +whu,0,0,1,100,0,0,1,0,0,0,0 +whv,0,0,1,100,0,0,1,0,0,0,0 +whw,0,0,1,100,0,0,1,0,0,0,0 +whx,0,0,1,100,0,0,1,0,0,0,0 +why,0,0,1,100,0,0,1,0,0,0,0 +whz,0,0,1,100,0,0,1,0,0,0,0 +wia,0,0,1,100,0,0,1,0,0,0,0 +wib,0,0,1,100,0,0,1,0,0,0,0 +wic,0,0,1,100,0,0,1,0,0,0,0 +wid,0,0,1,100,0,0,1,0,0,0,0 +wie,0,0,1,100,0,0,1,0,0,0,0 +wif,0,0,1,100,0,0,1,0,0,0,0 +wig,0,0,1,100,0,0,1,0,0,0,0 +wih,0,0,1,100,0,0,1,0,0,0,0 +wii,0,0,1,100,0,0,1,0,0,0,0 +wij,0,0,1,100,0,0,1,0,0,0,0 +wik,0,0,1,100,0,0,1,0,0,0,0 +wil,0,0,1,100,0,0,1,0,0,0,0 +wim,0,0,1,100,0,0,1,0,0,0,0 +win,0,0,1,100,0,0,1,0,0,0,0 +wio,0,0,1,100,0,0,1,0,0,0,0 +wip,0,0,1,100,0,0,1,0,0,0,0 +wiq,0,0,1,100,0,0,1,0,0,0,0 +wir,0,0,1,100,0,0,1,0,0,0,0 +wis,0,0,1,100,0,0,1,0,0,0,0 +wit,0,0,1,100,0,0,1,0,0,0,0 +wiu,0,0,1,100,0,0,1,0,0,0,0 +wiv,0,0,1,100,0,0,1,0,0,0,0 +wiw,0,0,1,100,0,0,1,0,0,0,0 +wix,0,0,1,100,0,0,1,0,0,0,0 +wiy,0,0,1,100,0,0,1,0,0,0,0 +wiz,0,0,1,100,0,0,1,0,0,0,0 +wja,0,0,1,100,0,0,1,0,0,0,0 +wjb,0,0,1,100,0,0,1,0,0,0,0 +wjc,0,0,1,100,0,0,1,0,0,0,0 +wjd,0,0,1,100,0,0,1,0,0,0,0 +wje,0,0,1,100,0,0,1,0,0,0,0 +wjf,0,0,1,100,0,0,1,0,0,0,0 +wjg,0,0,1,100,0,0,1,0,0,0,0 +wjh,0,0,1,100,0,0,1,0,0,0,0 +wji,0,0,1,100,0,0,1,0,0,0,0 +wjj,0,0,1,100,0,0,1,0,0,0,0 +wjk,0,0,1,100,0,0,1,0,0,0,0 +wjl,0,0,1,100,0,0,1,0,0,0,0 +wjm,0,0,1,100,0,0,1,0,0,0,0 +wjn,0,0,1,100,0,0,1,0,0,0,0 +wjo,0,0,1,100,0,0,1,0,0,0,0 +wjp,0,0,1,100,0,0,1,0,0,0,0 +wjq,0,0,1,100,0,0,1,0,0,0,0 +wjr,0,0,1,100,0,0,1,0,0,0,0 +wjs,0,0,1,100,0,0,1,0,0,0,0 +wjt,0,0,1,100,0,0,1,0,0,0,0 +wju,0,0,1,100,0,0,1,0,0,0,0 +wjv,0,0,1,100,0,0,1,0,0,0,0 +wjw,0,0,1,100,0,0,1,0,0,0,0 +wjx,0,0,1,100,0,0,1,0,0,0,0 +wjy,0,0,1,100,0,0,1,0,0,0,0 +wjz,0,0,1,100,0,0,1,0,0,0,0 +wka,0,0,1,100,0,0,1,0,0,0,0 +wkb,0,0,1,100,0,0,1,0,0,0,0 +wkc,0,0,1,100,0,0,1,0,0,0,0 +wkd,0,0,1,100,0,0,1,0,0,0,0 +wke,0,0,1,100,0,0,1,0,0,0,0 +wkf,0,0,1,100,0,0,1,0,0,0,0 +wkg,0,0,1,100,0,0,1,0,0,0,0 +wkh,0,0,1,100,0,0,1,0,0,0,0 +wki,0,0,1,100,0,0,1,0,0,0,0 +wkj,0,0,1,100,0,0,1,0,0,0,0 +wkk,0,0,1,100,0,0,1,0,0,0,0 +wkl,0,0,1,100,0,0,1,0,0,0,0 +wkm,0,0,1,100,0,0,1,0,0,0,0 +wkn,0,0,1,100,0,0,1,0,0,0,0 +wko,0,0,1,100,0,0,1,0,0,0,0 +wkp,0,0,1,100,0,0,1,0,0,0,0 +wkq,0,0,1,100,0,0,1,0,0,0,0 +wkr,0,0,1,100,0,0,1,0,0,0,0 +wks,0,0,1,100,0,0,1,0,0,0,0 +wkt,0,0,1,100,0,0,1,0,0,0,0 +wku,0,0,1,100,0,0,1,0,0,0,0 +wkv,0,0,1,100,0,0,1,0,0,0,0 +wkw,0,0,1,100,0,0,1,0,0,0,0 +wkx,0,0,1,100,0,0,1,0,0,0,0 +wky,0,0,1,100,0,0,1,0,0,0,0 +wkz,0,0,1,100,0,0,1,0,0,0,0 +wla,0,0,1,100,0,0,1,0,0,0,0 +wlb,0,0,1,100,0,0,1,0,0,0,0 +wlc,0,0,1,100,0,0,1,0,0,0,0 +wld,0,0,1,100,0,0,1,0,0,0,0 +wle,0,0,1,100,0,0,1,0,0,0,0 +wlf,0,0,1,100,0,0,1,0,0,0,0 +wlg,0,0,1,100,0,0,1,0,0,0,0 +wlh,0,0,1,100,0,0,1,0,0,0,0 +wli,0,0,1,100,0,0,1,0,0,0,0 +wlj,0,0,1,100,0,0,1,0,0,0,0 +wlk,0,0,1,100,0,0,1,0,0,0,0 +wll,0,0,1,100,0,0,1,0,0,0,0 +wlm,0,0,1,100,0,0,1,0,0,0,0 +wln,0,0,1,100,0,0,1,0,0,0,0 +wlo,0,0,1,100,0,0,1,0,0,0,0 +wlp,0,0,1,100,0,0,1,0,0,0,0 +wlq,0,0,1,100,0,0,1,0,0,0,0 +wlr,0,0,1,100,0,0,1,0,0,0,0 +wls,0,0,1,100,0,0,1,0,0,0,0 +wlt,0,0,1,100,0,0,1,0,0,0,0 +wlu,0,0,1,100,0,0,1,0,0,0,0 +wlv,0,0,1,100,0,0,1,0,0,0,0 +wlw,0,0,1,100,0,0,1,0,0,0,0 +wlx,0,0,1,100,0,0,1,0,0,0,0 +wly,0,0,1,100,0,0,1,0,0,0,0 +wlz,0,0,1,100,0,0,1,0,0,0,0 +wma,0,0,1,100,0,0,1,0,0,0,0 +wmb,0,0,1,100,0,0,1,0,0,0,0 +wmc,0,0,1,100,0,0,1,0,0,0,0 +wmd,0,0,1,100,0,0,1,0,0,0,0 +wme,0,0,1,100,0,0,1,0,0,0,0 +wmf,0,0,1,100,0,0,1,0,0,0,0 +wmg,0,0,1,100,0,0,1,0,0,0,0 +wmh,0,0,1,100,0,0,1,0,0,0,0 +wmi,0,0,1,100,0,0,1,0,0,0,0 +wmj,0,0,1,100,0,0,1,0,0,0,0 +wmk,0,0,1,100,0,0,1,0,0,0,0 +wml,0,0,1,100,0,0,1,0,0,0,0 +wmm,0,0,1,100,0,0,1,0,0,0,0 +wmn,0,0,1,100,0,0,1,0,0,0,0 +wmo,0,0,1,100,0,0,1,0,0,0,0 +wmp,0,0,1,100,0,0,1,0,0,0,0 +wmq,0,0,1,100,0,0,1,0,0,0,0 +wmr,0,0,1,100,0,0,1,0,0,0,0 +wms,0,0,1,100,0,0,1,0,0,0,0 +wmt,0,0,1,100,0,0,1,0,0,0,0 +wmu,0,0,1,100,0,0,1,0,0,0,0 +wmv,0,0,1,100,0,0,1,0,0,0,0 +wmw,0,0,1,100,0,0,1,0,0,0,0 +wmx,0,0,1,100,0,0,1,0,0,0,0 +wmy,0,0,1,100,0,0,1,0,0,0,0 +wmz,0,0,1,100,0,0,1,0,0,0,0 +wna,0,0,1,100,0,0,1,0,0,0,0 +wnb,0,0,1,100,0,0,1,0,0,0,0 +wnc,0,0,1,100,0,0,1,0,0,0,0 +wnd,0,0,1,100,0,0,1,0,0,0,0 +wne,0,0,1,100,0,0,1,0,0,0,0 +wnf,0,0,1,100,0,0,1,0,0,0,0 +wng,0,0,1,100,0,0,1,0,0,0,0 +wnh,0,0,1,100,0,0,1,0,0,0,0 +wni,0,0,1,100,0,0,1,0,0,0,0 +wnj,0,0,1,100,0,0,1,0,0,0,0 +wnk,0,0,1,100,0,0,1,0,0,0,0 +wnl,0,0,1,100,0,0,1,0,0,0,0 +wnm,0,0,1,100,0,0,1,0,0,0,0 +wnn,0,0,1,100,0,0,1,0,0,0,0 +wno,0,0,1,100,0,0,1,0,0,0,0 +wnp,0,0,1,100,0,0,1,0,0,0,0 +wnq,0,0,1,100,0,0,1,0,0,0,0 +wnr,0,0,1,100,0,0,1,0,0,0,0 +wns,0,0,1,100,0,0,1,0,0,0,0 +wnt,0,0,1,100,0,0,1,0,0,0,0 +wnu,0,0,1,100,0,0,1,0,0,0,0 +wnv,0,0,1,100,0,0,1,0,0,0,0 +wnw,0,0,1,100,0,0,1,0,0,0,0 +wnx,0,0,1,100,0,0,1,0,0,0,0 +wny,0,0,1,100,0,0,1,0,0,0,0 +wnz,0,0,1,100,0,0,1,0,0,0,0 +woa,0,0,1,100,0,0,1,0,0,0,0 +wob,0,0,1,100,0,0,1,0,0,0,0 +woc,0,0,1,100,0,0,1,0,0,0,0 +wod,0,0,1,100,0,0,1,0,0,0,0 +woe,0,0,1,100,0,0,1,0,0,0,0 +wof,0,0,1,100,0,0,1,0,0,0,0 +wog,0,0,1,100,0,0,1,0,0,0,0 +woh,0,0,1,100,0,0,1,0,0,0,0 +woi,0,0,1,100,0,0,1,0,0,0,0 +woj,0,0,1,100,0,0,1,0,0,0,0 +wok,0,0,1,100,0,0,1,0,0,0,0 +wol,0,0,1,100,0,0,1,0,0,0,0 +wom,0,0,1,100,0,0,1,0,0,0,0 +won,0,0,1,100,0,0,1,0,0,0,0 +woo,0,0,1,100,0,0,1,0,0,0,0 +wop,0,0,1,100,0,0,1,0,0,0,0 +woq,0,0,1,100,0,0,1,0,0,0,0 +wor,0,0,1,100,0,0,1,0,0,0,0 +wos,0,0,1,100,0,0,1,0,0,0,0 +wot,0,0,1,100,0,0,1,0,0,0,0 +wou,0,0,1,100,0,0,1,0,0,0,0 +wov,0,0,1,100,0,0,1,0,0,0,0 +a01,0,0,1,100,0,0,1,0,0,0,0 +a02,0,0,1,100,0,0,1,0,0,0,0 +a03,0,0,1,100,0,0,1,0,0,0,0 +a04,0,0,1,100,0,0,1,0,0,0,0 +a05,0,0,1,100,0,0,1,0,0,0,0 +a06,0,0,1,100,0,0,1,0,0,0,0 +a07,0,0,1,100,0,0,1,0,0,0,0 +a08,0,0,1,100,0,0,1,0,0,0,0 +a09,0,0,1,100,0,0,1,0,0,0,0 +a10,0,0,1,100,0,0,1,0,0,0,0 +a11,0,0,1,100,0,0,1,0,0,0,0 +a12,0,0,1,100,0,0,1,0,0,0,0 +a13,0,0,1,100,0,0,1,0,0,0,0 +a14,0,0,1,100,0,0,1,0,0,0,0 +a15,0,0,1,100,0,0,1,0,0,0,0 +a16,0,0,1,100,0,0,1,0,0,0,0 +a17,0,0,1,100,0,0,1,0,0,0,0 +a18,0,0,1,100,0,0,1,0,0,0,0 +a19,0,0,1,100,0,0,1,0,0,0,0 +a20,0,0,1,100,0,0,1,0,0,0,0 +a21,0,0,1,100,0,0,1,0,0,0,0 +a22,0,0,1,100,0,0,1,0,0,0,0 +a23,0,0,1,100,0,0,1,0,0,0,0 +a24,0,0,1,100,0,0,1,0,0,0,0 +a25,0,0,1,100,0,0,1,0,0,0,0 +a26,0,0,1,100,0,0,1,0,0,0,0 +a27,0,0,1,100,0,0,1,0,0,0,0 +a28,0,0,1,100,0,0,1,0,0,0,0 +a29,0,0,1,100,0,0,1,0,0,0,0 +a30,0,0,1,100,0,0,1,0,0,0,0 +a31,0,0,1,100,0,0,1,0,0,0,0 +a32,0,0,1,100,0,0,1,0,0,0,0 +a33,0,0,1,100,0,0,1,0,0,0,0 +a34,0,0,1,100,0,0,1,0,0,0,0 +a35,0,0,1,100,0,0,1,0,0,0,0 +a36,0,0,1,100,0,0,1,0,0,0,0 +a37,0,0,1,100,0,0,1,0,0,0,0 +a38,0,0,1,100,0,0,1,0,0,0,0 +a39,0,0,1,100,0,0,1,0,0,0,0 +a40,0,0,1,100,0,0,1,0,0,0,0 +a41,0,0,1,100,0,0,1,0,0,0,0 +a42,0,0,1,100,0,0,1,0,0,0,0 +a43,0,0,1,100,0,0,1,0,0,0,0 +a44,0,0,1,100,0,0,1,0,0,0,0 +a45,0,0,1,100,0,0,1,0,0,0,0 +a46,0,0,1,100,0,0,1,0,0,0,0 +a47,0,0,1,100,0,0,1,0,0,0,0 +a48,0,0,1,100,0,0,1,0,0,0,0 +a49,0,0,1,100,0,0,1,0,0,0,0 +a50,0,0,1,100,0,0,1,0,0,0,0 +a51,0,0,1,100,0,0,1,0,0,0,0 +a52,0,0,1,100,0,0,1,0,0,0,0 +a53,0,0,1,100,0,0,1,0,0,0,0 +a54,0,0,1,100,0,0,1,0,0,0,0 +a55,0,0,1,100,0,0,1,0,0,0,0 +a56,0,0,1,100,0,0,1,0,0,0,0 +a57,0,0,1,100,0,0,1,0,0,0,0 +a58,0,0,1,100,0,0,1,0,0,0,0 +a59,0,0,1,100,0,0,1,0,0,0,0 +a60,0,0,1,100,0,0,1,0,0,0,0 +a61,0,0,1,100,0,0,1,0,0,0,0 +a62,0,0,1,100,0,0,1,0,0,0,0 +a63,0,0,1,100,0,0,1,0,0,0,0 +a64,0,0,1,100,0,0,1,0,0,0,0 +a65,0,0,1,100,0,0,1,0,0,0,0 +a66,0,0,1,100,0,0,1,0,0,0,0 +a67,0,0,1,100,0,0,1,0,0,0,0 +a68,0,0,1,100,0,0,1,0,0,0,0 +a69,0,0,1,100,0,0,1,0,0,0,0 +a70,0,0,1,100,0,0,1,0,0,0,0 +a71,0,0,1,100,0,0,1,0,0,0,0 +a72,0,0,1,100,0,0,1,0,0,0,0 +a73,0,0,1,100,0,0,1,0,0,0,0 +a74,0,0,1,100,0,0,1,0,0,0,0 +a75,0,0,1,100,0,0,1,0,0,0,0 +a76,0,0,1,100,0,0,1,0,0,0,0 +a78,0,0,1,100,0,0,1,0,0,0,0 +a79,0,0,1,100,0,0,1,0,0,0,0 +a80,0,0,1,100,0,0,1,0,0,0,0 +a81,0,0,1,100,0,0,1,0,0,0,0 +a82,0,0,1,100,0,0,1,0,0,0,0 +a83,0,0,1,100,0,0,1,0,0,0,0 +a84,0,0,1,100,0,0,1,0,0,0,0 +a85,0,0,1,100,0,0,1,0,0,0,0 +a86,0,0,1,100,0,0,1,0,0,0,0 +a87,0,0,1,100,0,0,1,0,0,0,0 +a88,0,0,1,100,0,0,1,0,0,0,0 +a89,0,0,1,100,0,0,1,0,0,0,0 +a90,0,0,1,100,0,0,1,0,0,0,0 +a91,0,0,1,100,0,0,1,0,0,0,0 +a92,0,0,1,100,0,0,1,0,0,0,0 +a93,0,0,1,100,0,0,1,0,0,0,0 +a94,0,0,1,100,0,0,1,0,0,0,0 +a95,0,0,1,100,0,0,1,0,0,0,0 +a96,0,0,1,100,0,0,1,0,0,0,0 +a97,0,0,1,100,0,0,1,0,0,0,0 +a98,0,0,1,100,0,0,1,0,0,0,0 +a99,0,0,1,100,0,0,1,0,0,0,0 +aa1,0,0,1,100,0,0,1,0,0,0,0 +aa2,0,0,1,100,0,0,1,0,0,0,0 +aa3,0,0,1,100,0,0,1,0,0,0,0 +aa4,0,0,1,100,0,0,1,0,0,0,0 +aa5,0,0,1,100,0,0,1,0,0,0,0 +aa6,0,0,1,100,0,0,1,0,0,0,0 +aa7,0,0,1,100,0,0,1,0,0,0,0 +aa8,0,0,1,100,0,0,1,0,0,0,0 +aa9,0,0,1,100,0,0,1,0,0,0,0 +ab1,0,0,1,100,0,0,1,0,0,0,0 +ab2,0,0,1,100,0,0,1,0,0,0,0 +ab3,0,0,1,100,0,0,1,0,0,0,0 +ab4,0,0,1,100,0,0,1,0,0,0,0 +ab5,0,0,1,100,0,0,1,0,0,0,0 +ab6,0,0,1,100,0,0,1,0,0,0,0 +ab7,0,0,1,100,0,0,1,0,0,0,0 +ab8,0,0,1,100,0,0,1,0,0,0,0 +ab9,0,0,1,100,0,0,1,0,0,0,0 +ac1,0,0,1,100,0,0,1,0,0,0,0 +ac2,0,0,1,100,0,0,1,0,0,0,0 +ac3,0,0,1,100,0,0,1,0,0,0,0 +ac4,0,0,1,100,0,0,1,0,0,0,0 +ac5,0,0,1,100,0,0,1,0,0,0,0 +ac6,0,0,1,100,0,0,1,0,0,0,0 +ac7,0,0,1,100,0,0,1,0,0,0,0 +ac8,0,0,1,100,0,0,1,0,0,0,0 +ac9,0,0,1,100,0,0,1,0,0,0,0 +ad1,0,0,1,100,0,0,1,0,0,0,0 +ad2,0,0,1,100,0,0,1,0,0,0,0 +ad3,0,0,1,100,0,0,1,0,0,0,0 +ad4,0,0,1,100,0,0,1,0,0,0,0 +ad5,0,0,1,100,0,0,1,0,0,0,0 +ad6,0,0,1,100,0,0,1,0,0,0,0 +ad7,0,0,1,100,0,0,1,0,0,0,0 +ad8,0,0,1,100,0,0,1,0,0,0,0 +ad9,0,0,1,100,0,0,1,0,0,0,0 +ae1,0,0,1,100,0,0,1,0,0,0,0 +ae2,0,0,1,100,0,0,1,0,0,0,0 +ae3,0,0,1,100,0,0,1,0,0,0,0 +ae4,0,0,1,100,0,0,1,0,0,0,0 +ae5,0,0,1,100,0,0,1,0,0,0,0 +ae6,0,0,1,100,0,0,1,0,0,0,0 +ae7,0,0,1,100,0,0,1,0,0,0,0 +ae8,0,0,1,100,0,0,1,0,0,0,0 +ae9,0,0,1,100,0,0,1,0,0,0,0 +af1,0,0,1,100,0,0,1,0,0,0,0 +af2,0,0,1,100,0,0,1,0,0,0,0 +af3,0,0,1,100,0,0,1,0,0,0,0 +af4,0,0,1,100,0,0,1,0,0,0,0 +af5,0,0,1,100,0,0,1,0,0,0,0 +af6,0,0,1,100,0,0,1,0,0,0,0 +af7,0,0,1,100,0,0,1,0,0,0,0 +af8,0,0,1,100,0,0,1,0,0,0,0 +af9,0,0,1,100,0,0,1,0,0,0,0 +af0,0,0,1,100,0,0,1,0,0,0,0 +ag1,0,0,1,100,0,0,1,0,0,0,0 +ag2,0,0,1,100,0,0,1,0,0,0,0 +ag3,0,0,1,100,0,0,1,0,0,0,0 +ag4,0,0,1,100,0,0,1,0,0,0,0 +ag5,0,0,1,100,0,0,1,0,0,0,0 +ag6,0,0,1,100,0,0,1,0,0,0,0 +ag7,0,0,1,100,0,0,1,0,0,0,0 +ag8,0,0,1,100,0,0,1,0,0,0,0 +ag9,0,0,1,100,0,0,1,0,0,0,0 +ag0,0,0,1,100,0,0,1,0,0,0,0 +ah1,0,0,1,100,0,0,1,0,0,0,0 +ah2,0,0,1,100,0,0,1,0,0,0,0 +ah3,0,0,1,100,0,0,1,0,0,0,0 +ah4,0,0,1,100,0,0,1,0,0,0,0 +ah5,0,0,1,100,0,0,1,0,0,0,0 +ah6,0,0,1,100,0,0,1,0,0,0,0 +ah7,0,0,1,100,0,0,1,0,0,0,0 +ah8,0,0,1,100,0,0,1,0,0,0,0 +ah9,0,0,1,100,0,0,1,0,0,0,0 +ah0,0,0,1,100,0,0,1,0,0,0,0 +ai1,0,0,1,100,0,0,1,0,0,0,0 +ai2,0,0,1,100,0,0,1,0,0,0,0 +ai3,0,0,1,100,0,0,1,0,0,0,0 +ai4,0,0,1,100,0,0,1,0,0,0,0 +ai5,0,0,1,100,0,0,1,0,0,0,0 +ai6,0,0,1,100,0,0,1,0,0,0,0 +ai7,0,0,1,100,0,0,1,0,0,0,0 +ai8,0,0,1,100,0,0,1,0,0,0,0 +ai9,0,0,1,100,0,0,1,0,0,0,0 +ai0,0,0,1,100,0,0,1,0,0,0,0 +aj1,0,0,1,100,0,0,1,0,0,0,0 +aj2,0,0,1,100,0,0,1,0,0,0,0 +aj3,0,0,1,100,0,0,1,0,0,0,0 +aj4,0,0,1,100,0,0,1,0,0,0,0 +aj5,0,0,1,100,0,0,1,0,0,0,0 +aj6,0,0,1,100,0,0,1,0,0,0,0 +aj7,0,0,1,100,0,0,1,0,0,0,0 +aj8,0,0,1,100,0,0,1,0,0,0,0 +aj9,0,0,1,100,0,0,1,0,0,0,0 +aj0,0,0,1,100,0,0,1,0,0,0,0 +ak1,0,0,1,100,0,0,1,0,0,0,0 +ak2,0,0,1,100,0,0,1,0,0,0,0 +ak3,0,0,1,100,0,0,1,0,0,0,0 +ak4,0,0,1,100,0,0,1,0,0,0,0 +ak5,0,0,1,100,0,0,1,0,0,0,0 +ak6,0,0,1,100,0,0,1,0,0,0,0 +ak7,0,0,1,100,0,0,1,0,0,0,0 +ak8,0,0,1,100,0,0,1,0,0,0,0 +ak9,0,0,1,100,0,0,1,0,0,0,0 +ak0,0,0,1,100,0,0,1,0,0,0,0 +al1,0,0,1,100,0,0,1,0,0,0,0 +al2,0,0,1,100,0,0,1,0,0,0,0 +al3,0,0,1,100,0,0,1,0,0,0,0 +al4,0,0,1,100,0,0,1,0,0,0,0 +al5,0,0,1,100,0,0,1,0,0,0,0 +al6,0,0,1,100,0,0,1,0,0,0,0 +al7,0,0,1,100,0,0,1,0,0,0,0 +al8,0,0,1,100,0,0,1,0,0,0,0 +al9,0,0,1,100,0,0,1,0,0,0,0 +al0,0,0,1,100,0,0,1,0,0,0,0 +an1,0,0,1,100,0,0,1,0,0,0,0 +an2,0,0,1,100,0,0,1,0,0,0,0 +an3,0,0,1,100,0,0,1,0,0,0,0 +an4,0,0,1,100,0,0,1,0,0,0,0 +an5,0,0,1,100,0,0,1,0,0,0,0 +an6,0,0,1,100,0,0,1,0,0,0,0 +an7,0,0,1,100,0,0,1,0,0,0,0 +an8,0,0,1,100,0,0,1,0,0,0,0 +an9,0,0,1,100,0,0,1,0,0,0,0 +an0,0,0,1,100,0,0,1,0,0,0,0 +am7,0,0,1,100,0,0,1,0,0,0,0 +am8,0,0,1,100,0,0,1,0,0,0,0 +am9,0,0,1,100,0,0,1,0,0,0,0 +am0,0,0,1,100,0,0,1,0,0,0,0 +ao1,0,0,1,100,0,0,1,0,0,0,0 +ao2,0,0,1,100,0,0,1,0,0,0,0 +ao3,0,0,1,100,0,0,1,0,0,0,0 +ao4,0,0,1,100,0,0,1,0,0,0,0 +ao5,0,0,1,100,0,0,1,0,0,0,0 +ao6,0,0,1,100,0,0,1,0,0,0,0 +am1,0,0,1,100,0,0,1,0,0,0,0 +am2,0,0,1,100,0,0,1,0,0,0,0 +am3,0,0,1,100,0,0,1,0,0,0,0 +am4,0,0,1,100,0,0,1,0,0,0,0 +am5,0,0,1,100,0,0,1,0,0,0,0 +am6,0,0,1,100,0,0,1,0,0,0,0 +ao7,0,0,1,100,0,0,1,0,0,0,0 +ao8,0,0,1,100,0,0,1,0,0,0,0 +ao9,0,0,1,100,0,0,1,0,0,0,0 +ao0,0,0,1,100,0,0,1,0,0,0,0 +ap1,0,0,1,100,0,0,1,0,0,0,0 +ap2,0,0,1,100,0,0,1,0,0,0,0 +ap3,0,0,1,100,0,0,1,0,0,0,0 +ap4,0,0,1,100,0,0,1,0,0,0,0 +ap5,0,0,1,100,0,0,1,0,0,0,0 +ap6,0,0,1,100,0,0,1,0,0,0,0 +ap7,0,0,1,100,0,0,1,0,0,0,0 +ap8,0,0,1,100,0,0,1,0,0,0,0 +ap9,0,0,1,100,0,0,1,0,0,0,0 +ap0,0,0,1,100,0,0,1,0,0,0,0 +aq1,0,0,1,100,0,0,1,0,0,0,0 +aq2,0,0,1,100,0,0,1,0,0,0,0 +aq3,0,0,1,100,0,0,1,0,0,0,0 +aq4,0,0,1,100,0,0,1,0,0,0,0 +aq5,0,0,1,100,0,0,1,0,0,0,0 +aq6,0,0,1,100,0,0,1,0,0,0,0 +aq7,0,0,1,100,0,0,1,0,0,0,0 +aq8,0,0,1,100,0,0,1,0,0,0,0 +aq9,0,0,1,100,0,0,1,0,0,0,0 +ar0,0,0,1,100,0,0,1,0,0,0,0 +ar1,0,0,1,100,0,0,1,0,0,0,0 +ar2,0,0,1,100,0,0,1,0,0,0,0 +ar3,0,0,1,100,0,0,1,0,0,0,0 +ar4,0,0,1,100,0,0,1,0,0,0,0 +ar5,0,0,1,100,0,0,1,0,0,0,0 +ar6,0,0,1,100,0,0,1,0,0,0,0 +ar7,0,0,1,100,0,0,1,0,0,0,0 +ar8,0,0,1,100,0,0,1,0,0,0,0 +ar9,0,0,1,100,0,0,1,0,0,0,0 +as0,0,0,1,100,0,0,1,0,0,0,0 +as1,0,0,1,100,0,0,1,0,0,0,0 +as2,0,0,1,100,0,0,1,0,0,0,0 +as3,0,0,1,100,0,0,1,0,0,0,0 +as4,0,0,1,100,0,0,1,0,0,0,0 +as5,0,0,1,100,0,0,1,0,0,0,0 +as6,0,0,1,100,0,0,1,0,0,0,0 +as7,0,0,1,100,0,0,1,0,0,0,0 +as8,0,0,1,100,0,0,1,0,0,0,0 +as9,0,0,1,100,0,0,1,0,0,0,0 +at0,0,0,1,100,0,0,1,0,0,0,0 +at1,0,0,1,100,0,0,1,0,0,0,0 +at2,0,0,1,100,0,0,1,0,0,0,0 +at3,0,0,1,100,0,0,1,0,0,0,0 +at4,0,0,1,100,0,0,1,0,0,0,0 +at5,0,0,1,100,0,0,1,0,0,0,0 +at6,0,0,1,100,0,0,1,0,0,0,0 +at7,0,0,1,100,0,0,1,0,0,0,0 +at8,0,0,1,100,0,0,1,0,0,0,0 +at9,0,0,1,100,0,0,1,0,0,0,0 +au0,0,0,1,100,0,0,1,0,0,0,0 +au1,0,0,1,100,0,0,1,0,0,0,0 +au2,0,0,1,100,0,0,1,0,0,0,0 +au3,0,0,1,100,0,0,1,0,0,0,0 +au4,0,0,1,100,0,0,1,0,0,0,0 +au5,0,0,1,100,0,0,1,0,0,0,0 +au6,0,0,1,100,0,0,1,0,0,0,0 +au7,0,0,1,100,0,0,1,0,0,0,0 +au8,0,0,1,100,0,0,1,0,0,0,0 +au9,0,0,1,100,0,0,1,0,0,0,0 +av0,0,0,1,100,0,0,1,0,0,0,0 +av1,0,0,1,100,0,0,1,0,0,0,0 +av2,0,0,1,100,0,0,1,0,0,0,0 +av3,0,0,1,100,0,0,1,0,0,0,0 +av4,0,0,1,100,0,0,1,0,0,0,0 +av5,0,0,1,100,0,0,1,0,0,0,0 +av6,0,0,1,100,0,0,1,0,0,0,0 +av7,0,0,1,100,0,0,1,0,0,0,0 +av8,0,0,1,100,0,0,1,0,0,0,0 +av9,0,0,1,100,0,0,1,0,0,0,0 +aw0,0,0,1,100,0,0,1,0,0,0,0 +aw1,0,0,1,100,0,0,1,0,0,0,0 +aw2,0,0,1,100,0,0,1,0,0,0,0 +aw3,0,0,1,100,0,0,1,0,0,0,0 +aw4,0,0,1,100,0,0,1,0,0,0,0 +aw5,0,0,1,100,0,0,1,0,0,0,0 +aw6,0,0,1,100,0,0,1,0,0,0,0 +aw7,0,0,1,100,0,0,1,0,0,0,0 +aw8,0,0,1,100,0,0,1,0,0,0,0 +aw9,0,0,1,100,0,0,1,0,0,0,0 +ax0,0,0,1,100,0,0,1,0,0,0,0 +ax1,0,0,1,100,0,0,1,0,0,0,0 +ax2,0,0,1,100,0,0,1,0,0,0,0 +ax3,0,0,1,100,0,0,1,0,0,0,0 +ax4,0,0,1,100,0,0,1,0,0,0,0 +ax5,0,0,1,100,0,0,1,0,0,0,0 +ax6,0,0,1,100,0,0,1,0,0,0,0 +ax7,0,0,1,100,0,0,1,0,0,0,0 +ax8,0,0,1,100,0,0,1,0,0,0,0 +ax9,0,0,1,100,0,0,1,0,0,0,0 +ay0,0,0,1,100,0,0,1,0,0,0,0 +ay1,0,0,1,100,0,0,1,0,0,0,0 +ay2,0,0,1,100,0,0,1,0,0,0,0 +ay3,0,0,1,100,0,0,1,0,0,0,0 +ay4,0,0,1,100,0,0,1,0,0,0,0 +ay5,0,0,1,100,0,0,1,0,0,0,0 +ay6,0,0,1,100,0,0,1,0,0,0,0 +ay7,0,0,1,100,0,0,1,0,0,0,0 +ay8,0,0,1,100,0,0,1,0,0,0,0 +ay9,0,0,1,100,0,0,1,0,0,0,0 +az0,0,0,1,100,0,0,1,0,0,0,0 +az1,0,0,1,100,0,0,1,0,0,0,0 +az2,0,0,1,100,0,0,1,0,0,0,0 +az3,0,0,1,100,0,0,1,0,0,0,0 +az4,0,0,1,100,0,0,1,0,0,0,0 +az5,0,0,1,100,0,0,1,0,0,0,0 +az6,0,0,1,100,0,0,1,0,0,0,0 +az7,0,0,1,100,0,0,1,0,0,0,0 +az8,0,0,1,100,0,0,1,0,0,0,0 +az9,0,0,1,100,0,0,1,0,0,0,0 +e01,0,0,1,100,0,0,1,0,0,0,0 +e02,0,0,1,100,0,0,1,0,0,0,0 +e03,0,0,1,100,0,0,1,0,0,0,0 +e04,0,0,1,100,0,0,1,0,0,0,0 +e05,0,0,1,100,0,0,1,0,0,0,0 +e06,0,0,1,100,0,0,1,0,0,0,0 +e07,0,0,1,100,0,0,1,0,0,0,0 +e08,0,0,1,100,0,0,1,0,0,0,0 +e09,0,0,1,100,0,0,1,0,0,0,0 +e10,0,0,1,100,0,0,1,0,0,0,0 +e11,0,0,1,100,0,0,1,0,0,0,0 +e12,0,0,1,100,0,0,1,0,0,0,0 +e13,0,0,1,100,0,0,1,0,0,0,0 +e14,0,0,1,100,0,0,1,0,0,0,0 +e15,0,0,1,100,0,0,1,0,0,0,0 +e16,0,0,1,100,0,0,1,0,0,0,0 +e17,0,0,1,100,0,0,1,0,0,0,0 +e18,0,0,1,100,0,0,1,0,0,0,0 +e19,0,0,1,100,0,0,1,0,0,0,0 +e20,0,0,1,100,0,0,1,0,0,0,0 +e21,0,0,1,100,0,0,1,0,0,0,0 +e22,0,0,1,100,0,0,1,0,0,0,0 +e23,0,0,1,100,0,0,1,0,0,0,0 +e24,0,0,1,100,0,0,1,0,0,0,0 +e25,0,0,1,100,0,0,1,0,0,0,0 +e26,0,0,1,100,0,0,1,0,0,0,0 +e27,0,0,1,100,0,0,1,0,0,0,0 +e28,0,0,1,100,0,0,1,0,0,0,0 +e29,0,0,1,100,0,0,1,0,0,0,0 +e30,0,0,1,100,0,0,1,0,0,0,0 +e31,0,0,1,100,0,0,1,0,0,0,0 +e32,0,0,1,100,0,0,1,0,0,0,0 +e33,0,0,1,100,0,0,1,0,0,0,0 +e34,0,0,1,100,0,0,1,0,0,0,0 +e35,0,0,1,100,0,0,1,0,0,0,0 +e36,0,0,1,100,0,0,1,0,0,0,0 +e37,0,0,1,100,0,0,1,0,0,0,0 +e38,0,0,1,100,0,0,1,0,0,0,0 +e39,0,0,1,100,0,0,1,0,0,0,0 +e40,0,0,1,100,0,0,1,0,0,0,0 +e41,0,0,1,100,0,0,1,0,0,0,0 +e42,0,0,1,100,0,0,1,0,0,0,0 +e43,0,0,1,100,0,0,1,0,0,0,0 +e44,0,0,1,100,0,0,1,0,0,0,0 +e45,0,0,1,100,0,0,1,0,0,0,0 +e46,0,0,1,100,0,0,1,0,0,0,0 +e47,0,0,1,100,0,0,1,0,0,0,0 +e48,0,0,1,100,0,0,1,0,0,0,0 +e49,0,0,1,100,0,0,1,0,0,0,0 +e50,0,0,1,100,0,0,1,0,0,0,0 +e51,0,0,1,100,0,0,1,0,0,0,0 +e52,0,0,1,100,0,0,1,0,0,0,0 +e53,0,0,1,100,0,0,1,0,0,0,0 +e54,0,0,1,100,0,0,1,0,0,0,0 +e55,0,0,1,100,0,0,1,0,0,0,0 +e56,0,0,1,100,0,0,1,0,0,0,0 +e57,0,0,1,100,0,0,1,0,0,0,0 +e58,0,0,1,100,0,0,1,0,0,0,0 +e59,0,0,1,100,0,0,1,0,0,0,0 +e60,0,0,1,100,0,0,1,0,0,0,0 +e61,0,0,1,100,0,0,1,0,0,0,0 +e62,0,0,1,100,0,0,1,0,0,0,0 +e63,0,0,1,100,0,0,1,0,0,0,0 +e64,0,0,1,100,0,0,1,0,0,0,0 +e65,0,0,1,100,0,0,1,0,0,0,0 +e66,0,0,1,100,0,0,1,0,0,0,0 +e67,0,0,1,100,0,0,1,0,0,0,0 +e68,0,0,1,100,0,0,1,0,0,0,0 +e69,0,0,1,100,0,0,1,0,0,0,0 +e70,0,0,1,100,0,0,1,0,0,0,0 +e71,0,0,1,100,0,0,1,0,0,0,0 +e72,0,0,1,100,0,0,1,0,0,0,0 +e73,0,0,1,100,0,0,1,0,0,0,0 +e74,0,0,1,100,0,0,1,0,0,0,0 +e75,0,0,1,100,0,0,1,0,0,0,0 +e76,0,0,1,100,0,0,1,0,0,0,0 +e77,0,0,1,100,0,0,1,0,0,0,0 +e78,0,0,1,100,0,0,1,0,0,0,0 +e79,0,0,1,100,0,0,1,0,0,0,0 +e80,0,0,1,100,0,0,1,0,0,0,0 +e81,0,0,1,100,0,0,1,0,0,0,0 +e82,0,0,1,100,0,0,1,0,0,0,0 +e83,0,0,1,100,0,0,1,0,0,0,0 +e84,0,0,1,100,0,0,1,0,0,0,0 +e85,0,0,1,100,0,0,1,0,0,0,0 +e86,0,0,1,100,0,0,1,0,0,0,0 +e87,0,0,1,100,0,0,1,0,0,0,0 +e88,0,0,1,100,0,0,1,0,0,0,0 +e89,0,0,1,100,0,0,1,0,0,0,0 +e90,0,0,1,100,0,0,1,0,0,0,0 +e91,0,0,1,100,0,0,1,0,0,0,0 +e92,0,0,1,100,0,0,1,0,0,0,0 +e93,0,0,1,100,0,0,1,0,0,0,0 +e94,0,0,1,100,0,0,1,0,0,0,0 +e95,0,0,1,100,0,0,1,0,0,0,0 +e96,0,0,1,100,0,0,1,0,0,0,0 +e97,0,0,1,100,0,0,1,0,0,0,0 +e98,0,0,1,100,0,0,1,0,0,0,0 +e99,0,0,1,100,0,0,1,0,0,0,0 +ea0,0,0,1,100,0,0,1,0,0,0,0 +ea1,0,0,1,100,0,0,1,0,0,0,0 +ea2,0,0,1,100,0,0,1,0,0,0,0 +ea3,0,0,1,100,0,0,1,0,0,0,0 +ea4,0,0,1,100,0,0,1,0,0,0,0 +ea5,0,0,1,100,0,0,1,0,0,0,0 +ea6,0,0,1,100,0,0,1,0,0,0,0 +ea7,0,0,1,100,0,0,1,0,0,0,0 +ea8,0,0,1,100,0,0,1,0,0,0,0 +ea9,0,0,1,100,0,0,1,0,0,0,0 +eb0,0,0,1,100,0,0,1,0,0,0,0 +eb1,0,0,1,100,0,0,1,0,0,0,0 +eb2,0,0,1,100,0,0,1,0,0,0,0 +eb3,0,0,1,100,0,0,1,0,0,0,0 +eb4,0,0,1,100,0,0,1,0,0,0,0 +eb5,0,0,1,100,0,0,1,0,0,0,0 +eb6,0,0,1,100,0,0,1,0,0,0,0 +eb7,0,0,1,100,0,0,1,0,0,0,0 +eb8,0,0,1,100,0,0,1,0,0,0,0 +eb9,0,0,1,100,0,0,1,0,0,0,0 +ec0,0,0,1,100,0,0,1,0,0,0,0 +ec1,0,0,1,100,0,0,1,0,0,0,0 +ec2,0,0,1,100,0,0,1,0,0,0,0 +ec3,0,0,1,100,0,0,1,0,0,0,0 +ec4,0,0,1,100,0,0,1,0,0,0,0 +ec5,0,0,1,100,0,0,1,0,0,0,0 +ec6,0,0,1,100,0,0,1,0,0,0,0 +ec7,0,0,1,100,0,0,1,0,0,0,0 +ec8,0,0,1,100,0,0,1,0,0,0,0 +ec9,0,0,1,100,0,0,1,0,0,0,0 +ed0,0,0,1,100,0,0,1,0,0,0,0 +ed1,0,0,1,100,0,0,1,0,0,0,0 +ed2,0,0,1,100,0,0,1,0,0,0,0 +ed3,0,0,1,100,0,0,1,0,0,0,0 +ed4,0,0,1,100,0,0,1,0,0,0,0 +ed5,0,0,1,100,0,0,1,0,0,0,0 +ed6,0,0,1,100,0,0,1,0,0,0,0 +ed7,0,0,1,100,0,0,1,0,0,0,0 +ed8,0,0,1,100,0,0,1,0,0,0,0 +ed9,0,0,1,100,0,0,1,0,0,0,0 +ee0,0,0,1,100,0,0,1,0,0,0,0 +ee1,0,0,1,100,0,0,1,0,0,0,0 +ee2,0,0,1,100,0,0,1,0,0,0,0 +ee3,0,0,1,100,0,0,1,0,0,0,0 +ee4,0,0,1,100,0,0,1,0,0,0,0 +ee5,0,0,1,100,0,0,1,0,0,0,0 +ee6,0,0,1,100,0,0,1,0,0,0,0 +c01,0,0,1,100,0,0,1,0,0,0,0 +c02,0,0,1,100,0,0,1,0,0,0,0 +c03,0,0,1,100,0,0,1,0,0,0,0 +c04,0,0,1,100,0,0,1,0,0,0,0 +c05,0,0,1,100,0,0,1,0,0,0,0 +c06,0,0,1,100,0,0,1,0,0,0,0 +c07,0,0,1,100,0,0,1,0,0,0,0 +c08,0,0,1,100,0,0,1,0,0,0,0 +c09,0,0,1,100,0,0,1,0,0,0,0 +c10,0,0,1,100,0,0,1,0,0,0,0 +c11,0,0,1,100,0,0,1,0,0,0,0 +c12,0,0,1,100,0,0,1,0,0,0,0 +c13,0,0,1,100,0,0,1,0,0,0,0 +c14,0,0,1,100,0,0,1,0,0,0,0 +c15,0,0,1,100,0,0,1,0,0,0,0 +c16,0,0,1,100,0,0,1,0,0,0,0 +c17,0,0,1,100,0,0,1,0,0,0,0 +c18,0,0,1,100,0,0,1,0,0,0,0 +s01,0,0,1,100,0,0,1,0,0,0,0 +s05,0,0,1,100,0,0,1,0,0,0,0 +s06,0,0,1,100,0,0,1,0,0,0,0 +s08,0,0,1,100,0,0,1,0,0,0,0 +s09,0,0,1,100,0,0,1,0,0,0,0 +s10,0,0,1,100,0,0,1,0,0,0,0 +s11,0,0,1,100,0,0,1,0,0,0,0 +s12,0,0,1,100,0,0,1,0,0,0,0 +s13,0,0,1,100,0,0,1,0,0,0,0 +s14,0,0,1,100,0,0,1,0,0,0,0 +s15,0,0,1,100,0,0,1,0,0,0,0 +s16,0,0,1,100,0,0,1,0,0,0,0 +s17,0,0,1,100,0,0,1,0,0,0,0 +s18,0,0,1,100,0,0,1,0,0,0,0 +s19,0,0,1,100,0,0,1,0,0,0,0 +s20,0,0,1,100,0,0,1,0,0,0,0 +s21,0,0,1,100,0,0,1,0,0,0,0 +s22,0,0,1,100,0,0,1,0,0,0,0 +s23,0,0,1,100,0,0,1,0,0,0,0 +s24,0,0,1,100,0,0,1,0,0,0,0 +s25,0,0,1,100,0,0,1,0,0,0,0 +s80,0,0,1,100,0,0,1,0,0,0,0 +s82,0,0,1,100,0,0,1,0,0,0,0 +s83,0,0,1,100,0,0,1,0,0,0,0 +s84,0,0,1,100,0,0,1,0,0,0,0 +s85,0,0,1,100,0,0,1,0,0,0,0 +s86,0,0,1,100,0,0,1,0,0,0,0 +s87,0,0,1,100,0,0,1,0,0,0,0 +s88,0,0,1,100,0,0,1,0,0,0,0 +s89,0,0,1,100,0,0,1,0,0,0,0 +s90,0,0,1,100,0,0,1,0,0,0,0 +s91,0,0,1,100,0,0,1,0,0,0,0 +s92,0,0,1,100,0,0,1,0,0,0,0 +s93,0,0,1,100,0,0,1,0,0,0,0 +s94,0,0,1,100,0,0,1,0,0,0,0 +s95,0,0,1,100,0,0,1,0,0,0,0 +s96,0,0,1,100,0,0,1,0,0,0,0 +s97,0,0,1,100,0,0,1,0,0,0,0 +s98,0,0,1,100,0,0,1,0,0,0,0 +s99,0,0,1,100,0,0,1,0,0,0,0 +sa0,0,0,1,100,0,0,1,0,0,0,0 +sa1,0,0,1,100,0,0,1,0,0,0,0 +sa2,0,0,1,100,0,0,1,0,0,0,0 +sa3,0,0,1,100,0,0,1,0,0,0,0 +sa4,0,0,1,100,0,0,1,0,0,0,0 +sa5,0,0,1,100,0,0,1,0,0,0,0 +u01,0,0,1,100,0,0,1,0,0,0,0 +u02,0,0,1,100,0,0,1,0,0,0,0 +u03,0,0,1,100,0,0,1,0,0,0,0 +u04,0,0,1,100,0,0,1,0,0,0,0 +u05,0,0,1,100,0,0,1,0,0,0,0 +u06,0,0,1,100,0,0,1,0,0,0,0 +u07,0,0,1,100,0,0,1,0,0,0,0 +u08,0,0,1,100,0,0,1,0,0,0,0 +u09,0,0,1,100,0,0,1,0,0,0,0 +u10,0,0,1,100,0,0,1,0,0,0,0 +u11,0,0,1,100,0,0,1,0,0,0,0 +u12,0,0,1,100,0,0,1,0,0,0,0 diff --git a/Assembly-CSharp/_Emulator/GUI/DebugConsole.cs b/Assembly-CSharp/_Emulator/GUI/DebugConsole.cs index 9e20c24..7ae4765 100644 --- a/Assembly-CSharp/_Emulator/GUI/DebugConsole.cs +++ b/Assembly-CSharp/_Emulator/GUI/DebugConsole.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using UnityEngine; namespace _Emulator @@ -19,6 +20,7 @@ struct Log Vector2 scrollPosition; bool hidden = true; bool collapse = true; + private const string logFileName = "ClientLog.log"; static readonly Dictionary logTypeColors = new Dictionary() { @@ -36,6 +38,22 @@ struct Log GUIContent clearLabel = new GUIContent("Clear", "Clear the contents of the console."); GUIContent collapseLabel = new GUIContent("Collapse", "Hide repeated messages."); + void Awake() + { + // Clear the log file at the start of the program + try + { + if (File.Exists(logFileName)) + { + File.WriteAllText(logFileName, string.Empty); // Clear the file + } + } + catch (IOException ex) + { + Debug.LogError($"Failed to clear log file: {ex.Message}"); + } + } + void OnEnable() { Application.RegisterLogCallback(HandleLog); @@ -84,6 +102,8 @@ void ConsoleWindow(int windowID) GUI.contentColor = logTypeColors[log.type]; GUILayout.Label(log.message); + if (log.stackTrace != string.Empty) + GUILayout.Label(log.stackTrace); } GUILayout.EndScrollView(); @@ -106,12 +126,31 @@ void ConsoleWindow(int windowID) void HandleLog(string message, string stackTrace, LogType type) { - logs.Add(new Log() + var logEntry = new Log() { message = message, stackTrace = stackTrace, type = type, - }); + }; + + logs.Add(logEntry); + + // Append the log entry to the file + try + { + using (StreamWriter writer = new StreamWriter(logFileName, true)) + { + writer.WriteLine($"[{System.DateTime.Now}] [{type}] {message}"); + if (!string.IsNullOrEmpty(stackTrace)) + { + writer.WriteLine(stackTrace); + } + } + } + catch (IOException ex) + { + Debug.LogError($"Failed to write log to file: {ex.Message}"); + } } } } \ No newline at end of file diff --git a/Assembly-CSharp/_Emulator/GUI/InventoryGUI.cs b/Assembly-CSharp/_Emulator/GUI/InventoryGUI.cs index cff33bf..a93d5ce 100644 --- a/Assembly-CSharp/_Emulator/GUI/InventoryGUI.cs +++ b/Assembly-CSharp/_Emulator/GUI/InventoryGUI.cs @@ -68,20 +68,20 @@ private void OnGUI() if (GUI.Button(updateButtonRect, "Update Inventory")) { - ClientExtension.instance.inventory.UpdateCSV(); + //ClientExtension.instance.inventory.UpdateCSV(); ClientExtension.instance.SendInventoryCSV(); } if (GUI.Button(saveButtonRect, "Save Inventory")) { - ClientExtension.instance.inventory.UpdateCSV(); - ClientExtension.instance.inventory.Save(); + //ClientExtension.instance.inventory.UpdateCSV(); + //ClientExtension.instance.inventory.Save(); ClientExtension.instance.SendInventoryCSV(); } if (GUI.Button(loadButtonRect, "Load Inventory")) { - ClientExtension.instance.inventory.LoadInventoryFromDisk(); + //ClientExtension.instance.inventory.LoadInventoryFromDisk(); if (sortInventory) ClientExtension.instance.inventory.Sort(); ClientExtension.instance.SendInventoryCSV(); diff --git a/Assembly-CSharp/_Emulator/GUI/MainGUI.cs b/Assembly-CSharp/_Emulator/GUI/MainGUI.cs index 193d06d..2d20c13 100644 --- a/Assembly-CSharp/_Emulator/GUI/MainGUI.cs +++ b/Assembly-CSharp/_Emulator/GUI/MainGUI.cs @@ -36,14 +36,14 @@ private void SetupGUIWindow(int winID) GUILayout.Label("Host IP:"); ClientExtension.instance.hostIP = GUILayout.TextField(ClientExtension.instance.hostIP); - if (GUILayout.Button("Host Match")) + if (GUILayout.Button("Host")) { hostHidden = true; ServerEmulator.instance.SetupServer(); ClientExtension.instance.LoadServer(); } - if (GUILayout.Button("Join Match")) + if (GUILayout.Button("Join")) { hostHidden = true; ClientExtension.instance.LoadServer(); @@ -62,10 +62,10 @@ private void HostGUIWindow(int winID) ServerEmulator.instance.Reset(); } - if (GUILayout.Button("End Match")) + /*if (GUILayout.Button("End Match")) { ServerEmulator.instance.matchData.EndMatch(); - } + }*/ if (GUILayout.Button("Clear Buffers")) { diff --git a/Assembly-CSharp/_Emulator/Hooks.cs b/Assembly-CSharp/_Emulator/Hooks.cs index 6260425..d288285 100644 --- a/Assembly-CSharp/_Emulator/Hooks.cs +++ b/Assembly-CSharp/_Emulator/Hooks.cs @@ -4,6 +4,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using UnityEngine; +using System.IO; namespace _Emulator { @@ -61,7 +62,15 @@ class Hooks static MethodInfo hSockTcpHandleWeaponSlotListAckInfo = typeof(Hooks).GetMethod("hSockTcpHandleWeaponSlotListAck", BindingFlags.NonPublic | BindingFlags.Instance); static Hook SockTcpHandleWeaponSlotListAckHook; - static MethodInfo oMyInfoManagerSetItemUsageInfo = typeof(MyInfoManager).GetMethod("SetItemUsage", BindingFlags.Public | BindingFlags.Instance); + static MethodInfo oSockTcpRegisterReqInfo = typeof(SockTcp).GetMethod("SendCS_REGISTER_REQ", BindingFlags.Public | BindingFlags.Instance); + static MethodInfo hSockTcpRegisterReqInfo = typeof(Hooks).GetMethod("hSockTcpRegisterReq", BindingFlags.Public | BindingFlags.Instance); + static Hook SockTcpRegisterReqHook; + + static MethodInfo oSockTcpSaveMapReqInfo = typeof(SockTcp).GetMethod("SendCS_SAVE_REQ", BindingFlags.Public | BindingFlags.Instance); + static MethodInfo hSockTcpSaveMapReqInfo = typeof(Hooks).GetMethod("hSockTcpSaveMapReq", BindingFlags.Public | BindingFlags.Instance); + static Hook SockTcpSaveMapReqHook; + + static MethodInfo oMyInfoManagerSetItemUsageInfo = typeof(MyInfoManager).GetMethod("SetItemUsage", BindingFlags.Public | BindingFlags.Instance); static MethodInfo hMyInfoManagerSetItemUsageInfo = typeof(Hooks).GetMethod("hMyInfoManagerSetItemUsage", BindingFlags.Public | BindingFlags.Instance); static Hook MyInfoManagerSetItemUsageHook; @@ -180,6 +189,13 @@ public void hPimpManagerLoad() { PimpManager.Instance.LoadFromLocalFileSystem(); PimpManager.Instance.updateValue((int)UPGRADE_CAT.HANDGUN, (int)PIMP.PROP_RPM, 9, 400); + for (PIMP pimp = PIMP.PROP_ATK_POW; pimp < PIMP.PROP_MAX; pimp++) + { + for (int lv = 0; lv < 10; lv++) + { + PimpManager.Instance.updateValue((int)UPGRADE_CAT.OTHER, (int)pimp, lv, 0f); + } + } } private void hP2PManagerReliableSend(uint to, byte id, P2PMsgBody mb) @@ -363,7 +379,30 @@ public static void hApplicationQuit() ApplicationQuitHook.CallOriginal(null, null); } - public static void Initialize() + public void hSockTcpRegisterReq(int slot, ushort modeMask, int regHow, int point, int downloadFee, byte[] thumbnail, string msgEval) + { + ClientExtension.instance.SendBeginChunkedBuffer(ExtensionOpcodes.opChunkedBufferThumbnailReq, thumbnail); + + MsgBody msgBody = new MsgBody(); + msgBody.Write(slot); + msgBody.Write(modeMask); + msgBody.Write(regHow); + msgBody.Write(point); + msgBody.Write(downloadFee); + msgBody.Write(msgEval); + CSNetManager.Instance.Sock.Say(51, msgBody); + } + + public void hSockTcpSaveMapReq(int slot, byte[] thumbnail) + { + ClientExtension.instance.SendBeginChunkedBuffer(ExtensionOpcodes.opChunkedBufferThumbnailReq, thumbnail); + + MsgBody msgBody = new MsgBody(); + msgBody.Write(slot); + CSNetManager.Instance.Sock.Say(39, msgBody); + } + + public static void Initialize() { P2PManagerHandshakeHook = new Hook(oP2PManagerHandshakeInfo, hP2PManagerHandshakeInfo); P2PManagerHandshakeHook.ApplyHook(); @@ -393,8 +432,12 @@ public static void Initialize() SockTcpHandleWeaponSlotAckHook.ApplyHook(); SockTcpHandleWeaponSlotListAckHook = new Hook(oSockTcpHandleWeaponSlotListAckInfo, hSockTcpHandleWeaponSlotListAckInfo); SockTcpHandleWeaponSlotListAckHook.ApplyHook(); - ApplicationQuitHook = new Hook(oApplicationQuitInfo, hApplicationQuitInfo); + SockTcpRegisterReqHook = new Hook(oSockTcpRegisterReqInfo, hSockTcpRegisterReqInfo); + SockTcpRegisterReqHook.ApplyHook(); + SockTcpSaveMapReqHook = new Hook(oSockTcpSaveMapReqInfo, hSockTcpSaveMapReqInfo); + SockTcpSaveMapReqHook.ApplyHook(); + ApplicationQuitHook = new Hook(oApplicationQuitInfo, hApplicationQuitInfo); ApplicationQuitHook.ApplyHook(); } } -} +} \ No newline at end of file diff --git a/Assembly-CSharp/_Emulator/JSON/JsonObject.cs b/Assembly-CSharp/_Emulator/JSON/JsonObject.cs new file mode 100644 index 0000000..7195cbf --- /dev/null +++ b/Assembly-CSharp/_Emulator/JSON/JsonObject.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace _Emulator.JSON +{ + class JsonObject: IEnumerable + { + private readonly Dictionary _data = new Dictionary(); + + public void Add(string key, object value) + { + _data[key] = value; + } + + public T Get(string key) + { + if (_data.TryGetValue(key, out var value)) + { + if (value is T typedValue) + { + return typedValue; + } + throw new InvalidCastException($"Value for key '{key}' is not of type {typeof(T).Name}."); + } + throw new KeyNotFoundException($"Key '{key}' not found in JsonObject."); + } + + public Dictionary ToDictionary() + { + return new Dictionary(_data); + } + + public void LoadFromDictionary(Dictionary dictionary) + { + _data.Clear(); + foreach (var kvp in dictionary) + { + _data[kvp.Key] = kvp.Value; + } + } + + public IEnumerator> GetEnumerator() + { + return _data.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/Assembly-CSharp/_Emulator/JSON/JsonReader.cs b/Assembly-CSharp/_Emulator/JSON/JsonReader.cs new file mode 100644 index 0000000..c314274 --- /dev/null +++ b/Assembly-CSharp/_Emulator/JSON/JsonReader.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace _Emulator.JSON +{ + /* + * This is a JSON Reader class, this class only supports the following datatypes: + * String, Boolean, Float, Integer, Null + * This JSON implementation can currently not use any arrays. + * This JSON implementation can currently not use any nested objects. + */ + class JsonReader + { + private readonly TextReader _reader; + + public JsonReader(TextReader reader) + { + _reader = reader ?? throw new ArgumentNullException(nameof(reader)); + } + + public JsonObject ReadObject() + { + var result = new JsonObject(); + string line; + while ((line = _reader.ReadLine()) != null) + { + line = line.Trim(); + if (string.IsNullOrEmpty(line) || line.StartsWith("#") || line.StartsWith("{") || line.StartsWith("}")) // Skip empty lines or comments + continue; + + int separatorIndex = line.IndexOf(":"); + if (separatorIndex < 0) + throw new FormatException("Invalid format: Missing ':' separator."); + + string key = ParseKey(line.Substring(0, separatorIndex)); + object value = ParseValue(line.Substring(separatorIndex + 1).Trim()); + result.Add(key, value); + } + return result; + } + + private string ParseKey(string value) + { + return value.Trim().Trim('"'); + } + + private object ParseValue(string value) + { + if (value.StartsWith("\"") && value.EndsWith("\"")) // String + { + return value.Substring(1, value.Length - 2); + } + else if (int.TryParse(value, out int intValue)) // Integer + { + return intValue; + } + else if (float.TryParse(value, out float doubleValue)) // Float + { + return doubleValue; + } + else if (bool.TryParse(value, out bool boolValue)) // Boolean + { + return boolValue; + } + else if (value.Equals("null", StringComparison.OrdinalIgnoreCase)) // Null + { + return null; + } + else + { + throw new FormatException("Unsupported value type: " + value); + } + } + } +} diff --git a/Assembly-CSharp/_Emulator/JSON/JsonWriter.cs b/Assembly-CSharp/_Emulator/JSON/JsonWriter.cs new file mode 100644 index 0000000..bd78b42 --- /dev/null +++ b/Assembly-CSharp/_Emulator/JSON/JsonWriter.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace _Emulator.JSON +{ + /* + * This is a JSON Writer class, this class only supports the following datatypes: + * String, Boolean, Float, Integer, Null + * This JSON implementation can currently not use any arrays. + * This JSON implementation can currently not use any nested objects. + */ + class JsonWriter + { + private readonly TextWriter _writer; + + public JsonWriter(TextWriter writer) + { + _writer = writer ?? throw new ArgumentNullException(nameof(writer)); + } + + public void WriteObject(JsonObject data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + _writer.WriteLine("{"); + + foreach (var kvp in data) + { + string valueString = SerializeValue(kvp.Value); + _writer.WriteLine($" \"{kvp.Key}\": {valueString}"); + } + + _writer.WriteLine("}"); + } + + private string SerializeValue(object value) + { + if (value == null) + { + return "null"; + } + else if (value is string stringValue) + { + return $"\"{stringValue}\""; + } + else if (value is bool boolValue) + { + return boolValue.ToString().ToLower(); + } + else if (value is int) + { + return value.ToString(); + } + else if (value is float floatValue) + { + return floatValue.ToString("0.0"); + } + else + { + throw new InvalidOperationException("Unsupported value type: " + value.GetType().Name); + } + } + } +} diff --git a/Assembly-CSharp/_Emulator/Maps/MapGenerator.cs b/Assembly-CSharp/_Emulator/Maps/MapGenerator.cs new file mode 100644 index 0000000..57dd86c --- /dev/null +++ b/Assembly-CSharp/_Emulator/Maps/MapGenerator.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using UnityEngine; +using Debug = UnityEngine.Debug; + +namespace _Emulator +{ + class MapGenerator + { + public class Landscape + { + public byte[] bricks; + public float[] ratios; + public float[] distribution; + public byte size; + public byte height; + + public Landscape(byte[] _bricks, float[] _ratios, byte _size, byte _height) + { + bricks = _bricks; + ratios = _ratios; + size = _size; + height = _height; + distribution = new float[ratios.Length + 1]; + distribution[0] = 0f; + + for (int i = 0; i < ratios.Length; i++) + { + distribution[i + 1] = ratios[i] + distribution[i]; + } + } + } + + public static MapGenerator instance = new MapGenerator(); + private Dictionary landscapeTemplates; + + MapGenerator() + { + landscapeTemplates = new Dictionary(); + landscapeTemplates.Add(0, new Landscape(new byte[] { 0, 1}, new float[] { 0.7f, 0.3f }, 50, 1)); + landscapeTemplates.Add(1, new Landscape(new byte[] { 0, 1 }, new float[] { 0.7f, 0.3f }, 100, 1)); + landscapeTemplates.Add(2, new Landscape(new byte[] { 0, 1 }, new float[] { 0.7f, 0.3f }, 50, 5)); + landscapeTemplates.Add(3, new Landscape(new byte[] { 8, 9 }, new float[] { 0.7f, 0.3f }, 50, 1)); + landscapeTemplates.Add(4, new Landscape(new byte[] { 8, 9 }, new float[] { 0.7f, 0.3f }, 100, 1)); + landscapeTemplates.Add(5, new Landscape(new byte[] { 8, 9 }, new float[] { 0.7f, 0.3f }, 50, 5)); + landscapeTemplates.Add(6, new Landscape(new byte[] { 10, 25 }, new float[] { 0.7f, 0.3f }, 50, 1)); + landscapeTemplates.Add(7, new Landscape(new byte[] { 10, 25 }, new float[] { 0.7f, 0.3f }, 100, 1)); + landscapeTemplates.Add(8, new Landscape(new byte[] { 10, 25 }, new float[] { 0.7f, 0.3f }, 50, 5)); + landscapeTemplates.Add(9, new Landscape(new byte[] { 9, 137, 138 }, new float[] { 0.5f, 0.25f, 0.25f }, 50, 1)); + landscapeTemplates.Add(10, new Landscape(new byte[] { 9, 137, 138 }, new float[] { 0.5f, 0.25f, 0.25f }, 100, 1)); + landscapeTemplates.Add(11, new Landscape(new byte[] { 9, 137, 138 }, new float[] { 0.5f, 0.25f, 0.25f }, 50, 5)); + } + + public int GetHashIdForTime(DateTime time) + { + long bin = time.ToBinary(); + int hashId = CRC32.compute(BitConverter.GetBytes(bin)); + while (ServerEmulator.instance.regMaps.Exists(x => x.Value.Map == hashId)) + { + bin ^= hashId; + hashId = CRC32.compute(BitConverter.GetBytes(bin)); + } + + return hashId; + } + + private byte GetNextTemplateByDistribution(Landscape landscape) + { + float rnd = UnityEngine.Random.Range(landscape.distribution[0], landscape.distribution[landscape.ratios.Length]); + for (int i = 0; i < landscape.bricks.Length; i++) + { + if (rnd >= landscape.distribution[i] && rnd < landscape.distribution[i + 1]) + return landscape.bricks[i]; + } + + return landscape.bricks[0]; + } + + public UserMap GenerateInternal(Landscape landscape, int skyboxIndex) + { + byte size = landscape.size; + byte height = landscape.height; + + UserMap map = new UserMap(); + map.skybox = skyboxIndex; + map.min.x = 0; + map.min.y = 0; + map.min.z = 0; + map.max.x = Convert.ToSingle(size); + map.max.y = Convert.ToSingle(size); + map.max.z = Convert.ToSingle(size); + map.cenX = (map.min.x + map.max.x) * 0.5f; + map.cenZ = (map.min.z + map.max.z) * 0.5f; + + List morphes = new List(); + + int seq = 0; + for (byte x = 0; x < size; x++) + { + for (byte z = 0; z < size; z++) + { + for (byte y = 0; y < height; y++) + { + byte template = GetNextTemplateByDistribution(landscape); + map.AddBrickInst(seq, template, x, y, z, 0, ref morphes); + seq++; + } + } + } + + return map; + } + + public UserMap Generate(int landscapeIndex, int skyboxIndex) + { + return GenerateInternal(landscapeTemplates[landscapeIndex], skyboxIndex); + } + } +} diff --git a/Assembly-CSharp/_Emulator/Network/ChannelManager.cs b/Assembly-CSharp/_Emulator/Network/ChannelManager.cs new file mode 100644 index 0000000..a66f7bd --- /dev/null +++ b/Assembly-CSharp/_Emulator/Network/ChannelManager.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace _Emulator +{ + class ChannelManager + { + //public static ChannelManager instance = new ChannelManager(); + public List channels; + + public ChannelManager() + { + channels = new List(); + SetupDefaultChannels(); + } + + public ChannelReference GetChannelByID(int id) + { + return channels.Find(x => x.channel.Id == id); + } + + public ChannelReference GetDefaultChannel() + { + return channels[0]; + } + + public void AddChannel(Channel channel) + { + channels.Add(new ChannelReference(channel)); + } + + public void AddChannel(int id, Channel.MODE mode, string name) + { + channels.Add((new ChannelReference(new Channel(_id: id, _mode: (int)mode, _name: name, _ip: "", _port: 5000, _userCount: 1, _maxUserCount: 16, _country: 1, _minLvRank: 0, _maxLvRank: 66, _xpBonus: 0, _fpBonus: 0, _limitStarRate: 0)))); + } + + public void SetupDefaultChannels() + { + AddChannel(1, Channel.MODE.BATTLE, "Play"); + AddChannel(2, Channel.MODE.MAPEDIT, "Build"); + } + + public void Shutdown() + { + foreach (ChannelReference channel in channels) + channel.Shutdown(); + channels.Clear(); + } + } +} diff --git a/Assembly-CSharp/_Emulator/Network/ChannelReference.cs b/Assembly-CSharp/_Emulator/Network/ChannelReference.cs new file mode 100644 index 0000000..8404666 --- /dev/null +++ b/Assembly-CSharp/_Emulator/Network/ChannelReference.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace _Emulator +{ + class ChannelReference + { + public Channel channel; + public List matches; + public List clientList; + const int maxRoomNumber = 100; + + public ChannelReference(Channel _channel) + { + channel = _channel; + matches = new List(); + clientList = new List(); + } + + public MatchData GetMatchByRoomNumber(int roomNumber) + { + return matches.Find(x => x.room.No == roomNumber); + } + + public int GetNextRoomNumber() + { + for (int i = 0; i < maxRoomNumber; i++) + { + if (matches.Find(x => x.room.No == i) == null) + return i; + } + + return -1; + } + + public void AddClient(ClientReference client) + { + if (client.channel != null) + client.channel.RemoveClient(client); + client.channel = this; + clientList.Add(client); + channel.UserCount = clientList.Count; + } + + public void RemoveClient(ClientReference client) + { + client.channel = null; + clientList.Remove(client); + channel.UserCount = clientList.Count; + } + + public MatchData AddNewMatch() + { + MatchData matchData = new MatchData(); + matchData.channel = this; + matchData.roomCreated = true; + matchData.room.no = GetNextRoomNumber(); + matches.Add(matchData); + return matchData; + } + + public void AddMatch(MatchData match) + { + match.channel = this; + matches.Add(match); + } + + public void RemoveMatch(MatchData match) + { + match.channel = null; + matches.Remove(match); + } + + public void Shutdown() + { + foreach (MatchData match in matches) + { + match.Shutdown(); + match.channel = null; + } + //clientList.Clear(); + //matches.Clear(); + } + } +} diff --git a/Assembly-CSharp/_Emulator/Network/ChunkedBuffer.cs b/Assembly-CSharp/_Emulator/Network/ChunkedBuffer.cs new file mode 100644 index 0000000..3542518 --- /dev/null +++ b/Assembly-CSharp/_Emulator/Network/ChunkedBuffer.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using Debug = UnityEngine.Debug; + +namespace _Emulator +{ + class ChunkedBuffer + { + public byte[] buffer; + public uint offset; + public uint crc; + public ushort id; + public int lastChunk; + public bool finished; + + public ChunkedBuffer(uint _size, uint _crc, ushort _id) + { + buffer = new byte[_size]; + offset = 0; + crc = _crc; + id = _id; + lastChunk = -1; + } + + public void WriteNext(byte[] next, int chunkId) + { + if (next.Length + offset > buffer.Length) + { + Debug.LogError("ChunkedBuffer.WriteNext: next buffer too big"); + return; + } + lastChunk++; + if (lastChunk != chunkId) + { + Debug.LogError("ChunkedBuffer.WriteNext: chunk order mismatch, was " + chunkId + ", expected " + lastChunk); + return; + } + + Array.Copy(next, 0, buffer, offset, next.Length); + offset += Convert.ToUInt32(next.Length); + } + } +} diff --git a/Assembly-CSharp/_Emulator/Network/ClientExtension.cs b/Assembly-CSharp/_Emulator/Network/ClientExtension.cs index 7dca787..61742b4 100644 --- a/Assembly-CSharp/_Emulator/Network/ClientExtension.cs +++ b/Assembly-CSharp/_Emulator/Network/ClientExtension.cs @@ -1,4 +1,7 @@ -using UnityEngine; +using System; +using System.Diagnostics; +using UnityEngine; +using Debug = UnityEngine.Debug; namespace _Emulator { @@ -21,6 +24,9 @@ public void LoadServer() { gameObject.BroadcastMessage("OnRoundRobin"); } + ShopEmulator shop = new ShopEmulator(); + //shop.LoadAndSave(); + shop.ParseData(); } public void Say(ushort id, MsgBody msgBody) @@ -69,7 +75,7 @@ public bool HandleMessage(Msg2Handle msg) case ExtensionOpcodes.opDisconnectAck: HandleDisconnected(msg._msg); break; - + default: result = false; break; @@ -164,16 +170,17 @@ public void SendInventoryCSV() { MsgBody body = new MsgBody(); - body.Write(inventory.csv._rows.Count); - for (int row = 0; row < inventory.csv._rows.Count; row++) + body.Write(inventory.equipment.Count); + + // Write each item's slot (category) and code + foreach (var item in inventory.equipment) { - body.Write(inventory.csv._rows[row].Length); - for (int col = 0; col < inventory.csv._rows[row].Length; col++) - { - body.Write(inventory.csv._rows[row][col]); - } + body.Write(item.Template.slot.ToString()); // Write the slot (e.g., Main, Secondary) + body.Write(item.Code); // Write the item code + body.Write(item.Usage.ToString()); // Write the item Usage } + // Send the data Say(ExtensionOpcodes.opInventoryAck, body); } @@ -183,5 +190,63 @@ public void SendDisconnect() Say(ExtensionOpcodes.opDisconnectReq, body); } + + public void SendBeginChunkedBuffer(ushort opcode, byte[] buffer) + { + const int maxBufferSize = 1000000000; + if (buffer.Length > maxBufferSize) + { + Debug.LogWarning("ClientExtension.SendBeginChunkedBuffer: Buffer was " + buffer.Length + " bytes"); + return; + } + + uint crc = CRC32.computeUnsigned(buffer); + + MsgBody body = new MsgBody(); + body.Write(opcode); + body.Write(buffer.Length); + body.Write(crc); + + Debug.LogWarning("Begin"); + Say(ExtensionOpcodes.opBeginChunkedBufferReq, body); + SendChunkedBuffer(opcode, buffer); + SendEndChunkedBuffer(opcode, crc); + } + + public void SendChunkedBuffer(ushort opcode, byte[] buffer) + { + int chunkSize = 4096; + int chunkCount = Mathf.CeilToInt((float)buffer.Length / (float)chunkSize); + int processedCount = 0; + + Debug.Log(chunkSize + " " + buffer.Length + " " + chunkCount); + for (int chunk = 0; chunk < chunkCount; chunk++) + { + int remaining = buffer.Length - processedCount; + if (remaining < chunkSize) + chunkSize = remaining; + + MsgBody body = new MsgBody(); + + byte[] next = new byte[chunkSize]; + Array.Copy(buffer, processedCount, next, 0, chunkSize); + body.Write(opcode); + body.Write(chunk); + body.Write(next); + processedCount += chunkSize; + + Debug.LogWarning("Send " + chunk + " " + chunkSize + " " + processedCount); + Say(ExtensionOpcodes.opChunkedBufferReq, body); + } + } + + public void SendEndChunkedBuffer(ushort opcode, uint crc) + { + MsgBody body = new MsgBody(); + body.Write(opcode); + + Debug.LogWarning("End"); + Say(ExtensionOpcodes.opEndChunkedBufferReq, body); + } } } diff --git a/Assembly-CSharp/_Emulator/Network/ClientReference.cs b/Assembly-CSharp/_Emulator/Network/ClientReference.cs index 7f32360..0a82bfb 100644 --- a/Assembly-CSharp/_Emulator/Network/ClientReference.cs +++ b/Assembly-CSharp/_Emulator/Network/ClientReference.cs @@ -1,4 +1,5 @@ -using System.Net.Sockets; +using System.Collections.Generic; +using System.Net.Sockets; namespace _Emulator { @@ -25,6 +26,7 @@ public enum ClientStatus public int deaths = 0; public int assists = 0; public int score = 0; + public bool isZombie = false; public bool isBreakingInto; public float toleranceTime; public ClientStatus clientStatus; @@ -32,6 +34,10 @@ public enum ClientStatus public SlotData slot; public Inventory inventory; public DummyData data; + public MatchData matchData; + public ChannelReference channel; + public ChunkedBuffer chunkedBuffer; + private readonly object dataLock = new object(); public ClientReference(Socket _socket, string _name = "", int _seq = -1) @@ -56,13 +62,17 @@ public void Disconnect(bool send = true) socket.Close(); lock (dataLock) { - ServerEmulator.instance.matchData.RemoveClient(this); + if (matchData != null) + matchData.RemoveClient(this); + if (channel != null) + channel.RemoveClient(this); + //ServerEmulator.instance.matchData.RemoveClient(this); ServerEmulator.instance.clientList.Remove(this); } if (send) { ServerEmulator.instance.SendLeave(this); - ServerEmulator.instance.SendSlotData(); + ServerEmulator.instance.SendSlotData(matchData); } } diff --git a/Assembly-CSharp/_Emulator/Network/DummyData.cs b/Assembly-CSharp/_Emulator/Network/DummyData.cs index a14cf7f..b6f87f7 100644 --- a/Assembly-CSharp/_Emulator/Network/DummyData.cs +++ b/Assembly-CSharp/_Emulator/Network/DummyData.cs @@ -3,11 +3,11 @@ class DummyData { public int xp = 7000000; - public int forcePoints = int.MaxValue; - public int brickPoints = int.MaxValue; - public int tokens = int.MaxValue; - public int coins = int.MaxValue; - public int starDust = int.MaxValue; + public int forcePoints = 100000000; + public int brickPoints = 100000000; + public int tokens = 100000000; + public int coins = 100000000; + public int starDust = 100000000; public int gm = 0; public int clanSeq = 0; public string clanName = ""; @@ -21,10 +21,22 @@ class DummyData public int handGun = 0; public int melee = 0; public int special = 0; - public sbyte tutorialed = 1; + public sbyte tutorialed = 3; public int countryFilter = -1; public sbyte tos = 1; public int extraSlots = 0; public int firstLoginFp = 0; + public static string[][] startingGear = + { + new string[] { "MAIN", "wau" }, + new string[] { "AUX", "wax" }, + new string[] { "BOMB", "wba" }, + new string[] { "MELEE", "wap" }, + new string[] { "UPPER", "aac" }, + new string[] { "LOWER", "aad" }, + new string[] { "BRICK-GUN", "s07" }, + new string[] { "NONE","sb7", "sb8", "sb9", "sc0", "sc1", "sc2", "sc3", "sc4", "s34", "s43", "s78", "s79" } + }; + } } diff --git a/Assembly-CSharp/_Emulator/Network/ExtensionOpcodes.cs b/Assembly-CSharp/_Emulator/Network/ExtensionOpcodes.cs index 5a9e3e4..b8f7fdd 100644 --- a/Assembly-CSharp/_Emulator/Network/ExtensionOpcodes.cs +++ b/Assembly-CSharp/_Emulator/Network/ExtensionOpcodes.cs @@ -10,5 +10,12 @@ class ExtensionOpcodes public const int opCustomMessageAck = 1005; public const int opDisconnectReq = 1006; public const int opDisconnectAck = 1007; + public const int opBeginChunkedBufferReq = 1008; + public const int opChunkedBufferReq = 1009; + public const int opEndChunkedBufferReq = 1010; + public const int opBeginChunkedBufferAck= 1011; + public const int opChunkedBufferAck = 1012; + public const int opEndChunkedBufferAck = 1013; + public const int opChunkedBufferThumbnailReq = 1014; } } diff --git a/Assembly-CSharp/_Emulator/Network/Inventory.cs b/Assembly-CSharp/_Emulator/Network/Inventory.cs index 855ed7f..f972949 100644 --- a/Assembly-CSharp/_Emulator/Network/Inventory.cs +++ b/Assembly-CSharp/_Emulator/Network/Inventory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using UnityEngine; @@ -9,7 +10,6 @@ namespace _Emulator class Inventory { public int seq; - public CSVLoader csv; public List equipment; public Item[] weaponChg; public Item[] shooterTools; @@ -18,20 +18,21 @@ class Inventory public string[] weaponChgString; public const int maxItems = 400; - public Inventory(int _seq, CSVLoader _csv = null) + public Inventory(int _seq) { equipment = new List(); weaponChg = new Item[5]; shooterTools = new Item[5]; - activeSlots = new Item[16]; - csv = _csv; + activeSlots = new Item[19]; seq = _seq; - if (csv != null) + LoadInventoryFromMemory(); + + /*if (csv != null) LoadInventoryFromMemory(); else - LoadInventoryFromDisk(); - Sort(); + LoadInventoryFromDisk();*/ + //Sort(); } public void Apply() @@ -39,7 +40,7 @@ public void Apply() MyInfoManager.Instance.inventory.Clear(); foreach (Item item in equipment) { - MyInfoManager.Instance.SetItem(item.Seq, item.Code, item.Usage, -1, 0, 1000); + MyInfoManager.Instance.SetItem(item.Seq, item.Code, item.Usage, item.Remain, 0, 1000); } GameObject mainObject = GameObject.Find("Main"); Lobby lobby = mainObject.GetComponent(); @@ -57,7 +58,7 @@ public void Apply() } } - public Item AddItem(TItem template, bool sort = false) + public Item AddItem(TItem template, bool sort = false, int amount = -1, Item.USAGE usage = Item.USAGE.UNEQUIP) { if (equipment.Count >= maxItems) return null; @@ -76,8 +77,7 @@ public Item AddItem(TItem template, bool sort = false) baseSeq[i] ^= codeSeed[i]; long itemSeq = BitConverter.ToInt64(baseSeq, 0) * seqSeed; - Item.USAGE usage = Item.USAGE.UNEQUIP; - Item item = new Item(itemSeq, template, template.code, usage, -1, 0, 1000); + Item item = new Item(itemSeq, template, template.code, usage, amount, 0, 1000); equipment.Add(item); if (sort) @@ -122,6 +122,17 @@ public void RemoveItem(Item item) GenerateActiveSlots(); GenerateActiveTools(); GenerateActiveChange(); + UpdateCSV(); + } + + public void RemoveItem(long seq) + { + Item item = equipment.Find(x => x.Seq == seq); + equipment.Remove(item); + GenerateActiveSlots(); + GenerateActiveTools(); + GenerateActiveChange(); + UpdateCSV(); } public void Sort() @@ -131,7 +142,7 @@ public void Sort() public void GenerateActiveSlots() { - activeSlots = new Item[16]; + activeSlots = new Item[19]; List activeItems = equipment.FindAll(x => x.Usage == Item.USAGE.EQUIP && x.Template.type < TItem.TYPE.SPECIAL); equipmentString = new string[activeItems.Count]; for (int i = 0; i < activeItems.Count; i++) @@ -164,7 +175,30 @@ public void GenerateActiveChange() } } - public void UpdateCSV() + public void UpdateCSV(string filePath = "Config\\Inventory.csv") + { + try + { + // Ensure the directory exists + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + + using (StreamWriter writer = new StreamWriter(filePath)) + { + foreach (var item in equipment) + { + writer.WriteLine($"{item.Template.slot};{item.Code};{item.Usage}"); + } + } + + Debug.Log($"Equipment successfully saved to {filePath}."); + } + catch (Exception ex) + { + Debug.LogError($"Failed to save equipment to {filePath}: {ex.Message}"); + } + } + + /*public void UpdateCSV() { csv.Save("Config\\InventoryBackup.csv"); GenerateActiveSlots(); @@ -220,101 +254,121 @@ public void LoadInventoryFromDisk(string path = "Config\\Inventory.csv") csv._rows.RemoveRange(maxItems, csv._rows.Count - maxItems); LoadInventoryFromMemory(); - } + }*/ public void LoadInventoryFromMemory() { - int col = 1; - Dictionary weaponSlots = new Dictionary(); - for (int row = 0; row < csv.Rows && row < maxItems; row++) - { - if (!csv.ReadValue(col, row, "", out string code)) - continue; + string filePath = "Config\\Inventory.csv"; + + // Ensure the directory exists + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); - if (code != "") + // Check if the file exists + if (!File.Exists(filePath)) + { + foreach (var category in DummyData.startingGear) { - TItem template = TItemManager.Instance.Get(code); - if (template == null) - continue; + string categoryName = category[0]; + for (int i = 1; i < category.Length; i++) + { + TItem template = TItemManager.Instance.Get(category[i]); + if (template == null) + continue; - Item item = AddItem(template); + Item item = AddItem(template); - if (item != null) - { - if (row < 21) + if (item != null) { - if (row > 15) + if (categoryName != "NONE") { - if (item.IsShooterSlotAble) - item.toolSlot = (sbyte)(row - 16); + item.Usage = Item.USAGE.EQUIP; } - - else + else if (item.Code == "s92" || item.Code == "s08" || item.Code == "s09" || item.Code == "s07") + { + //check for all build guns but only if in starting gear item.Usage = Item.USAGE.EQUIP; + } } } + } + //Debug.Log($"Inventory file created at {filePath}."); + } else + { + // Read data from the CSV file + foreach (string line in File.ReadAllLines(filePath)) + { + string[] parts = line.Split(';'); + if (parts.Length < 3) + continue; + + string categoryName = parts[0]; + string code = parts[1]; + Item.USAGE usage = (Item.USAGE) Enum.Parse(typeof(Item.USAGE), parts[2], true); - if (row >= 21 && row < 26) + if (!string.IsNullOrEmpty(code)) { - weaponSlots.Add(row - 21, template.code); + TItem template = TItemManager.Instance.Get(code); + if (template == null) + continue; + + Item item = AddItem(template); + + if (item != null) + { + item.Usage = usage; + } } } } - foreach (KeyValuePair entry in weaponSlots) - { - Item item = equipment.Find(x => x.Code == entry.Value); - if (item != null) - { - if (item.IsWeaponSlotAble) - item.toolSlot = (sbyte)entry.Key; - } - } GenerateActiveSlots(); GenerateActiveTools(); GenerateActiveChange(); } + public static int SlotToIndex(TItem.SLOT slot) { switch (slot) { case TItem.SLOT.UPPER: - return 5; + return 0; case TItem.SLOT.LOWER: - return 6; + return 1; case TItem.SLOT.MELEE: return 2; case TItem.SLOT.MAIN: - return 0; + return 4; case TItem.SLOT.AUX: - return 1; - case TItem.SLOT.BOMB: return 3; + case TItem.SLOT.BOMB: + return 5; case TItem.SLOT.HEAD: - return 4; + return 6; case TItem.SLOT.FACE: - return 11; + return 7; case TItem.SLOT.BACK: - return 10; + return 8; case TItem.SLOT.LEG: - return 12; + return 9; case TItem.SLOT.SASH1: - return 14; + return 10; case TItem.SLOT.SASH2: - return 14; + return 11; case TItem.SLOT.SASH3: - return 14; + return 12; case TItem.SLOT.KIT: - return 13; + return 16; case TItem.SLOT.LAUNCHER: - return 7; + return 13; case TItem.SLOT.MAGAZINE_L: - return 8; + return 14; case TItem.SLOT.MAGAZINE_R: - return 9; - case TItem.SLOT.CHARACTER: return 15; + case TItem.SLOT.CHARACTER: + return 17; + case TItem.SLOT.NUM: + return 18; } return -1; diff --git a/Assembly-CSharp/_Emulator/Network/MatchData.cs b/Assembly-CSharp/_Emulator/Network/MatchData.cs index decbef0..69b4825 100644 --- a/Assembly-CSharp/_Emulator/Network/MatchData.cs +++ b/Assembly-CSharp/_Emulator/Network/MatchData.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace _Emulator @@ -24,8 +26,40 @@ class MatchData public Dictionary usedCannons; public Dictionary usedTrains; public List killLog; + public ChannelReference channel; public Room room; + //CTF + public int ctfRedKillCount; + public int ctfBlueKillCount; + + //Build only + public UserMap cachedMap; + public UserMapInfo cachedUMI; + public bool mapCached; + + //BND + public bool isBuildPhase; // Current phase: true = Build, false = Destroy + public bool useBuildGun; + public int repeat; // Total number of Build-and-Destroy rounds + public int currentRound; // Current round number + public int buildPhaseTime; // Time (in seconds) for Build phase + public int battlePhaseTime; // Time (in seconds) for Destroy phase + + //Zombie + public List humanPlayers; + public List zombiePlayers; + public List killedPlayers; + public List infectedPlayers; + public bool roundInit; + public int zombieCountdown; + public int zombieRounds; + public int zombieCurrentRound; + public int zombieRoundsLeft; + public int zombieTimePerRound; + public double zombieDeltaTimer; + public ZombieMatch.STEP zombieStatus; + public MatchData() { countdownTime = 0; @@ -51,13 +85,32 @@ public MatchData() List> split = Utils.SplitList(slots, 8); redSlots = split[0]; blueSlots = split[1]; + isBuildPhase = true; + repeat = 0; + currentRound = 1; + buildPhaseTime = 0; + battlePhaseTime = 0; for (int i = 0; i < redSlots.Count; i++) redSlots[i].isRed = true; - + ctfRedKillCount = 0; + ctfBlueKillCount = 0; room = new Room(false, 0, "", Room.ROOM_TYPE.TEAM_MATCH, Room.ROOM_STATUS.WAITING, 0, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, false, false, false, 0, 0); - } + cachedMap = new UserMap(); + mapCached = false; + roundInit = true; + humanPlayers = new List(); + zombiePlayers = new List(); + killedPlayers = new List(); + infectedPlayers = new List(); + zombieCountdown = 0; + zombieRounds = 0; + zombieTimePerRound = 0; + zombieRoundsLeft = 0; + zombieDeltaTimer = 0; + zombieCurrentRound = 1; + } public void Reset() { @@ -68,6 +121,13 @@ public void Reset() usedCannons.Clear(); usedTrains.Clear(); killLog.Clear(); + ctfRedKillCount = 0; + ctfBlueKillCount = 0; + isBuildPhase = true; + repeat = 0; + currentRound = 1; + buildPhaseTime = 0; + battlePhaseTime = 0; room.Status = Room.ROOM_STATUS.WAITING; for (int i = 0; i < clientList.Count; i++) { @@ -75,8 +135,97 @@ public void Reset() clientList[i].deaths = 0; clientList[i].kills = 0; clientList[i].assists = 0; + clientList[i].isZombie = false; clientList[i].score = 0; } + roundInit = true; + humanPlayers = new List(); + zombiePlayers = new List(); + killedPlayers = new List(); + infectedPlayers = new List(); + zombieCountdown = 0; + zombieRounds = 0; + zombieTimePerRound = 0; + zombieRoundsLeft = 0; + zombieDeltaTimer = 0; + zombieCurrentRound = 1; + } + + // Method to reset data for a new round + public void ResetForNewRound() + { + // Reset round-specific data + remainTime = countdownTime; // assuming countdownTime is set to the desired round duration + playTime = 0; + destroyedBricks.Clear(); + usedCannons.Clear(); + usedTrains.Clear(); + killLog.Clear(); + roundInit = true; + humanPlayers = new List(); + zombiePlayers = new List(); + killedPlayers = new List(); + infectedPlayers = new List(); + zombieCountdown = 0; + zombieDeltaTimer = 0; + zombieStatus = ZombieMatch.STEP.WAITING; + foreach(ClientReference client in clientList) + { + client.isZombie = false; + } + } + + public void Shutdown() + { + foreach (ClientReference client in clientList) + { + client.matchData = null; + client.DetachSlot(); + client.clientStatus = ClientReference.ClientStatus.Lobby; + client.status = BrickManDesc.STATUS.PLAYER_WAITING; + client.deaths = 0; + client.kills = 0; + client.assists = 0; + client.score = 0; + room.CurPlayer = clientList.Count; + } + + Reset(); + } + + public void CacheMap(RegMap regMap, UserMapInfo umi) + { + if (regMap != null) + { + mapCached = true; + cachedMap.Clear(); + cachedMap.Load(regMap.Map); + cachedUMI = umi; + cachedUMI.AssignRegMap(regMap); + cachedUMI.Alias = cachedUMI.regMap.Alias; + } + + else + Debug.LogError("Couldn't cache map"); + } + + public void CacheMapGenerate(int landscapeIndex, int skyboxIndex, string alias) + { + mapCached = true; + cachedMap.Clear(); + cachedMap = MapGenerator.instance.Generate(landscapeIndex, skyboxIndex); + DateTime time = DateTime.Now; + int hashId = MapGenerator.instance.GetHashIdForTime(time); + cachedMap.map = hashId; + cachedUMI = new UserMapInfo(hashId, alias, cachedMap.dic.Keys.Count, time, 0); + } + + public int GetNextBrickSeq() + { + int seq = UnityEngine.Random.Range(0, int.MaxValue); + while (cachedMap.dic.ContainsKey(seq)) + seq = UnityEngine.Random.Range(0, int.MaxValue); + return seq; } public sbyte GetWinningTeam() @@ -122,21 +271,40 @@ public void EndMatch() switch (room.Type) { case Room.ROOM_TYPE.TEAM_MATCH: - ServerEmulator.instance.HandleTeamMatchEnd(); + ServerEmulator.instance.HandleTeamMatchEnd(this); break; case Room.ROOM_TYPE.INDIVIDUAL: - ServerEmulator.instance.HandleIndividualMatchEnd(); + ServerEmulator.instance.HandleIndividualMatchEnd(this); + break; + + case Room.ROOM_TYPE.CAPTURE_THE_FLAG: + ServerEmulator.instance.HandleCTFMatchEnd(this); + break; + + case Room.ROOM_TYPE.BND: + /*Debug.LogWarning("MatchDataEndMatch repeat:" + repeat + " remainTime: " + remainTime + " isBuildPhase: " + isBuildPhase); + if (repeat <= 0 && remainTime <0 && !isBuildPhase) + { + ServerEmulator.instance.HandleBNDMatchEnd(this); + }*/ + ServerEmulator.instance.HandleBNDMatchEnd(this); + break; + + case Room.ROOM_TYPE.ZOMBIE: + Debug.LogWarning("ZombieMatchend"); + ServerEmulator.instance.HandleZombieMatchEnd(this); break; default: - ServerEmulator.instance.HandleIndividualMatchEnd(); + ServerEmulator.instance.HandleIndividualMatchEnd(this); break; } } public void AddClient(ClientReference client) { + client.matchData = this; client.AssignSlot(GetNextFreeSlot()); client.clientStatus = ClientReference.ClientStatus.Room; clientList.Add(client); @@ -145,6 +313,7 @@ public void AddClient(ClientReference client) public void RemoveClient(ClientReference client) { + client.matchData = null; client.DetachSlot(); client.clientStatus = ClientReference.ClientStatus.Lobby; client.status = BrickManDesc.STATUS.PLAYER_WAITING; diff --git a/Assembly-CSharp/_Emulator/Network/MsgReference.cs b/Assembly-CSharp/_Emulator/Network/MsgReference.cs index f6fab75..4dce212 100644 --- a/Assembly-CSharp/_Emulator/Network/MsgReference.cs +++ b/Assembly-CSharp/_Emulator/Network/MsgReference.cs @@ -4,6 +4,7 @@ public enum SendType { Unicast, Broadcast, + BroadcastChannel, BroadcastRoom, BroadcastRoomExclusive, BroadcastRedTeam, @@ -14,21 +15,27 @@ class MsgReference public Msg2Handle msg; public ClientReference client; public SendType sendType; + public ChannelReference channelRef; + public MatchData matchData; - public MsgReference(Msg2Handle _msg, ClientReference _client, SendType _sendType = SendType.Unicast) + public MsgReference(Msg2Handle _msg, ClientReference _client, SendType _sendType = SendType.Unicast, ChannelReference _channelRef = null, MatchData _matchData = null) { msg = _msg; sendType = _sendType; if (_client != null) client = _client; + channelRef = _channelRef; + matchData = _matchData; } - public MsgReference(ushort _id, MsgBody _msg, ClientReference _client, SendType _sendType = SendType.Unicast) + public MsgReference(ushort _id, MsgBody _msg, ClientReference _client, SendType _sendType = SendType.Unicast, ChannelReference _channelRef = null, MatchData _matchData = null) { msg = new Msg2Handle(_id, _msg); sendType = _sendType; if (_client != null) client = _client; + channelRef = _channelRef; + matchData = _matchData; } } } diff --git a/Assembly-CSharp/_Emulator/Network/ServerEmulator.cs b/Assembly-CSharp/_Emulator/Network/ServerEmulator.cs index a5295ea..b0f719c 100644 --- a/Assembly-CSharp/_Emulator/Network/ServerEmulator.cs +++ b/Assembly-CSharp/_Emulator/Network/ServerEmulator.cs @@ -1,2515 +1,3540 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Security.Policy; using System.Text.RegularExpressions; using UnityEngine; +using static Room; +using Debug = UnityEngine.Debug; namespace _Emulator { class ServerEmulator : MonoBehaviour { - public static ServerEmulator instance; - private readonly object dataLock = new object(); - public List clientList = new List(); + public static ServerEmulator instance; + private readonly object dataLock = new object(); + public List clientList = new List(); private Socket serverSocket; - private byte recvKey = byte.MaxValue; - private byte sendKey = byte.MaxValue; - private Queue readQueue = new Queue(); - private Queue writeQueue = new Queue(); - private int curSeq = 0; - public bool debugHandle = false; - public bool debugSend = false; - public bool debugPing = false; - public bool serverCreated = false; - public MatchData matchData; - private Channel defaultChannel; - private float killLogTimer = 0f; - private List> regMaps = new List>(); - private bool waitForShutDown = false; - - private void Start() - { - matchData = new MatchData(); - defaultChannel = new Channel(_id: 1, _mode: 2, _name: "Default", _ip: "", _port: 5000, _userCount: 1, _maxUserCount: 16, _country: 1, _minLvRank: 0, _maxLvRank: 66, _xpBonus: 0, _fpBonus: 0, _limitStarRate: 0); - } - - public void SetupServer() - { - try - { - if (serverSocket == null) - { - serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - serverSocket.Bind(new IPEndPoint(IPAddress.Any, 5000)); - } - serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - serverSocket.Listen(16); - serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); - serverCreated = true; - Debug.Log("Server created"); - } + private byte recvKey = byte.MaxValue; + private byte sendKey = byte.MaxValue; + private Queue readQueue = new Queue(); + private Queue writeQueue = new Queue(); + private int curSeq = 0; + public bool debugHandle = false; + public bool debugSend = false; + public bool debugPing = false; + public bool serverCreated = false; + //public MatchData matchData; + //private Channel defaultChannel; + public ChannelManager channelManager = new ChannelManager(); + private float killLogTimer = 0f; + public List> regMaps = new List>(); + private bool waitForShutDown = false; + + private void Start() + { + //matchData = new MatchData(); + } - catch (Exception ex) - { - Debug.LogError("SetupServer: " + ex.Message); - } + public void SetupServer() + { + try + { + if (serverSocket == null) + { + serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + serverSocket.Bind(new IPEndPoint(IPAddress.Any, 5000)); + } + serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + serverSocket.Listen(16); + serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); + serverCreated = true; + Debug.Log("Server created"); + } + + catch (Exception ex) + { + Debug.LogError("SetupServer: " + ex.Message); + } + + //Pulls all loaded RegMaps into the emulator + regMaps = RegMapManager.Instance.dicRegMap.ToList(); + } + + private void AcceptCallback(IAsyncResult result) + { + try + { + Socket clientSocket = serverSocket.EndAccept(result); + + ClientReference client = new ClientReference(clientSocket); + if (!Config.instance.blockConnections) + { + if (HandleClientAccepted(client)) + clientSocket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client); + else + SendDisconnect(client); + } + + else + SendDisconnect(client); + } + + catch (Exception ex) + { + Debug.LogError("AcceptCallback: " + ex.Message); + } + + finally + { + serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); + } + } + + private void ReceiveCallback(IAsyncResult result) + { + try + { + ClientReference client = (ClientReference)result.AsyncState; + int numBytes = client.socket.EndReceive(result); + Msg4Recv recv = new Msg4Recv(client.buffer); + recv._hdr.FromArray(recv.Buffer); + MsgBody msgBody = recv.Flush(); + msgBody.Decrypt(recvKey); + + lock (dataLock) + { + if (numBytes <= 0) + client.Disconnect(true); + else + { + readQueue.Enqueue(new MsgReference(new Msg2Handle(recv.GetId(), msgBody), client, _channelRef: client.channel, _matchData: client.matchData)); + //HandleMessages(); + } + } + + client.buffer = new byte[8192]; + if (numBytes > 0) + client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client); + } + + catch (Exception ex) + { + Debug.LogError("ReceiveCallback: " + ex.Message); + } + } + + private void SendCallback(IAsyncResult result) + { + Socket clientSocket = (Socket)result.AsyncState; + clientSocket.EndSend(result); + } + + private void UnicastMessage(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + msgRef.client.socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), msgRef.client.socket); + } + private void BroadcastMessage(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < clientList.Count; i++) + { + clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); + } + } + + private void BroadcastChannelMessage(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < msgRef.channelRef.clientList.Count; i++) + { + msgRef.channelRef.clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), msgRef.channelRef.clientList[i].socket); + } + } + + private void BroadcastRoomMessage(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < msgRef.matchData.clientList.Count; i++) + { + if (msgRef.matchData.clientList[i].clientStatus < ClientReference.ClientStatus.Room) + continue; - regMaps = RegMapManager.Instance.dicRegMap.ToList(); - } + msgRef.matchData.clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), msgRef.matchData.clientList[i].socket); + } + } - private void AcceptCallback(IAsyncResult result) + private void BroadcastRedTeamMessage(MsgReference msgRef) { - try - { - Socket clientSocket = serverSocket.EndAccept(result); - - ClientReference client = new ClientReference(clientSocket); - if (!Config.instance.blockConnections) - { - if (HandleClientAccepted(client)) - clientSocket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client); - else - SendDisconnect(client); - } - - else - SendDisconnect(client); - } + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < clientList.Count; i++) + { + if (clientList[i].clientStatus < ClientReference.ClientStatus.Room || !clientList[i].slot.isRed) + continue; - catch (Exception ex) - { - Debug.LogError("AcceptCallback: " + ex.Message); - } + clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); + } + } - finally - { - serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); - } - } + private void BroadcastBlueTeamMessage(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < clientList.Count; i++) + { + if (clientList[i].clientStatus < ClientReference.ClientStatus.Room || clientList[i].slot.isRed) + continue; - private void ReceiveCallback(IAsyncResult result) - { - try - { - ClientReference client = (ClientReference)result.AsyncState; - int numBytes = client.socket.EndReceive(result); - Msg4Recv recv = new Msg4Recv(client.buffer); - recv._hdr.FromArray(recv.Buffer); - MsgBody msgBody = recv.Flush(); - msgBody.Decrypt(recvKey); - - lock (dataLock) - { - if (numBytes <= 0) - client.Disconnect(true); - else - { - readQueue.Enqueue(new MsgReference(new Msg2Handle(recv.GetId(), msgBody), client)); - HandleMessages(); - } - } - - client.buffer = new byte[8192]; - if (numBytes > 0) - client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client); - } + clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); + } + } - catch(Exception ex) - { - Debug.LogError("ReceiveCallback: " + ex.Message); - } - } - - private void SendCallback(IAsyncResult result) - { - Socket clientSocket = (Socket)result.AsyncState; - clientSocket.EndSend(result); - } - - private void UnicastMessage(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - msgRef.client.socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), msgRef.client.socket); - } - private void BroadcastMessage(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - for (int i = 0; i < clientList.Count; i++) - { - clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); - } - } + private void BroadcastRoomMessageExclusive(MsgReference msgRef) + { + Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); + for (int i = 0; i < msgRef.matchData.clientList.Count; i++) + { + if (msgRef.matchData.clientList[i].socket == msgRef.client.socket || msgRef.matchData.clientList[i].clientStatus < ClientReference.ClientStatus.Room) + continue; - private void BroadcastRoomMessage(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - for (int i = 0; i < clientList.Count; i++) - { - if (clientList[i].clientStatus < ClientReference.ClientStatus.Room) - continue; + msgRef.matchData.clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), msgRef.matchData.clientList[i].socket); + } + } - clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); - } - } + private ClientReference FindClientBySocket(Socket clientSocket) + { + ClientReference client = clientList.Find(x => x.socket == clientSocket); + if (client == null) + Debug.LogError("FindClientBySocket: Could not find ClientReference for client: " + clientSocket.RemoteEndPoint.ToString()); + return client; - private void BroadcastRedTeamMessage(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - for (int i = 0; i < clientList.Count; i++) - { - if (clientList[i].clientStatus < ClientReference.ClientStatus.Room || !clientList[i].slot.isRed) - continue; + } - clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); - } - } + public void ShutdownInit() + { + channelManager.Shutdown(); + channelManager = new ChannelManager(); + //matchData = new MatchData(); + curSeq = 0; + serverCreated = false; + SendDisconnect(null, SendType.Broadcast); + waitForShutDown = true; + } + + public void ShutdownFinally() + { + lock (dataLock) + { + waitForShutDown = false; + serverSocket.Shutdown(SocketShutdown.Both); + serverSocket.Close(); + ClearBuffers(); + clientList.Clear(); + } + } + + public void ClearBuffers() + { + lock (dataLock) + { + writeQueue.Clear(); + readQueue.Clear(); + } + } + + public void Say(MsgReference msg) + { + lock (dataLock) + { + writeQueue.Enqueue(msg); + //SendMessages(); + } + } + + public void SayInstant(MsgReference msg) + { + lock (dataLock) + { + writeQueue.Enqueue(msg); + SendMessages(); + } + } + + private void Update() + { + if (!serverCreated) + return; + + lock (dataLock) + { + if (waitForShutDown && clientList.Count == 0) + ShutdownFinally(); + + killLogTimer += Time.deltaTime; + HandleDeadClients(); + HandleMessages(); + SendMessages(); + } + } + + public void Reset() + { + ClearBuffers(); + channelManager.Shutdown(); + channelManager = new ChannelManager(); + //matchData.Reset(); + //matchData = new MatchData(); + foreach (ClientReference client in clientList) + { + SendChannels(client); + SendKick(client); + SendRoomList(client); + } + SendCustomMessage("Reset By Host"); + } + + private void HandleDeadClients() + { + if (!Config.instance.autoClearDeadClients) + return; + + foreach (ClientReference client in clientList) + { + if (client.seq == -1) + { + client.toleranceTime += Time.deltaTime; + if (client.toleranceTime >= 3f) + client.Disconnect(false); + } + } + } + + private void HandleMessages() + { + if (readQueue.Count < 1) + return; - private void BroadcastBlueTeamMessage(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - for (int i = 0; i < clientList.Count; i++) - { - if (clientList[i].clientStatus < ClientReference.ClientStatus.Room || clientList[i].slot.isRed) - continue; + MsgReference msgRef = readQueue.Peek(); + + try + { + if (debugSend) + Debug.Log($"[Verbose] Processing message ID: {msgRef.msg._id} from client: {msgRef.client.GetIdentifier()}"); + switch (msgRef.msg._id) + { + case 1: + HandleLoginRequest(msgRef); + break; - clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); - } - } + case 3: + HandleHeartbeat(msgRef); + break; - private void BroadcastRoomMessageExclusive(MsgReference msgRef) - { - Msg4Send data = new Msg4Send(msgRef.msg._id, uint.MaxValue, uint.MaxValue, msgRef.msg._msg, sendKey); - for (int i = 0; i < clientList.Count; i++) - { - if (clientList[i].socket == msgRef.client.socket || clientList[i].clientStatus < ClientReference.ClientStatus.Room) - continue; + case 4: + HandleRoomListRequest(msgRef); + break; - clientList[i].socket.BeginSend(data.Buffer, 0, data.Buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientList[i].socket); - } - } - - private ClientReference FindClientBySocket(Socket clientSocket) - { - ClientReference client = clientList.Find(x => x.socket == clientSocket); - if (client == null) - Debug.LogError("FindClientBySocket: Could not find ClientReference for client: " + clientSocket.RemoteEndPoint.ToString()); - return client; - - } - - public void ShutdownInit() - { - matchData = new MatchData(); - curSeq = 0; - serverCreated = false; - SendDisconnect(null, SendType.Broadcast); - waitForShutDown = true; - } - - public void ShutdownFinally() - { - lock (dataLock) - { - waitForShutDown = false; - serverSocket.Shutdown(SocketShutdown.Both); - serverSocket.Close(); - ClearBuffers(); - clientList.Clear(); - } - } + case 7: + HandleCreateRoomRequest(msgRef); + break; - public void ClearBuffers() - { - lock (dataLock) - { - writeQueue.Clear(); - readQueue.Clear(); - } - } + case 13: + HandleAddBrickRequest(msgRef); + break; - public void Say(MsgReference msg) - { - lock (dataLock) - { - writeQueue.Enqueue(msg); - SendMessages(); - } - } + case 15: + HandleDelBrickRequest(msgRef); + break; - public void SayInstant(MsgReference msg) - { - lock (dataLock) - { - writeQueue.Enqueue(msg); - SendMessages(); - } - } + case 19: + Debug.LogWarning("PaletteManagerRequest"); + break; - private void Update() - { - if (!serverCreated) - return; + case 20: + HandleCacheBrickRequest(msgRef); + break; - lock (dataLock) - { - if (waitForShutDown && clientList.Count == 0) - ShutdownFinally(); + case 23: + HandleLeave(msgRef); + break; - killLogTimer += Time.deltaTime; - HandleDeadClients(); - //HandleMessages(); - //SendMessages(); - } - } - - public void Reset() - { - ClearBuffers(); - matchData.Reset(); - matchData = new MatchData(); - foreach(ClientReference client in clientList) - { - SendKick(client); - SendRoomList(client); - } - SendCustomMessage("Reset By Host"); - } + case 24: + HandleChatRequest(msgRef); + break; - private void HandleDeadClients() - { - if (!Config.instance.autoClearDeadClients) - return; + case 28: + HandleJoinRequest(msgRef); + break; - foreach (ClientReference client in clientList) - { - if (client.seq == -1) - { - client.toleranceTime += Time.deltaTime; - if (client.toleranceTime >= 3f) - client.Disconnect(false); - } - } - } + case 32: + HandleResumeRoomRequest(msgRef); + break; - private void HandleMessages() - { - if (readQueue.Count < 1) - return; + case 35: + HandleEquipRequest(msgRef); + break; - MsgReference msgRef = readQueue.Peek(); + case 37: + HandleUnequipRequest(msgRef); + break; - try - { - switch (msgRef.msg._id) - { - case 1: - HandleLoginRequest(msgRef); - break; + case 39: + HandleSaveMap(msgRef); + break; - case 3: - HandleHeartbeat(msgRef); - break; + case 42: + HandleLoadComplete(msgRef); + break; - case 4: - HandleRoomListRequest(msgRef); - break; + case 44: + HandleKillLogRequest(msgRef); + break; - case 7: - HandleCreateRoomRequest(msgRef); - break; + case 47: + HandleSetStatusRequest(msgRef); + break; - case 23: - HandleLeave(msgRef); - break; + case 49: + HandleStartRequest(msgRef); + break; - case 24: - HandleChatRequest(msgRef); - break; + case 51: + HandleRegisterMapRequest(msgRef); + break; - case 28: - HandleJoinRequest(msgRef); - break; + case 63: + HandleRespawnTicketRequest(msgRef); + break; - case 32: - HandleResumeRoomRequest(msgRef); - break; + case 65: + HandleTimer(msgRef); + break; - case 35: - HandleEquipRequest(msgRef); - break; + case 71: + HandleMatchCountdown(msgRef); + break; - case 42: - HandleLoadComplete(msgRef); - break; + case 73: + HandleBreakIntoRequest(msgRef); + break; + + case 75: + HandleTeamScoreRequest(msgRef); + break; - case 44: - HandleKillLogRequest(msgRef); - break; + case 76: + HandleDestroyBrickRequest(msgRef); + break; - case 47: - HandleSetStatusRequest(msgRef); - break; + case 80: + HandleTeamChangeRequest(msgRef); + break; - case 49: - HandleStartRequest(msgRef); - break; + case 85: + HandleSlotLockRequest(msgRef); + break; - case 63: - HandleRespawnTicketRequest(msgRef); - break; + case 91: + HandleRoomConfig(msgRef); + break; - case 65: - HandleTimer(msgRef); - break; + case 93: + HandleTeamChatRequest(msgRef); + break; - case 71: - HandleMatchCountdown(msgRef); - break; + case 95: + HandleRadioMsgRequest(msgRef); + break; - case 73: - HandleBreakIntoRequest(msgRef); - break; + case 121: + HandleBuyRequest(msgRef); + break; - case 75: - HandleTeamScoreRequest(msgRef); - break; + case 135: + HandleP2PComplete(msgRef); + break; - case 76: - HandleDestroyBrickRequest(msgRef); - break; + case 137: + HandleResultDoneRequest(msgRef); + break; - case 80: - HandleTeamChangeRequest(msgRef); - break; + case 143: + HandleRoamout(msgRef); + break; - case 85: - HandleSlotLockRequest(msgRef); - break; + case 145: + HandleRoamin(msgRef); + break; - case 91: - HandleRoomConfig(msgRef); - break; - - case 93: - HandleTeamChatRequest(msgRef); - break; - - case 95: - HandleRadioMsgRequest(msgRef); - break; - - case 135: - HandleP2PComplete(msgRef); - break; - - case 137: - HandleResultDoneRequest(msgRef); - break; + case 158: + HandleGetCannonRequest(msgRef); + break; - case 145: - HandleRoamin(msgRef); - break; + case 160: + HandleEmptyCannonRequest(msgRef); + break; - case 158: - HandleGetCannonRequest(msgRef); - break; + case 262: + HandleGetBack2SpawnerRequest(msgRef); + break; - case 160: - HandleEmptyCannonRequest(msgRef); - break; + case 264: + HandleMatchRestartCountRequest(msgRef); + break; - case 333: - HandleSetShooterToolRequest(msgRef); - break; + case 266: + HandleMatchRestartRequest(msgRef); + break; - case 334: - HandleClearShooterTools(msgRef); - break; + case 285: + HandlePickFlagRequest(msgRef); + break; - case 337: - HandleRegMapInfoRequest(msgRef); - break; + case 287: + HandleCaptureFlagRequest(msgRef); + break; - case 368: - HandleWeaponHeldRatioRequest(msgRef); - break; + case 289: + HandleDropFlagRequest(msgRef); + break; - case 389: - HandleDelegateMasterRequest(msgRef); - break; + case 295: + HandleCTFScoreRequest(msgRef); + break; - case 414: - HandleWeaponChangeRequest(msgRef); - break; + case 304: + HandleChangeEditorPermissionRequest(msgRef); + break; - case 419: - HandleSetWeaponSlotRequest(msgRef); - break; + case 307: + HandleInitItemTermRequest(msgRef); + break; - case 420: - HandleClearWeaponSlots(msgRef); - break; + case 324: + HandleBNDScoreRequest(msgRef); + break; - case 425: - HandleRequestDownloadedMaps(msgRef); - break; + case 325: + HandleLineBrickRequest(msgRef); + break; - case 447: - HandleOpenDoorRequest(msgRef); - break; + case 327: + HandleReplaceBrickRequest(msgRef); + break; - case 448: - HandleCloseDoorRequest(msgRef); - break; + case 329: + msgRef.msg._msg.Read(out long item); + msgRef.msg._msg.Read(out string code); + Debug.LogWarning("UseConsumable Item: " + item + " code: " + code); + break; - case 469: - HandleRoomRequest(msgRef); - break; + case 333: + HandleSetShooterToolRequest(msgRef); + break; - case 478: - HandleRequestUserList(msgRef); - break; + case 334: + HandleClearShooterTools(msgRef); + break; - case 551: - HandleGetTrainRequest(msgRef); - break; + case 337: + HandleRegMapInfoRequest(msgRef); + break; - case 553: - HandleEmptyTrainRequest(msgRef); - break; + case 345: + Debug.LogWarning("StackPointRequest"); + break; - case ExtensionOpcodes.opInventoryAck: - HandleInventoryCSV(msgRef); - break; + case 349: + HandleBNDShiftPhaseRequest(msgRef); + break; - case ExtensionOpcodes.opDisconnectReq: - HandleDisconnect(msgRef); - break; + case 366: + HandleFlagReturnRequest(msgRef); + break; - default: - if (debugHandle) - Debug.LogWarning("Received unhandled message ID " + msgRef.msg._id + " from: " + msgRef.client.GetIdentifier()); - break; - } - } + case 368: + HandleWeaponHeldRatioRequest(msgRef); + break; - catch (Exception ex) - { - Debug.LogError("HandleMessages: " + ex.Message); - } + case 389: + HandleDelegateMasterRequest(msgRef); + break; - finally - { - readQueue.Dequeue(); - } - } + case 399: + Debug.LogWarning("InflictedDamageRequest"); + break; - private void SendMessages() - { - if (writeQueue.Count < 1) - return; + case 414: + HandleWeaponChangeRequest(msgRef); + break; + + case 419: + HandleSetWeaponSlotRequest(msgRef); + break; + + case 420: + HandleClearWeaponSlots(msgRef); + break; + + case 425: + HandleRequestDownloadedMaps(msgRef); + break; + + case 427: + HandleRequestRegisteredMaps(msgRef); + break; + + case 429: + HandleRequestUserMaps(msgRef); + break; + + case 431: + Debug.LogWarning("AllMapRequest from: " + msgRef.client.GetIdentifier()); + break; + + case 447: + HandleOpenDoorRequest(msgRef); + break; + + case 448: + HandleCloseDoorRequest(msgRef); + break; + + case 460: + HandleCommonOpt(msgRef); + break; + + case 469: + HandleRoomRequest(msgRef); + break; + + case 471: + HandleChargeForcePoint(msgRef); + break; + + case 478: + HandleRequestUserList(msgRef); + break; + + case 538: + HandleZombieInfectionRequest(msgRef); + break; + + case 540: + HandleZombieInfectRequest(msgRef); + break; + + case 545: + HandleZombieScoreRequest(msgRef); + break; + + case 547: + HandleZombieStatusRequest(msgRef); + break; + + case 549: + HandleZombieObserverRequest(msgRef); + break; + + case 551: + HandleGetTrainRequest(msgRef); + break; + + case 553: + HandleEmptyTrainRequest(msgRef); + break; + + case ExtensionOpcodes.opInventoryAck: + HandleInventoryCSV(msgRef); + break; + + case ExtensionOpcodes.opDisconnectReq: + HandleDisconnect(msgRef); + break; + + case ExtensionOpcodes.opBeginChunkedBufferReq: + HandleBeginChunkedBuffer(msgRef); + break; + + case ExtensionOpcodes.opChunkedBufferReq: + HandleChunkedBuffer(msgRef); + break; + + case ExtensionOpcodes.opEndChunkedBufferReq: + HandleEndChunkedBuffer(msgRef); + break; + + default: + if (debugHandle) + Debug.LogWarning("Received unhandled message ID " + msgRef.msg._id + " from: " + msgRef.client.GetIdentifier()); + break; + } + } + + catch (Exception ex) + { + Debug.LogError("HandleMessages: " + ex.Message); + Debug.LogError("HandleMessages StackTrace: " + ex.StackTrace); + } + + finally + { + readQueue.Dequeue(); + } + } + + private void SendMessages() + { + if (writeQueue.Count < 1) + return; + + MsgReference msgRef = writeQueue.Peek(); + + try + { + switch (msgRef.sendType) + { + case SendType.Unicast: + UnicastMessage(msgRef); + break; + + case SendType.Broadcast: + BroadcastMessage(msgRef); + break; + + case SendType.BroadcastChannel: + BroadcastChannelMessage(msgRef); + break; + + case SendType.BroadcastRoom: + BroadcastRoomMessage(msgRef); + break; + + case SendType.BroadcastRoomExclusive: + BroadcastRoomMessageExclusive(msgRef); + break; + + case SendType.BroadcastRedTeam: + BroadcastRedTeamMessage(msgRef); + break; + + case SendType.BroadcastBlueTeam: + BroadcastBlueTeamMessage(msgRef); + break; + } + } + + catch (Exception ex) + { + Debug.LogError("SendMessages: " + ex.Message); + if (debugHandle) + Debug.LogError("SendMessages StackTrace: " + ex.StackTrace); + } + + finally + { + writeQueue.Dequeue(); + } + } + + private bool HandleClientAccepted(ClientReference client) + { + lock (dataLock) + { + if (!Config.instance.blockConnections && clientList.Count < Config.instance.maxConnections && !clientList.Exists(x => x.socket == client.socket) && (!Config.instance.oneClientPerIP || !clientList.Exists(x => x.ip == client.ip))) + { + clientList.Add(client); + SendConnected(client); + return true; + } + + else + { + Debug.Log("HandleClientAccepted: Blocked Client " + client.GetIdentifier() + " from Connecting"); + return false; + } + } + } + + private void HandleHeartbeat(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int gmFunction); + if (Time.time - msgRef.client.lastHeartBeatTime > 3f) + msgRef.client.Disconnect(); - MsgReference msgRef = writeQueue.Peek(); + else + msgRef.client.lastHeartBeatTime = Time.time; + } - try - { - switch (msgRef.sendType) - { - case SendType.Unicast: - UnicastMessage(msgRef); - break; - - case SendType.Broadcast: - BroadcastMessage(msgRef); - break; - - case SendType.BroadcastRoom: - BroadcastRoomMessage(msgRef); - break; - - case SendType.BroadcastRoomExclusive: - BroadcastRoomMessageExclusive(msgRef); - break; - - case SendType.BroadcastRedTeam: - BroadcastRedTeamMessage(msgRef); - break; - - case SendType.BroadcastBlueTeam: - BroadcastBlueTeamMessage(msgRef); - break; - } - } + private void HandleLoginRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out string id); + msgRef.msg._msg.Read(out string pswd); + msgRef.msg._msg.Read(out int major); + msgRef.msg._msg.Read(out int minor); + msgRef.msg._msg.Read(out string privateIpAddress); + msgRef.msg._msg.Read(out string macAddress); + + msgRef.client.name = id; + msgRef.client.seq = curSeq; + msgRef.client.port = 6000 + msgRef.client.seq; + curSeq++; + + ChannelReference channel = channelManager.GetDefaultChannel(); + channel.AddClient(msgRef.client); + + SendPlayerInitInfo(msgRef.client); + SendChannels(msgRef.client); + SendCurChannel(msgRef.client, channel.channel.Id); + SendInventoryRequest(msgRef.client); + SendLogin(msgRef.client, channel.channel.Id); + SendPlayerInfo(msgRef.client); + SendAllDownloadedMaps(msgRef.client); + SendEmptyUserMap(msgRef.client); + SendAllUserMaps(msgRef.client); + } + + private void HandleLoadComplete(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int crc); - catch (Exception ex) - { - Debug.LogError("SendMessages: " + ex.Message); - } + msgRef.client.isLoaded = true; - finally - { - writeQueue.Dequeue(); - } - } + if (debugHandle) + Debug.Log("HandleLoadComplete from: " + msgRef.client.GetIdentifier()); + } - private bool HandleClientAccepted(ClientReference client) - { - lock (dataLock) - { - if (!Config.instance.blockConnections && clientList.Count < Config.instance.maxConnections && !clientList.Exists(x => x.socket == client.socket) && (!Config.instance.oneClientPerIP || !clientList.Exists(x => x.ip == client.ip))) - { - clientList.Add(client); - SendConnected(client); - return true; - } - - else - { - Debug.Log("HandleClientAccepted: Blocked Client " + client.GetIdentifier() + " from Connecting"); - return false; - } - } - } - - private void HandleHeartbeat(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int gmFunction); - if (Time.time - msgRef.client.lastHeartBeatTime > 3f) - msgRef.client.Disconnect(); - - else - msgRef.client.lastHeartBeatTime = Time.time; - } - - private void HandleLoginRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out string id); - msgRef.msg._msg.Read(out string pswd); - msgRef.msg._msg.Read(out int major); - msgRef.msg._msg.Read(out int minor); - msgRef.msg._msg.Read(out string privateIpAddress); - msgRef.msg._msg.Read(out string macAddress); - - msgRef.client.name = id; - msgRef.client.seq = curSeq; - msgRef.client.port = 6000 + msgRef.client.seq; - curSeq++; - - SendPlayerInitInfo(msgRef.client); - SendChannels(msgRef.client, new Channel[] { defaultChannel }); - SendCurChannel(msgRef.client, defaultChannel.Id); - SendInventoryRequest(msgRef.client); - SendLogin(msgRef.client, defaultChannel.Id); - } - - private void HandleLoadComplete(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int crc); - - msgRef.client.isLoaded = true; - - if (debugHandle) - Debug.Log("HandleLoadComplete from: " + msgRef.client.GetIdentifier()); - } - - private void HandleTimer(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int remainTime); - msgRef.msg._msg.Read(out int playTime); - - if (msgRef.client.seq == matchData.masterSeq) - { - matchData.remainTime = remainTime; - matchData.playTime = playTime; - } + private void HandleTimer(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + msgRef.msg._msg.Read(out int remainTime); + msgRef.msg._msg.Read(out int playTime); + + if (msgRef.client.seq == matchData.masterSeq) + { + matchData.remainTime = remainTime; + matchData.playTime = playTime; + } + + if (debugPing) + Debug.Log("HandleTimer from: " + msgRef.client.GetIdentifier()); + if (matchData.room.type == Room.ROOM_TYPE.BND) + { + if (matchData.repeat <= 0) + { + matchData.EndMatch(); + } + } + else + { + if (matchData.remainTime <= 0) + matchData.EndMatch(); + } + + SendTimer(msgRef.client); + } + + private void HandleMatchCountdown(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - if (debugPing) - Debug.Log("HandleTimer from: " + msgRef.client.GetIdentifier()); + msgRef.msg._msg.Read(out int countdownTime); - if (matchData.remainTime <= 0) - matchData.EndMatch(); + if (debugHandle) + Debug.Log("HandleMatchCountdown from: " + msgRef.client.GetIdentifier()); - SendTimer(msgRef.client); - } + if (msgRef.client.seq == matchData.masterSeq) + { + matchData.countdownTime = countdownTime; + if (matchData.countdownTime <= 0) + { + matchData.room.Status = Room.ROOM_STATUS.PLAYING; + SendRoom(null, matchData, SendType.BroadcastRoom); + } - private void HandleMatchCountdown(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int countdownTime); + SendMatchCountdown(matchData); + } + } - if (debugHandle) - Debug.Log("HandleMatchCountdown from: " + msgRef.client.GetIdentifier()); + private void HandleRoamout(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int dest); - if (msgRef.client.seq == matchData.masterSeq) - { - matchData.countdownTime = countdownTime; - if (matchData.countdownTime <= 0) - { - matchData.room.Status = Room.ROOM_STATUS.PLAYING; - SendRoom(null, SendType.BroadcastRoom); - } - - SendMatchCountdown(); - } - } - - private void HandleRoamin(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int seq); - msgRef.msg._msg.Read(out int userType); - msgRef.msg._msg.Read(out bool isWebPlayer); - msgRef.msg._msg.Read(out int language); - msgRef.msg._msg.Read(out string hashCode); - - if (debugHandle) - Debug.Log("HandleRoamin from: " + msgRef.client.GetIdentifier()); - - SendPlayerInfo(msgRef.client); - SendUserList(msgRef.client); - SendDownloadedMaps(msgRef.client); - SendRoamin(msgRef.client); - - msgRef.client.clientStatus = ClientReference.ClientStatus.Lobby; - } - - private void HandleRequestDownloadedMaps(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int prevPage); - msgRef.msg._msg.Read(out int nextPage); - msgRef.msg._msg.Read(out int indexer); - msgRef.msg._msg.Read(out ushort modeMask); - - if (debugHandle) - Debug.Log("HandleRequestDownloadedMaps from: " + msgRef.client.GetIdentifier()); - - SendDownloadedMaps(msgRef.client); - } - - private void HandleRequestUserList(MsgReference msgRef) - { - if (debugPing) - Debug.Log("HandleRequestUserList from: " + msgRef.client.GetIdentifier()); - - SendUserList(msgRef.client); - } - - private void HandleJoinRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int roomNumber); - msgRef.msg._msg.Read(out string pswd); - msgRef.msg._msg.Read(out bool invite); - - if (debugHandle) - Debug.Log("HandleJoin from: " + msgRef.client.GetIdentifier()); - - if (roomNumber == matchData.room.No) - { - matchData.AddClient(msgRef.client); - - SendJoin(msgRef.client); - SendRendezvousInfo(msgRef.client); - SendMaster(msgRef.client); - SendSlotLocks(msgRef.client); - SendRoomConfig(msgRef.client); - SendAddRoom(msgRef.client); - SendEnter(msgRef.client); - SendSlotData(); - } - } + if (debugHandle) + Debug.Log("HandleRoamout from: " + msgRef.client.GetIdentifier()); - private void HandleBreakIntoRequest(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleBreakInto from: " + msgRef.client.GetIdentifier()); + ChannelReference channelRef = channelManager.GetChannelByID(dest); + if (channelRef != null) + { + SendCurChannel(msgRef.client, channelRef.channel.Id); + channelRef.AddClient(msgRef.client); + SendUserList(msgRef.client); + SendRoamin(msgRef.client, channelRef.channel.Id); + } - int reply = 0; + msgRef.client.clientStatus = ClientReference.ClientStatus.Lobby; + } - if (!matchData.room.isBreakInto) - reply = -1; + private void HandleRoamin(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); + msgRef.msg._msg.Read(out int userType); + msgRef.msg._msg.Read(out bool isWebPlayer); + msgRef.msg._msg.Read(out int language); + msgRef.msg._msg.Read(out string hashCode); - else if (matchData.room.Status != Room.ROOM_STATUS.PLAYING) - reply = -2; + if (debugHandle) + Debug.Log("HandleRoamin from: " + msgRef.client.GetIdentifier()); - else - { - msgRef.client.status = BrickManDesc.STATUS.PLAYER_LOADING; - msgRef.client.clientStatus = ClientReference.ClientStatus.Match; - SendSetStatus(msgRef.client); - SendTeamScore(); - for (int i = 0; i < matchData.clientList.Count; i++) - { - SendKillCount(matchData.clientList[i]); - SendDeathCount(matchData.clientList[i]); - } - msgRef.client.isBreakingInto = true; - } + SendUserList(msgRef.client); + SendRoamin(msgRef.client, msgRef.client.channel.channel.Id); - SendBreakInto(msgRef.client, reply); - } + msgRef.client.clientStatus = ClientReference.ClientStatus.Lobby; + } - private void HandleLeave(MsgReference msgRef) - { - matchData.RemoveClient(msgRef.client); + private void HandleRequestDownloadedMaps(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int prevPage); + msgRef.msg._msg.Read(out int nextPage); + msgRef.msg._msg.Read(out int indexer); + msgRef.msg._msg.Read(out ushort modeMask); - if (debugHandle) - Debug.Log("HandleLeave from: " + msgRef.client.GetIdentifier()); + if (debugHandle) + Debug.Log("HandleRequestDownloadedMaps from: " + msgRef.client.GetIdentifier()); - SendLeave(msgRef.client); - SendSetStatus(msgRef.client); + SendDownloadedMaps(msgRef.client, nextPage); + } - if (matchData.room.CurPlayer <= 0) - { - SendDeleteRoom(); - matchData = new MatchData(); - return; - } + private void HandleRequestRegisteredMaps(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int prevPage); + msgRef.msg._msg.Read(out int nextPage); + msgRef.msg._msg.Read(out int indexer); + msgRef.msg._msg.Read(out ushort modeMask); - if (msgRef.client.seq == matchData.masterSeq) - { - matchData.masterSeq = matchData.clientList[0].seq; - SendMaster(null); - } - } + if (debugHandle) + Debug.Log("HandleRequestRegisteredMaps from: " + msgRef.client.GetIdentifier()); - private void HandleCreateRoomRequest(MsgReference msgRef) - { - if (matchData.roomCreated) - { - SendCreateRoom(msgRef.client, false); - return; - } + SendRegisteredMaps(msgRef.client, nextPage); + } - msgRef.msg._msg.Read(out int type); - msgRef.msg._msg.Read(out string title); - msgRef.msg._msg.Read(out bool isLocked); - msgRef.msg._msg.Read(out string pswd); - msgRef.msg._msg.Read(out int maxPlayer); - msgRef.msg._msg.Read(out int goal); - msgRef.msg._msg.Read(out int timelimit); - msgRef.msg._msg.Read(out int weaponOption); - msgRef.msg._msg.Read(out int map); - msgRef.msg._msg.Read(out int breakinto); - msgRef.msg._msg.Read(out int autobalance); - msgRef.msg._msg.Read(out int wanted); - msgRef.msg._msg.Read(out int drop); - msgRef.msg._msg.Read(out string alias); - msgRef.msg._msg.Read(out int master); - - matchData.room.Type = (Room.ROOM_TYPE)type; - matchData.room.Title = title; - matchData.room.Locked = isLocked; - matchData.room.MaxPlayer = maxPlayer; - matchData.room.goal = goal; - matchData.room.timelimit = timelimit; - matchData.room.weaponOption = weaponOption; - matchData.room.map = map; - matchData.room.isBreakInto = Convert.ToBoolean(breakinto); - matchData.room.isWanted = Convert.ToBoolean(wanted); - matchData.room.isDropItem = false;//Convert.ToBoolean(drop); - matchData.isBalance = Convert.ToBoolean(autobalance); - matchData.room.CurMapAlias = alias; - matchData.masterSeq = msgRef.client.seq; - matchData.LockSlotsByMaxPlayers(matchData.room.MaxPlayer); - matchData.roomCreated = true; - - if (debugHandle) - Debug.Log("HandleCreateRoom from: " + msgRef.client.GetIdentifier()); - - matchData.AddClient(msgRef.client); - SendRendezvousInfo(msgRef.client); - SendMaster(msgRef.client); - SendSlotLocks(msgRef.client); - SendRoomConfig(msgRef.client); - SendAddRoom(msgRef.client); - SendCreateRoom(msgRef.client); - SendEnter(msgRef.client); - SendSlotData(); - } - - private void HandleRoomConfig(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int killCount); - msgRef.msg._msg.Read(out int timeLimit); - msgRef.msg._msg.Read(out int weaponOption); - msgRef.msg._msg.Read(out int nWhere); - msgRef.msg._msg.Read(out int breakInto); - msgRef.msg._msg.Read(out int teamBalance); - msgRef.msg._msg.Read(out int useBuildGun); - msgRef.msg._msg.Read(out int itemPickup); - msgRef.msg._msg.Read(out string whereAlias); - msgRef.msg._msg.Read(out string pswd); - msgRef.msg._msg.Read(out int type); - - matchData.room.goal = killCount; - matchData.room.timelimit = timeLimit; - matchData.room.weaponOption = weaponOption; - matchData.room.map = nWhere; - matchData.room.isBreakInto = Convert.ToBoolean(breakInto); - matchData.isBalance = Convert.ToBoolean(teamBalance); - matchData.room.isDropItem = false;//Convert.ToBoolean(itemPickup); - matchData.room.CurMapAlias = whereAlias; - matchData.room.Type = (Room.ROOM_TYPE)type; - - if (debugHandle) - Debug.Log("HandleRoomConfig from: " + msgRef.client.GetIdentifier()); - - SendRoomConfig(null); - } - - private void HandleRoomRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int roomNumber); - - if (debugHandle) - Debug.Log("HandleRoomRequest from: " + msgRef.client.GetIdentifier()); - - if (roomNumber == matchData.room.No) - SendRoom(msgRef.client); - } - - private void HandleRoomListRequest(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleRoomListRequest from: " + msgRef.client.GetIdentifier()); - - SendRoomList(msgRef.client); - } - - private void HandleResumeRoomRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int nextStatus); - - if (msgRef.client.seq == matchData.masterSeq) - { - matchData.room.Status = (Room.ROOM_STATUS)nextStatus; - } + private void HandleRequestUserMaps(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int page); - if (debugHandle) - Debug.Log("HandleResumeRoomRequest from: " + msgRef.client.GetIdentifier()); + if (debugHandle) + Debug.Log("HandleRequestUserMaps from: " + msgRef.client.GetIdentifier()); - SendRoom(null, SendType.BroadcastRoom); - } + SendUserMaps(msgRef.client, page); + } - private void HandleTeamChangeRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out bool clickSlot); - msgRef.msg._msg.Read(out int slotNum); + private void HandleRequestUserList(MsgReference msgRef) + { + if (debugPing) + Debug.Log("HandleRequestUserList from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleTeamChangeRequest from: " + msgRef.client.GetIdentifier()); + SendUserList(msgRef.client); + } - if (slotNum < -1 && slotNum > 15) - Debug.LogWarning("HandleTeamChangeRequest: Bad slot num " + slotNum + " from client: " + msgRef.client.GetIdentifier()); + private void HandleJoinRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int roomNumber); + msgRef.msg._msg.Read(out string pswd); + msgRef.msg._msg.Read(out bool invite); + + if (debugHandle) + Debug.Log("HandleJoin from: " + msgRef.client.GetIdentifier()); + + MatchData matchData = msgRef.client.channel.GetMatchByRoomNumber(roomNumber); + if (roomNumber == matchData.room.No) + { + matchData.AddClient(msgRef.client); + + SendJoin(msgRef.client); + SendRendezvousInfo(msgRef.client); + SendMaster(msgRef.client, matchData); + SendSlotLocks(msgRef.client); + SendRoomConfig(msgRef.client, matchData); + SendAddRoom(msgRef.client, matchData); + SendEnter(msgRef.client); + SendSlotData(matchData); + + if (matchData.room.Type == Room.ROOM_TYPE.MAP_EDITOR) + SendCopyright(msgRef.client); + } + } + + private void HandleBreakIntoRequest(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleBreakInto from: " + msgRef.client.GetIdentifier()); - else if (slotNum == -1) - { - msgRef.client.AssignSlot(matchData.GetNextFreeSlotOnOtherTeam(msgRef.client.slot)); - } + MatchData matchData = msgRef.matchData; - else - msgRef.client.AssignSlot(matchData.slots[slotNum]); + int reply = 0; - SendTeamChange(msgRef.client); - } + if (!matchData.room.isBreakInto) + reply = -1; - private void HandleSlotLockRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out sbyte slotNum); - msgRef.msg._msg.Read(out sbyte lck); + else if (matchData.room.Status != Room.ROOM_STATUS.PLAYING) + reply = -2; - if (debugHandle) - Debug.Log("HandleSlotLockRequest from: " + msgRef.client.GetIdentifier()); + else + { + msgRef.client.status = BrickManDesc.STATUS.PLAYER_LOADING; + msgRef.client.clientStatus = ClientReference.ClientStatus.Match; + SendSetStatus(msgRef.client); + SendTeamScore(matchData); + for (int i = 0; i < matchData.clientList.Count; i++) + { + SendKillCount(matchData.clientList[i]); + SendDeathCount(matchData.clientList[i]); + } + msgRef.client.isBreakingInto = true; + } - if (slotNum < 0 && slotNum > 15) - Debug.LogWarning("HandleSlotLockRequest: Bad slot num " + slotNum + " from client: " + msgRef.client.GetIdentifier()); + SendBreakInto(msgRef.client, reply); + } - else if (msgRef.client.seq == matchData.masterSeq) - { - matchData.slots[slotNum].ToggleLock(Convert.ToBoolean(lck)); - matchData.room.MaxPlayer = matchData.slots.FindAll(x => !x.isLocked).Count; + private void HandleLeave(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - SendSlotLock(msgRef.client, slotNum, SendType.BroadcastRoom); - } + if (debugHandle) + Debug.Log("HandleLeave from: " + msgRef.client.GetIdentifier()); - } + SendLeave(msgRef.client); + SendSetStatus(msgRef.client); - private void HandleSetStatusRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int status); + matchData.RemoveClient(msgRef.client); - msgRef.client.status = (BrickManDesc.STATUS)status; + if (matchData.room.CurPlayer <= 0) + { + SendDeleteRoom(matchData, matchData.channel); + msgRef.client.channel.RemoveMatch(matchData); + //matchData = new MatchData(); + return; + } - if (debugHandle) - Debug.Log("HandleSetStatusRequest from: " + msgRef.client.GetIdentifier()); + if (msgRef.client.seq == matchData.masterSeq) + { + matchData.masterSeq = matchData.clientList[0].seq; + SendMaster(null, matchData); + } + } - SendSetStatus(msgRef.client); - } + private void HandleCreateRoomRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int type); + msgRef.msg._msg.Read(out string title); + msgRef.msg._msg.Read(out bool isLocked); + msgRef.msg._msg.Read(out string pswd); + msgRef.msg._msg.Read(out int maxPlayer); + msgRef.msg._msg.Read(out int param1); //Play: goal Build: isLoad + msgRef.msg._msg.Read(out int param2); //Play: timeLimit Build: slot + msgRef.msg._msg.Read(out int param3); //Play: weaponOption Build: brickCount:landscapeIndex + msgRef.msg._msg.Read(out int param4); //Play: map Build: map:skyboxIndex + msgRef.msg._msg.Read(out int param5); //Play: breakInto Build: premium + msgRef.msg._msg.Read(out int param6); //Play: isBalance Build: N/A + msgRef.msg._msg.Read(out int param7); //Play: isWanted Build: N/A + msgRef.msg._msg.Read(out int param8); //Play: isDrop Build: N/A + msgRef.msg._msg.Read(out string alias); + msgRef.msg._msg.Read(out int master); + + MatchData matchData = msgRef.client.channel.AddNewMatch(); + + matchData.room.Type = (Room.ROOM_TYPE)type; + matchData.room.Title = title; + matchData.room.Locked = isLocked; + matchData.room.MaxPlayer = maxPlayer; + matchData.room.CurMapAlias = alias; + matchData.masterSeq = msgRef.client.seq; + matchData.LockSlotsByMaxPlayers(matchData.room.MaxPlayer); + matchData.roomCreated = true; + + if ((Room.ROOM_TYPE)type == Room.ROOM_TYPE.MAP_EDITOR) + { + //UserMapInfoManager.Instance.AddOrUpdate(param2, alias, param3, DateTime.Now, (sbyte)param5); + //UserMapInfoManager.Instance.CurSlot = param2; + //UserMapInfoManager.Instance.CurMapName = alias; + if (param1 == 1) + { + //matchData.CacheMap(regMaps.Find(x => x.Value.Map == param2).Value, new UserMapInfo(param2, (sbyte)param5)); + matchData.CacheMap(regMaps.Find(x => x.Value.Map == param2).Value, UserMapInfoManager.Instance.Get(param2)); + } + else + { + matchData.CacheMapGenerate(param3, param4, alias); + } + } + + else + { + matchData.room.goal = param1; + matchData.room.timelimit = param2; + matchData.room.weaponOption = param3; + matchData.room.map = param4; + matchData.room.isBreakInto = Convert.ToBoolean(param5); + matchData.room.isWanted = Convert.ToBoolean(param7); + matchData.room.isDropItem = false;//Convert.ToBoolean(param8); + matchData.isBalance = Convert.ToBoolean(param6); + } + + if ((Room.ROOM_TYPE)type == Room.ROOM_TYPE.BND) + { + // Unpack the timer configuration for Build and Destroy phases + int buildTime, destroyTime, repeat; + UnpackTimerOption(param2, out buildTime, out destroyTime, out repeat); + + matchData.buildPhaseTime = buildTime; + matchData.battlePhaseTime = destroyTime; + matchData.repeat = repeat; + + // Initialize BND-specific fields + /*matchData.currentPhase = MatchData.BnDPhase.Build; + matchData.currentRound = 1; + matchData.remainTime = buildTime; // Start with Build phase time*/ + } + + if (debugHandle) + Debug.Log("HandleCreateRoom from: " + msgRef.client.GetIdentifier()); + + matchData.AddClient(msgRef.client); + SendRendezvousInfo(msgRef.client); + SendMaster(msgRef.client, matchData); + SendSlotLocks(msgRef.client); + SendRoomConfig(msgRef.client, matchData); + SendAddRoom(msgRef.client, matchData); + SendCreateRoom(msgRef.client); + SendEnter(msgRef.client); + SendSlotData(matchData); + + if ((Room.ROOM_TYPE)type == Room.ROOM_TYPE.MAP_EDITOR) + SendCopyright(msgRef.client); + } + + private void HandleRoomConfig(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + msgRef.msg._msg.Read(out int killCount); + msgRef.msg._msg.Read(out int timeLimit); + msgRef.msg._msg.Read(out int weaponOption); + msgRef.msg._msg.Read(out int nWhere); + msgRef.msg._msg.Read(out int breakInto); + msgRef.msg._msg.Read(out int teamBalance); + msgRef.msg._msg.Read(out int useBuildGun); + msgRef.msg._msg.Read(out int itemPickup); + msgRef.msg._msg.Read(out string whereAlias); + msgRef.msg._msg.Read(out string pswd); + msgRef.msg._msg.Read(out int type); + + matchData.room.goal = killCount; + matchData.room.timelimit = timeLimit; + matchData.room.weaponOption = weaponOption; + matchData.room.map = nWhere; + matchData.room.isBreakInto = Convert.ToBoolean(breakInto); + matchData.isBalance = Convert.ToBoolean(teamBalance); + matchData.room.isDropItem = false;//Convert.ToBoolean(itemPickup); + matchData.room.CurMapAlias = whereAlias; + matchData.room.Type = (Room.ROOM_TYPE)type; + + if (debugHandle) + Debug.Log("HandleRoomConfig from: " + msgRef.client.GetIdentifier()); + + SendRoomConfig(null, matchData); + } + + private void HandleRoomRequest(MsgReference msgRef) + { - private void HandleStartRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int remainingCountdown); + msgRef.msg._msg.Read(out int roomNumber); - matchData.lobbyCountdownTime = 0; + if (debugHandle) + Debug.Log("HandleRoomRequest from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleStartRequest from: " + msgRef.client.GetIdentifier()); + MatchData matchData = msgRef.client.channel.GetMatchByRoomNumber(roomNumber); + SendRoom(msgRef.client, matchData); + } - if (matchData.clientList.Find(x => x.status == BrickManDesc.STATUS.PLAYER_WAITING && x.seq != matchData.masterSeq) != null) - { - Debug.LogWarning("HandleStartRequest: Not All Ready"); - return; - } + private void HandleRoomListRequest(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleRoomListRequest from: " + msgRef.client.GetIdentifier()); - matchData.room.Status = Room.ROOM_STATUS.PENDING; - SendRoom(null, SendType.BroadcastRoom); + SendRoomList(msgRef.client); + } - for (int i = 0; i < matchData.clientList.Count; i++) - { - matchData.clientList[i].status = BrickManDesc.STATUS.PLAYER_LOADING; - matchData.clientList[i].clientStatus = ClientReference.ClientStatus.Match; - SendSetStatus(matchData.clientList[i]); - SendRespawnTicket(matchData.clientList[i]); - } + private void HandleResumeRoomRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - SendStart(); - } + msgRef.msg._msg.Read(out int nextStatus); - private void HandleWeaponHeldRatioRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int count); - for (int i = 0; i < count; i++) - { - msgRef.msg._msg.Read(out long key); - msgRef.msg._msg.Read(out float value); - } + if (msgRef.client.seq == matchData.masterSeq) + { + matchData.room.Status = (Room.ROOM_STATUS)nextStatus; + } - if (debugHandle) - Debug.Log("HandleWeaponHeldRatioRequest from: " + msgRef.client.GetIdentifier()); + if (debugHandle) + Debug.Log("HandleResumeRoomRequest from: " + msgRef.client.GetIdentifier()); - if (msgRef.client.status == BrickManDesc.STATUS.PLAYER_LOADING) - { - msgRef.client.status = BrickManDesc.STATUS.PLAYER_PLAYING; - SendSetStatus(msgRef.client); - SendPostLoadInit(msgRef.client); - } + SendRoom(null, matchData, SendType.BroadcastRoom); + } - if (msgRef.client.isBreakingInto) - { - msgRef.client.isBreakingInto = false; + private void HandleTeamChangeRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - for (int i = 0; i < matchData.destroyedBricks.Count; i++) - SendDestroyedBrick(msgRef.client, matchData.destroyedBricks[i]); + msgRef.msg._msg.Read(out bool clickSlot); + msgRef.msg._msg.Read(out int slotNum); - SendCannons(msgRef.client); - SendTrains(msgRef.client); - } - } + if (debugHandle) + Debug.Log("HandleTeamChangeRequest from: " + msgRef.client.GetIdentifier()); - private void HandleP2PComplete(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleP2PComplete from: " + msgRef.client.GetIdentifier()); + if (slotNum < -1 && slotNum > 15) + Debug.LogWarning("HandleTeamChangeRequest: Bad slot num " + slotNum + " from client: " + msgRef.client.GetIdentifier()); - if (msgRef.client.status == BrickManDesc.STATUS.PLAYER_P2PING) - { - msgRef.client.status = BrickManDesc.STATUS.PLAYER_PLAYING; - SendSetStatus(msgRef.client); - } - } + else if (slotNum == -1) + { + msgRef.client.AssignSlot(matchData.GetNextFreeSlotOnOtherTeam(msgRef.client.slot)); + } - private void HandleKillLogRequest(MsgReference msgRef) - { - if (killLogTimer < 0.2f) - return; + else + msgRef.client.AssignSlot(matchData.slots[slotNum]); - msgRef.msg._msg.Read(out int id); + SendTeamChange(msgRef.client); + } - if (matchData.killLog.Find(x => x.id == id) != null) - return; + private void HandleSlotLockRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - if (id != matchData.lastKillLogId) - matchData.lastKillLogId = id; - else - return; + msgRef.msg._msg.Read(out sbyte slotNum); + msgRef.msg._msg.Read(out sbyte lck); - killLogTimer = 0f; + if (debugHandle) + Debug.Log("HandleSlotLockRequest from: " + msgRef.client.GetIdentifier()); - msgRef.msg._msg.Read(out sbyte killerType); - msgRef.msg._msg.Read(out int killer); - msgRef.msg._msg.Read(out sbyte victimType); - msgRef.msg._msg.Read(out int victim); - msgRef.msg._msg.Read(out int weaponBy); - msgRef.msg._msg.Read(out int slot); - msgRef.msg._msg.Read(out int category); - msgRef.msg._msg.Read(out int hitpart); - msgRef.msg._msg.Read(out int damageLogCount); + if (slotNum < 0 && slotNum > 15) + Debug.LogWarning("HandleSlotLockRequest: Bad slot num " + slotNum + " from client: " + msgRef.client.GetIdentifier()); - Dictionary damageLog = new Dictionary(); - for (int i = 0; i < damageLogCount; i++) - { - msgRef.msg._msg.Read(out int key); - msgRef.msg._msg.Read(out int value); - - if (key == victim) - continue; - if (!damageLog.ContainsKey(key)) - damageLog.Add(key, value); - else - damageLog[key] += value; - } + else if (msgRef.client.seq == matchData.masterSeq) + { + matchData.slots[slotNum].ToggleLock(Convert.ToBoolean(lck)); + matchData.room.MaxPlayer = matchData.slots.FindAll(x => !x.isLocked).Count; - if (debugHandle) - Debug.Log("HandleKillLogRequest from: " + msgRef.client.GetIdentifier()); + SendSlotLock(msgRef.client, matchData, slotNum, SendType.BroadcastRoom); + } - ClientReference victimClient = matchData.clientList.Find(x => x.seq == victim); - victimClient.deaths++; - SendDeathCount(victimClient); + } - if (killer == victim) - killer = damageLog.OrderByDescending(x => x.Value).FirstOrDefault().Key; + private void HandleSetStatusRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int status); - ClientReference killerClient = matchData.clientList.Find(x => x.seq == killer); - if (killer != victim) - { - killerClient.kills++; - SendKillCount(killerClient); - } + msgRef.client.status = (BrickManDesc.STATUS)status; - foreach (KeyValuePair entry in damageLog) - { - if (entry.Key != victim) - { - if (entry.Key != killer) - { - ClientReference assistClient = matchData.clientList.Find(x => x.seq == entry.Key); - assistClient.assists++; - assistClient.score += entry.Value; - SendAssistCount(assistClient); - } - - else - { - killerClient.score += entry.Value; - SendRoundScore(killerClient); - } - - } - } + if (debugHandle) + Debug.Log("HandleSetStatusRequest from: " + msgRef.client.GetIdentifier()); - KillLogEntry killLogEntry = new KillLogEntry(id, killerType, killer, victimType, victim, (Weapon.BY)weaponBy, slot, category, hitpart, damageLog); - matchData.killLog.Add(killLogEntry); - SendKillLogEntry(killLogEntry); + SendSetStatus(msgRef.client); + } - if (killer != victim) - { - switch (matchData.room.Type) - { - case Room.ROOM_TYPE.TEAM_MATCH: - if (victimClient.slot.slotIndex > 7) - matchData.redScore++; - else - matchData.blueScore++; - SendTeamScore(); - if (matchData.blueScore >= matchData.room.goal || matchData.redScore >= matchData.room.goal) - { - HandleTeamMatchEnd(); - } - break; - - case Room.ROOM_TYPE.INDIVIDUAL: - matchData.redScore++; - SendIndividualScore(); - - if (matchData.redScore >= matchData.room.goal) - { - HandleIndividualMatchEnd(); - } - break; - } - } - } + private void HandleStartRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - private void HandleTeamScoreRequest(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleTeamScoreRequest from: " + msgRef.client.GetIdentifier()); + msgRef.msg._msg.Read(out int remainingCountdown); - SendTeamScore(); - } + matchData.lobbyCountdownTime = 0; - private void HandleDestroyBrickRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int brick); + if (debugHandle) + Debug.Log("HandleStartRequest from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleDestroyBrickRequest from: " + msgRef.client.GetIdentifier()); + if (matchData.clientList.Find(x => x.status == BrickManDesc.STATUS.PLAYER_WAITING && x.seq != matchData.masterSeq) != null) + { + Debug.LogWarning("HandleStartRequest: Not All Ready"); + return; + } - if (!(matchData.destroyedBricks.Exists(x => x == brick))) - { - matchData.destroyedBricks.Add(brick); - SendDestroyBrick(brick); - } - } + matchData.room.Status = Room.ROOM_STATUS.PENDING; + SendRoom(null, matchData, SendType.BroadcastRoom); - private void HandleRegMapInfoRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int mapId); + for (int i = 0; i < matchData.clientList.Count; i++) + { + matchData.clientList[i].status = BrickManDesc.STATUS.PLAYER_LOADING; + matchData.clientList[i].clientStatus = ClientReference.ClientStatus.Match; + SendSetStatus(matchData.clientList[i]); + SendRespawnTicket(matchData.clientList[i]); + } - if (debugHandle) - Debug.Log("HandleRegMapInfoRequest from: " + msgRef.client.GetIdentifier()); - } + SendStart(matchData); + } - private void HandleInventoryCSV(MsgReference msgRef) - { - List rows = new List(); + private void HandleWeaponHeldRatioRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + msgRef.msg._msg.Read(out int count); + for (int i = 0; i < count; i++) + { + msgRef.msg._msg.Read(out long key); + msgRef.msg._msg.Read(out float value); + } + + if (debugHandle) + Debug.Log("HandleWeaponHeldRatioRequest from: " + msgRef.client.GetIdentifier()); + + if (msgRef.client.status <= BrickManDesc.STATUS.PLAYER_LOADING) + { + msgRef.client.status = BrickManDesc.STATUS.PLAYER_PLAYING; + SendSetStatus(msgRef.client); + SendPostLoadInit(msgRef.client); + } + + if (msgRef.client.isBreakingInto) + { + msgRef.client.isBreakingInto = false; + + for (int i = 0; i < matchData.destroyedBricks.Count; i++) + SendDestroyedBrick(msgRef.client, matchData.destroyedBricks[i], matchData); + + SendCannons(msgRef.client); + SendTrains(msgRef.client); + } + } + + private void HandleP2PComplete(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleP2PComplete from: " + msgRef.client.GetIdentifier()); - msgRef.msg._msg.Read(out int rowCount); - for (int row = 0; row < rowCount; row++) - { - msgRef.msg._msg.Read(out int colCount); - string[] rowData = new string[colCount]; - for (int col = 0; col < colCount; col++) - { - msgRef.msg._msg.Read(out string entry); - rowData[col] = entry; - } - rows.Add(rowData); - } + if (msgRef.client.status == BrickManDesc.STATUS.PLAYER_P2PING) + { + msgRef.client.status = BrickManDesc.STATUS.PLAYER_PLAYING; + SendSetStatus(msgRef.client); + } + } - msgRef.client.inventory = new Inventory(msgRef.client.seq, new CSVLoader(rows)); + private void HandleInitItemTermRequest(MsgReference msgRef) + { - if (debugHandle) - Debug.Log("HandleInventoryCSV from: " + msgRef.client.GetIdentifier()); + MsgBody msgBody = msgRef.msg._msg; + msgBody.Read(out long item); + msgBody.Read(out int code); - SendInventory(msgRef.client); - } + //TODO: activate Item - private void HandleEquipRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out long itemSeq); + MsgBody body = new MsgBody(); + body.Write(0); // 0 = sucess !0 == fail + body.Write(item); - if (debugHandle) - Debug.Log("HandleEquipRequest from: " + msgRef.client.GetIdentifier()); + Say(new MsgReference(308, body, msgRef.client, SendType.Unicast)); + } - Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); - if (item != null) - { - if (!item.IsEquipable) - return; - - int index = Inventory.SlotToIndex(item.Template.slot); - if (index != -1 && index < msgRef.client.inventory.activeSlots.Length) - { - Item oldItem = msgRef.client.inventory.activeSlots[index]; - if (oldItem != null) - { - oldItem.Usage = Item.USAGE.UNEQUIP; - msgRef.client.inventory.activeSlots[index] = null; - SendUnequip(msgRef.client, oldItem.Seq, oldItem.Code); - } - } - item.Usage = Item.USAGE.EQUIP; - msgRef.client.inventory.GenerateActiveSlots(); - - SendEquip(msgRef.client, item.Seq, item.Code); - } - } + private void HandleBuyRequest(MsgReference msgRef) + { + //BuyHow See Good.BUY_HOW + //Option = duration (days) + //needEquip = Direct Equip + //val = False afaik + MsgBody msgBody = msgRef.msg._msg; + msgBody.Read(out string code); + msgBody.Read(out int buyHow); + msgBody.Read(out int option); + msgBody.Read(out byte val); + //TODO needEquip + msgBody.Read(out bool needEqup); + //seq is error code or unique id + //Read(out long val); seq + //msgRef.Read(out string val2); code + //msgRef.Read(out int val3); remain + int remain = option * 86400; + //negative = permanent + if (option > 30) remain = -1; + sbyte premium = 0; // isPremium 0 || 1 + int durability = int.MaxValue; //Durability int.MaxValue = Permanent + MsgBody body = new MsgBody(); + + TItem template = TItemManager.Instance.dic.FirstOrDefault(x => x.Value.code == code).Value; + + int seqSeed = msgRef.client.seq + 1; + byte[] baseSeq = new byte[8]; + byte[] seed = System.Text.Encoding.UTF8.GetBytes(template.name); + byte[] codeSeed = System.Text.Encoding.UTF8.GetBytes(template.code); + for (int i = 0; i < seed.Length && i < 5; i++) + baseSeq[i] = (byte)(seed[i] ^ seed[seed.Length - 1 - i]); + + for (int i = 0; i < 3; i++) + baseSeq[i] ^= codeSeed[i]; + + long itemSeq = BitConverter.ToInt64(baseSeq, 0) * seqSeed; + + Good good = ShopManager.Instance.dic.FirstOrDefault(x => x.Value.code == code).Value; + int price = good.GetPriceByOpt(option, (Good.BUY_HOW)buyHow); + switch ((Good.BUY_HOW)buyHow) + { + case Good.BUY_HOW.BRICK_POINT: + break; + case Good.BUY_HOW.CASH_POINT: + if (msgRef.client.data.tokens >= price) + { + int tokens = msgRef.client.data.tokens = msgRef.client.data.tokens - price; + MsgBody bodyUpdate = new MsgBody(); + bodyUpdate.Write(msgRef.client.data.forcePoints); + bodyUpdate.Write(msgRef.client.data.brickPoints); + bodyUpdate.Write(tokens); + bodyUpdate.Write(msgRef.client.data.coins); + bodyUpdate.Write(msgRef.client.data.starDust); + Say(new MsgReference(102, bodyUpdate, msgRef.client, SendType.Unicast)); + } + else + { + itemSeq = -3; + } + break; + case Good.BUY_HOW.GENERAL_POINT: + if (msgRef.client.data.forcePoints >= price) + { + int point = msgRef.client.data.forcePoints = msgRef.client.data.forcePoints - price; + MsgBody bodyUpdate = new MsgBody(); + bodyUpdate.Write(point); + bodyUpdate.Write(msgRef.client.data.brickPoints); + bodyUpdate.Write(msgRef.client.data.tokens); + bodyUpdate.Write(msgRef.client.data.coins); + bodyUpdate.Write(msgRef.client.data.starDust); + Say(new MsgReference(102, bodyUpdate, msgRef.client, SendType.Unicast)); + } + else + { + itemSeq = -3; + } + break; + default: + break; + } + + msgRef.client.inventory.AddItem(template); + body.Write(itemSeq); + body.Write(code); + body.Write(remain); + body.Write(premium); + body.Write(durability); + Say(new MsgReference(122, body, msgRef.client, SendType.Unicast)); + } + + private void HandleKillLogRequest(MsgReference msgRef) + { + if (killLogTimer < 0.2f) + return; + + MatchData matchData = msgRef.matchData; + + msgRef.msg._msg.Read(out int id); + + if (matchData.killLog.Find(x => x.id == id) != null) + return; + + if (id != matchData.lastKillLogId) + matchData.lastKillLogId = id; + else + return; + + killLogTimer = 0f; + + msgRef.msg._msg.Read(out sbyte killerType); + msgRef.msg._msg.Read(out int killer); + msgRef.msg._msg.Read(out sbyte victimType); + msgRef.msg._msg.Read(out int victim); + msgRef.msg._msg.Read(out int weaponBy); + msgRef.msg._msg.Read(out int slot); + msgRef.msg._msg.Read(out int category); + msgRef.msg._msg.Read(out int hitpart); + msgRef.msg._msg.Read(out int damageLogCount); + + Dictionary damageLog = new Dictionary(); + for (int i = 0; i < damageLogCount; i++) + { + msgRef.msg._msg.Read(out int key); + msgRef.msg._msg.Read(out int value); + + if (key == victim) + continue; + if (!damageLog.ContainsKey(key)) + damageLog.Add(key, value); + else + damageLog[key] += value; + } + + if (debugHandle) + Debug.Log("HandleKillLogRequest from: " + msgRef.client.GetIdentifier()); + + ClientReference victimClient = matchData.clientList.Find(x => x.seq == victim); + victimClient.deaths++; + SendDeathCount(victimClient); + + if (killer == victim) + killer = damageLog.OrderByDescending(x => x.Value).FirstOrDefault().Key; + + ClientReference killerClient = matchData.clientList.Find(x => x.seq == killer); + if (killer != victim) + { + killerClient.kills++; + SendKillCount(killerClient); + } + + foreach (KeyValuePair entry in damageLog) + { + if (entry.Key != victim) + { + if (entry.Key != killer) + { + ClientReference assistClient = matchData.clientList.Find(x => x.seq == entry.Key); + assistClient.assists++; + assistClient.score += entry.Value; + SendAssistCount(assistClient); + } + + else + { + killerClient.score += entry.Value; + SendRoundScore(killerClient); + } + + } + } + + KillLogEntry killLogEntry = new KillLogEntry(id, killerType, killer, victimType, victim, (Weapon.BY)weaponBy, slot, category, hitpart, damageLog); + matchData.killLog.Add(killLogEntry); + SendKillLogEntry(killLogEntry, matchData); + + if (killer != victim) + { + switch (matchData.room.Type) + { + case Room.ROOM_TYPE.TEAM_MATCH: + if (victimClient.slot.slotIndex > 7) + matchData.redScore++; + else + matchData.blueScore++; + SendTeamScore(matchData); + if (matchData.blueScore >= matchData.room.goal || matchData.redScore >= matchData.room.goal) + { + HandleTeamMatchEnd(matchData); + } + break; + + case Room.ROOM_TYPE.INDIVIDUAL: + matchData.redScore++; + SendIndividualScore(matchData); + + if (matchData.redScore >= matchData.room.goal) + { + HandleIndividualMatchEnd(matchData); + } + break; + + case Room.ROOM_TYPE.BND: + Debug.LogWarning(matchData.isBuildPhase); + //the emulator match data is currently in the wrong phase? + if (!matchData.isBuildPhase) + { + // Score during the Destroy phase + if (victimClient.slot.slotIndex > 7) + matchData.redScore++; + else + matchData.blueScore++; + + SendBnDScore(matchData); + + if (matchData.blueScore >= matchData.room.goal || matchData.redScore >= matchData.room.goal) + { + HandleBNDMatchEnd(matchData); + } + } + break; + + case Room.ROOM_TYPE.CAPTURE_THE_FLAG: + if (victimClient.slot.slotIndex > 7) + matchData.ctfRedKillCount++; + else + matchData.ctfBlueKillCount++; + SendTeamScore(matchData); + if (matchData.blueScore >= matchData.room.goal || matchData.redScore >= matchData.room.goal) + { + HandleCTFMatchEnd(matchData); + } + break; + } + } + } + + private void HandleTeamScoreRequest(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleTeamScoreRequest from: " + msgRef.client.GetIdentifier()); - private void HandleClearShooterTools(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleClearShooterTools from: " + msgRef.client.GetIdentifier()); + SendTeamScore(msgRef.matchData); + } - for (int i = 0; i < msgRef.client.inventory.shooterTools.Length; i++) - { - if (msgRef.client.inventory.shooterTools[i] == null) - continue; + private void HandleDestroyBrickRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - msgRef.client.inventory.shooterTools[i].toolSlot = -1; - msgRef.client.inventory.shooterTools[i] = null; - } + msgRef.msg._msg.Read(out int brick); - msgRef.client.inventory.GenerateActiveTools(); - SendShooterToolList(msgRef.client); - } + if (debugHandle) + Debug.Log("HandleDestroyBrickRequest from: " + msgRef.client.GetIdentifier()); - private void HandleClearWeaponSlots(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleClearWeaponSlots from: " + msgRef.client.GetIdentifier()); + if (!(matchData.destroyedBricks.Exists(x => x == brick))) + { + matchData.destroyedBricks.Add(brick); + SendDestroyBrick(brick, matchData); + } + } - for (int i = 0; i < msgRef.client.inventory.weaponChg.Length; i++) - { - if (msgRef.client.inventory.weaponChg[i] == null) - continue; + private void HandleRegMapInfoRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int mapId); - msgRef.client.inventory.weaponChg[i].toolSlot = -1; - msgRef.client.inventory.weaponChg[i] = null; - } + if (debugHandle) + Debug.Log("HandleRegMapInfoRequest from: " + msgRef.client.GetIdentifier()); + } - msgRef.client.inventory.GenerateActiveChange(); - SendWeaponSlotList(msgRef.client); - } + private void HandleInventoryCSV(MsgReference msgRef) + { + // List to hold new equipment + List newEquipment = new List(); + + // Read the total count of items + msgRef.msg._msg.Read(out int itemCount); + msgRef.client.inventory = new Inventory(msgRef.client.seq); + msgRef.client.inventory.equipment.Clear(); + + // Read each item's slot and code + for (int i = 0; i < itemCount; i++) + { + msgRef.msg._msg.Read(out string slotName); + msgRef.msg._msg.Read(out string code); + msgRef.msg._msg.Read(out string usage); + + // Fetch the item template + TItem template = TItemManager.Instance.Get(code); + if (template != null) + { + msgRef.client.inventory.AddItem(template, false, -1, (Item.USAGE) Enum.Parse(typeof(Item.USAGE), usage, true)); + } + else + { + Debug.LogWarning($"Template not found for code: {code}"); + } + } + + if (debugHandle) + Debug.Log($"HandleInventoryCSV from: {msgRef.client.GetIdentifier()}"); + + msgRef.client.inventory.GenerateActiveSlots(); + msgRef.client.inventory.GenerateActiveTools(); + msgRef.client.inventory.GenerateActiveChange(); + + // Notify the client about the updated inventory + SendInventory(msgRef.client); + } + + private void HandleEquipRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + msgRef.msg._msg.Read(out long itemSeq); + + if (debugHandle) + Debug.Log("HandleEquipRequest from: " + msgRef.client.GetIdentifier()); + + Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); + if (item != null) + { + if (!item.IsEquipable) + return; + + int index = Inventory.SlotToIndex(item.Template.slot); + if (index != -1 && index < msgRef.client.inventory.activeSlots.Length) + { + Item oldItem = msgRef.client.inventory.activeSlots[index]; + if (oldItem != null) + { + oldItem.Usage = Item.USAGE.UNEQUIP; + msgRef.client.inventory.activeSlots[index] = null; + SendUnequip(msgRef.client, oldItem.Seq, oldItem.Code); + } + } + + if (item.Code == "s92" || item.Code == "s09" || item.Code == "s08" || item.Code == "s07") + { + string[] targetCodes = { "s92", "s09", "s08", "s07" }; + + // Find and unequip any items with matching codes in equipment + foreach (string code in targetCodes) + { + Item equippedItem = msgRef.client.inventory.equipment.Find(x => x.Code == code); + if (equippedItem != null) + { + equippedItem.Usage = Item.USAGE.UNEQUIP; + SendUnequip(msgRef.client, equippedItem.Seq, equippedItem.Code); + } + } + } + + item.Usage = Item.USAGE.EQUIP; + msgRef.client.inventory.GenerateActiveSlots(); + msgRef.client.inventory.UpdateCSV(); + + SendEquip(msgRef.client, item.Seq, item.Code); + } + } + + private void HandleUnequipRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + // Read the item sequence number from the message. + msgRef.msg._msg.Read(out long itemSeq); + + if (debugHandle) + Debug.Log("HandleUnequipRequest from: " + msgRef.client.GetIdentifier()); + + // Find the item in the inventory using the sequence number. + Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); + if (item != null) + { + // Check if the item is currently equipped. + if (item.Usage != Item.USAGE.EQUIP) + return; + + // Find the index of the slot that the item is equipped to. + int index = Inventory.SlotToIndex(item.Template.slot); + if (index != -1 && index < msgRef.client.inventory.activeSlots.Length) + { + // Ensure that the item is the one currently equipped in the slot. + Item currentItem = msgRef.client.inventory.activeSlots[index]; + if (currentItem != null && currentItem.Seq == itemSeq) + { + // Set the item's usage to unequip and update the inventory slot. + currentItem.Usage = Item.USAGE.UNEQUIP; + msgRef.client.inventory.activeSlots[index] = null; + + // Send a message to the client indicating the item has been unequipped. + SendUnequip(msgRef.client, currentItem.Seq, currentItem.Code); + } + } + + // Regenerate the active slots to reflect the change in the inventory. + msgRef.client.inventory.GenerateActiveSlots(); + msgRef.client.inventory.UpdateCSV(); + } + } + + + private void HandleClearShooterTools(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleClearShooterTools from: " + msgRef.client.GetIdentifier()); - private void HandleSetShooterToolRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out sbyte slot); - msgRef.msg._msg.Read(out long itemSeq); + for (int i = 0; i < msgRef.client.inventory.shooterTools.Length; i++) + { + if (msgRef.client.inventory.shooterTools[i] == null) + continue; - if (debugHandle) - Debug.Log("HandleSetShooterToolRequest from: " + msgRef.client.GetIdentifier()); + msgRef.client.inventory.shooterTools[i].toolSlot = -1; + msgRef.client.inventory.shooterTools[i] = null; + } + msgRef.client.inventory.GenerateActiveTools(); + SendShooterToolList(msgRef.client); + } - if (itemSeq < 0) - { - msgRef.client.inventory.shooterTools[slot].toolSlot = -1; - msgRef.client.inventory.shooterTools[slot] = null; - } + private void HandleClearWeaponSlots(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleClearWeaponSlots from: " + msgRef.client.GetIdentifier()); - else - { - Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); - - if (item != null) - { - if (item.toolSlot >= 0) - { - Item dupeItem = msgRef.client.inventory.shooterTools[item.toolSlot]; - if (dupeItem != null) - msgRef.client.inventory.shooterTools[dupeItem.toolSlot] = null; - } - - Item oldItem = msgRef.client.inventory.shooterTools[slot]; - if (oldItem != null) - { - oldItem.toolSlot = -1; - msgRef.client.inventory.shooterTools[slot] = null; - } - - item.toolSlot = slot; - msgRef.client.inventory.shooterTools[slot] = item; - } - } + for (int i = 0; i < msgRef.client.inventory.weaponChg.Length; i++) + { + if (msgRef.client.inventory.weaponChg[i] == null) + continue; - msgRef.client.inventory.GenerateActiveTools(); - SendShooterToolList(msgRef.client); - //SendSetShooterTool(msgRef.client, slot, item.Seq); - } + msgRef.client.inventory.weaponChg[i].toolSlot = -1; + msgRef.client.inventory.weaponChg[i] = null; + } - private void HandleSetWeaponSlotRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int slot); - msgRef.msg._msg.Read(out long itemSeq); + msgRef.client.inventory.GenerateActiveChange(); + SendWeaponSlotList(msgRef.client); + } - if (debugHandle) - Debug.Log("HandleSetWeaponSlotRequest from: " + msgRef.client.GetIdentifier()); + private void HandleSetShooterToolRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out sbyte slot); + msgRef.msg._msg.Read(out long itemSeq); + + if (debugHandle) + Debug.Log("HandleSetShooterToolRequest from: " + msgRef.client.GetIdentifier()); + + + if (itemSeq < 0) + { + msgRef.client.inventory.shooterTools[slot].toolSlot = -1; + msgRef.client.inventory.shooterTools[slot] = null; + } + + else + { + Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); + + if (item != null) + { + if (item.toolSlot >= 0) + { + Item dupeItem = msgRef.client.inventory.shooterTools[item.toolSlot]; + if (dupeItem != null) + msgRef.client.inventory.shooterTools[dupeItem.toolSlot] = null; + } + + Item oldItem = msgRef.client.inventory.shooterTools[slot]; + if (oldItem != null) + { + oldItem.toolSlot = -1; + msgRef.client.inventory.shooterTools[slot] = null; + } + + item.toolSlot = slot; + msgRef.client.inventory.shooterTools[slot] = item; + } + } + + msgRef.client.inventory.GenerateActiveTools(); + SendShooterToolList(msgRef.client); + //SendSetShooterTool(msgRef.client, slot, item.Seq); + } + + private void HandleSetWeaponSlotRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int slot); + msgRef.msg._msg.Read(out long itemSeq); + + if (debugHandle) + Debug.Log("HandleSetWeaponSlotRequest from: " + msgRef.client.GetIdentifier()); + + if (itemSeq < 0) + { + msgRef.client.inventory.weaponChg[slot].toolSlot = -1; + msgRef.client.inventory.weaponChg[slot] = null; + } + + else + { + Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); + if (item != null) + { + if (item.toolSlot >= 0) + { + Item dupeItem = msgRef.client.inventory.weaponChg[item.toolSlot]; + if (dupeItem != null) + msgRef.client.inventory.weaponChg[dupeItem.toolSlot] = null; + } + + Item oldItem = msgRef.client.inventory.weaponChg[slot]; + if (oldItem != null) + { + oldItem.toolSlot = -1; + msgRef.client.inventory.shooterTools[slot] = null; + } + + item.toolSlot = (sbyte)slot; + msgRef.client.inventory.shooterTools[slot] = item; + } + } + + msgRef.client.inventory.GenerateActiveChange(); + SendWeaponSlotList(msgRef.client); + //SendSetWeaponSlot(msgRef.client, slot, item.Seq); + } + + private void HandleRadioMsgRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); + msgRef.msg._msg.Read(out int category); + msgRef.msg._msg.Read(out int message); - if (itemSeq < 0) - { - msgRef.client.inventory.weaponChg[slot].toolSlot = -1; - msgRef.client.inventory.weaponChg[slot] = null; - } + if (debugHandle) + Debug.Log("HandleRadioMsgRequest from: " + msgRef.client.GetIdentifier()); - else - { - Item item = msgRef.client.inventory.equipment.Find(x => x.Seq == itemSeq); - if (item != null) - { - if (item.toolSlot >= 0) - { - Item dupeItem = msgRef.client.inventory.weaponChg[item.toolSlot]; - if (dupeItem != null) - msgRef.client.inventory.weaponChg[dupeItem.toolSlot] = null; - } - - Item oldItem = msgRef.client.inventory.weaponChg[slot]; - if (oldItem != null) - { - oldItem.toolSlot = -1; - msgRef.client.inventory.shooterTools[slot] = null; - } - - item.toolSlot = (sbyte)slot; - msgRef.client.inventory.shooterTools[slot] = item; - } - } + SendRadioMsg(seq, category, message, msgRef.matchData); + } - msgRef.client.inventory.GenerateActiveChange(); - SendWeaponSlotList(msgRef.client); - //SendSetWeaponSlot(msgRef.client, slot, item.Seq); - } + private void HandleChargeForcePoint(MsgReference msgRef) + { + msgRef.msg._msg.Read(out long seq); + msgRef.msg._msg.Read(out string code); + + Item item = MyInfoManager.Instance.inventory[seq]; + + Debug.LogWarning("Found Item: " + item.Code + item.IsAmount + " amount: " + item.Amount); + item.Amount = item.Amount - 1; + Debug.LogWarning("New Amount " + item.Amount); + Debug.LogWarning("EnopughToConsume " + item.EnoughToConsume); + if (!item.EnoughToConsume) + { + Debug.LogWarning("Remove Item"); + MyInfoManager.Instance.inventory.Remove(item.Seq); + } + TSpecial special = (TSpecial)item.Template; + int forcePoints = msgRef.client.data.forcePoints = msgRef.client.data.forcePoints + int.Parse(special.param); + SendForcePointAssetUpdate(msgRef.client, forcePoints); + SendChargeForcePoint(msgRef.client, seq, code, int.Parse(special.param)); + } + + public void SendForcePointAssetUpdate(ClientReference client, int forcePoints) + { + MsgBody bodyUpdate = new MsgBody(); + bodyUpdate.Write(forcePoints); + bodyUpdate.Write(client.data.brickPoints); + bodyUpdate.Write(client.data.tokens); + bodyUpdate.Write(client.data.coins); + bodyUpdate.Write(client.data.starDust); + Say(new MsgReference(102, bodyUpdate, client, SendType.Unicast)); + } + + public void SendChargeForcePoint(ClientReference client, long seq, string code, int amount) + { + MsgBody body = new MsgBody(); - private void HandleRadioMsgRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int seq); - msgRef.msg._msg.Read(out int category); - msgRef.msg._msg.Read(out int message); - - if (debugHandle) - Debug.Log("HandleRadioMsgRequest from: " + msgRef.client.GetIdentifier()); - - SendRadioMsg(seq, category, message); - } - - private void HandleChatRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out string text); - - if (debugHandle) - Debug.Log("HandleChatRequest from: " + msgRef.client.GetIdentifier()); - - SendChat(msgRef.client, ChatText.CHAT_TYPE.NORMAL, text); - } - - private void HandleTeamChatRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out string text); - - if (debugHandle) - Debug.Log("HandleTeamChatRequest from: " + msgRef.client.GetIdentifier()); - - SendChat(msgRef.client, ChatText.CHAT_TYPE.TEAM, text); - } - - private void HandleResultDoneRequest(MsgReference msgRef) - { - msgRef.client.status = BrickManDesc.STATUS.PLAYER_WAITING; - msgRef.client.clientStatus = ClientReference.ClientStatus.Room; - - if (debugHandle) - Debug.Log("HandleResultDoneRequest from: " + msgRef.client.GetIdentifier()); - - SendSetStatus(msgRef.client); - } - - public void HandleRespawnTicketRequest(MsgReference msgRef) - { - if (debugHandle) - Debug.Log("HandleRespawnTicketRequest from: " + msgRef.client.GetIdentifier()); - - SendRespawnTicket(msgRef.client); - } - - public void HandleIndividualMatchEnd() - { - matchData.room.Status = Room.ROOM_STATUS.WAITING; - SendIndividualMatchEnd(); - matchData.Reset(); - SendRoom(null, SendType.BroadcastRoom); - } - - public void HandleTeamMatchEnd() - { - matchData.room.Status = Room.ROOM_STATUS.WAITING; - SendTeamMatchEnd(); - matchData.Reset(); - SendRoom(null, SendType.BroadcastRoom); - } - - private void HandleWeaponChangeRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int slot); - msgRef.msg._msg.Read(out long seq); - msgRef.msg._msg.Read(out string next); - msgRef.msg._msg.Read(out string prev); - - if (debugHandle) - Debug.Log("HandleWeaponChangeRequest from: " + msgRef.client.GetIdentifier()); - - SendWeaponChange(msgRef.client, seq); - SendPlayerWeaponChange(msgRef.client, prev, next); - } - - private void HandleOpenDoorRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int seq); - - if (debugHandle) - Debug.Log("HandleOpenDoorRequest from: " + msgRef.client.GetIdentifier()); - - SendOpenDoor(seq); - } - - private void HandleCloseDoorRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int seq); - - if (debugHandle) - Debug.Log("HandleCloseDoorRequest from: " + msgRef.client.GetIdentifier()); - } - - private void HandleDisconnect(MsgReference msgRef) - { - msgRef.client.Disconnect(); - } - - private void HandleDelegateMasterRequest(MsgReference msgRef) - { - if (msgRef.client.seq == matchData.masterSeq) - { - msgRef.msg._msg.Read(out int newMaster); - if (debugHandle) - Debug.Log("HandleDelegateMasterRequest from: " + msgRef.client.GetIdentifier()); - matchData.masterSeq = newMaster; - SendMaster(null); - } - } + body.Write(1); //flag for success? + body.Write(seq); //unused + body.Write(code); - private void HandleGetCannonRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int brickSeq); + body.Write(amount); //charge amount - if (debugHandle) - Debug.Log("HandleGetCannonRequest from: " + msgRef.client.GetIdentifier()); + Say(new MsgReference(472, body, client, SendType.Unicast)); + } - if (!matchData.usedCannons.ContainsKey(brickSeq)) - { - matchData.usedCannons.Add(brickSeq, msgRef.client.seq); - SendGetCannon(msgRef.client.seq, brickSeq); - Debug.Log(matchData.usedCannons.Count); - } - } + private void HandleChatRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out string text); - private void HandleEmptyCannonRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int brickSeq); + if (debugHandle) + Debug.Log("HandleChatRequest from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleGetCannonRequest from: " + msgRef.client.GetIdentifier()); + SendChat(msgRef.client, ChatText.CHAT_TYPE.NORMAL, text); + } - if (matchData.usedCannons.ContainsKey(brickSeq)) - { - matchData.usedCannons.Remove(brickSeq); - SendEmptyCannon(brickSeq); - } - } + private void HandleTeamChatRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out string text); - private void HandleGetTrainRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int brickSeq); - msgRef.msg._msg.Read(out int trainId); + if (debugHandle) + Debug.Log("HandleTeamChatRequest from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleGetTrainRequest from: " + msgRef.client.GetIdentifier()); + SendChat(msgRef.client, ChatText.CHAT_TYPE.TEAM, text); + } - if (!matchData.usedTrains.ContainsKey(trainId)) - { - matchData.usedTrains.Add(trainId, msgRef.client.seq); - SendGetTrain(msgRef.client.seq, trainId); - } - } + private void HandleResultDoneRequest(MsgReference msgRef) + { + msgRef.client.status = BrickManDesc.STATUS.PLAYER_WAITING; + msgRef.client.clientStatus = ClientReference.ClientStatus.Room; - private void HandleEmptyTrainRequest(MsgReference msgRef) - { - msgRef.msg._msg.Read(out int trainId); + if (debugHandle) + Debug.Log("HandleResultDoneRequest from: " + msgRef.client.GetIdentifier()); - if (debugHandle) - Debug.Log("HandleEmptyTrainRequest from: " + msgRef.client.GetIdentifier()); + SendSetStatus(msgRef.client); + } - if (matchData.usedTrains.ContainsKey(trainId)) - { - matchData.usedTrains.Remove(trainId); - SendEmptyTrain(trainId); - } - } + public void HandleRespawnTicketRequest(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleRespawnTicketRequest from: " + msgRef.client.GetIdentifier()); - public void SendPremiumItems(ClientReference client) - { - MsgBody body = new MsgBody(); + SendRespawnTicket(msgRef.client); + } - body.Write(2); - body.Write("s20"); - body.Write("s21"); + public void HandleIndividualMatchEnd(MatchData matchData) + { + matchData.room.Status = Room.ROOM_STATUS.WAITING; + SendIndividualMatchEnd(matchData); + matchData.Reset(); + SendRoom(null, matchData, SendType.BroadcastRoom); + } - Say(new MsgReference(492, body, client)); - } + public void HandleTeamMatchEnd(MatchData matchData) + { + matchData.room.Status = Room.ROOM_STATUS.WAITING; + SendTeamMatchEnd(matchData); + matchData.Reset(); + SendRoom(null, matchData, SendType.BroadcastRoom); + } - public void SendKick(ClientReference client, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + public void HandleCTFMatchEnd(MatchData matchData) + { + matchData.room.Status = Room.ROOM_STATUS.WAITING; + SendCTFMatchEnd(matchData); + matchData.Reset(); + SendRoom(null, matchData, SendType.BroadcastRoom); + } - body.Write(client.seq); + public void HandleBNDMatchEnd(MatchData matchData) + { + matchData.room.Status = Room.ROOM_STATUS.WAITING; + SendBNDMatchEnd(matchData); + matchData.Reset(); + SendRoom(null, matchData, SendType.BroadcastRoom); + } - Say(new MsgReference(89, body, client, sendType)); - } - public void SendCannons(ClientReference client) - { - foreach(KeyValuePair entry in matchData.usedCannons) - { - SendGetCannon(entry.Value, entry.Key, client, SendType.Unicast); - } - } + public void HandleZombieMatchEnd(MatchData matchData) + { + matchData.room.Status = Room.ROOM_STATUS.WAITING; + SendZombieMatchEnd(matchData); + matchData.Reset(); + SendRoom(null, matchData, SendType.BroadcastRoom); + } - public void SendTrains(ClientReference client) - { - foreach (KeyValuePair entry in matchData.usedTrains) - { - SendGetTrain(entry.Value, entry.Key, client, SendType.Unicast); - } - } + private void HandleWeaponChangeRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int slot); + msgRef.msg._msg.Read(out long seq); + msgRef.msg._msg.Read(out string next); + msgRef.msg._msg.Read(out string prev); - public void SendGetCannon(int seq, int brickSeq, ClientReference client = null, SendType sendType = SendType.BroadcastRoom) - { - MsgBody body = new MsgBody(); + if (debugHandle) + Debug.Log("HandleWeaponChangeRequest from: " + msgRef.client.GetIdentifier()); - body.Write(seq); - body.Write(brickSeq); + SendWeaponChange(msgRef.client, seq); + SendPlayerWeaponChange(msgRef.client, prev, next); + } - Say(new MsgReference(159, body, null, sendType)); + private void HandleOpenDoorRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); - if (debugSend) - { - if (sendType == SendType.BroadcastRoom) - Debug.Log("Broadcasted SendGetCannon for room no: " + matchData.room.No); + if (debugHandle) + Debug.Log("HandleOpenDoorRequest from: " + msgRef.client.GetIdentifier()); - else - Debug.Log("SendGetCannon to: " + client.GetIdentifier()); - } - } + SendOpenDoor(seq, msgRef.matchData); + } - public void SendEmptyCannon(int brickSeq) - { - MsgBody body = new MsgBody(); + private void HandleCloseDoorRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); - body.Write(brickSeq); + if (debugHandle) + Debug.Log("HandleCloseDoorRequest from: " + msgRef.client.GetIdentifier()); + } - Say(new MsgReference(161, body, null, SendType.BroadcastRoom)); + private void HandleDisconnect(MsgReference msgRef) + { + msgRef.client.Disconnect(); + } - if (debugSend) - Debug.Log("Broadcasted SendEmptyCannon for room no: " + matchData.room.No); - } + private void HandleDelegateMasterRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - public void SendGetTrain(int seq, int trainId, ClientReference client = null, SendType sendType = SendType.BroadcastRoom) - { - MsgBody body = new MsgBody(); + if (msgRef.client.seq == matchData.masterSeq) + { + msgRef.msg._msg.Read(out int newMaster); - body.Write(seq); - body.Write(trainId); + if (debugHandle) + Debug.Log("HandleDelegateMasterRequest from: " + msgRef.client.GetIdentifier()); - Say(new MsgReference(552, body, client, sendType)); + matchData.masterSeq = newMaster; + SendMaster(null, matchData); + } + } - if (debugSend) - { - if (sendType == SendType.BroadcastRoom) - Debug.Log("Broadcasted SendGetTrain for room no: " + matchData.room.No); + private void HandleGetCannonRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - else - Debug.Log("SendGetTrain to: " + client.GetIdentifier()); - } - } + msgRef.msg._msg.Read(out int brickSeq); - public void SendEmptyTrain(int trainId) - { - MsgBody body = new MsgBody(); + if (debugHandle) + Debug.Log("HandleGetCannonRequest from: " + msgRef.client.GetIdentifier()); - body.Write(trainId); + if (!matchData.usedCannons.ContainsKey(brickSeq)) + { + matchData.usedCannons.Add(brickSeq, msgRef.client.seq); + SendGetCannon(msgRef.client.seq, brickSeq, matchData); + Debug.Log(matchData.usedCannons.Count); + } + } - Say(new MsgReference(554, body, null, SendType.BroadcastRoom)); + private void HandleEmptyCannonRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - if (debugSend) - Debug.Log("Broadcasted SendEmptyTrain for room no: " + matchData.room.No); - } + msgRef.msg._msg.Read(out int brickSeq); - public void SendDisconnect(ClientReference client, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + if (debugHandle) + Debug.Log("HandleGetCannonRequest from: " + msgRef.client.GetIdentifier()); - SayInstant(new MsgReference(ExtensionOpcodes.opDisconnectAck, body, client, sendType)); - } + if (matchData.usedCannons.ContainsKey(brickSeq)) + { + matchData.usedCannons.Remove(brickSeq); + SendEmptyCannon(brickSeq, matchData); + } + } - public void SendOpenDoor(int seq) - { - MsgBody body = new MsgBody(); + private void HandleGetTrainRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - body.Write(seq); + msgRef.msg._msg.Read(out int brickSeq); + msgRef.msg._msg.Read(out int trainId); - Say(new MsgReference(450, body, null, SendType.BroadcastRoom)); + if (debugHandle) + Debug.Log("HandleGetTrainRequest from: " + msgRef.client.GetIdentifier()); - if (debugSend) - Debug.Log("Broadcasted SendOpenDoor for room no: " + matchData.room.No); - } + if (!matchData.usedTrains.ContainsKey(trainId)) + { + matchData.usedTrains.Add(trainId, msgRef.client.seq); + SendGetTrain(msgRef.client.seq, trainId, matchData); + } + } - public void SendWeaponChange(ClientReference client, long seq) - { - MsgBody body = new MsgBody(); + private void HandleEmptyTrainRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - body.Write(0); //errorcode - body.Write(0); //unused; - body.Write(seq); + msgRef.msg._msg.Read(out int trainId); - Say(new MsgReference(415, body, client)); + if (debugHandle) + Debug.Log("HandleEmptyTrainRequest from: " + msgRef.client.GetIdentifier()); - if (debugSend) - Debug.Log("SendWeaponChange to: " + client.GetIdentifier()); - } + if (matchData.usedTrains.ContainsKey(trainId)) + { + matchData.usedTrains.Remove(trainId); + SendEmptyTrain(trainId, matchData); + } + } - public void SendPlayerWeaponChange(ClientReference client, string prev, string next) - { - MsgBody body = new MsgBody(); + private void HandleCacheBrickRequest(MsgReference msgRef) + { + if (debugHandle) + Debug.Log("HandleCacheBrickRequest from: " + msgRef.client.GetIdentifier()); - body.Write(client.seq); - body.Write(prev); - body.Write(next); + SendCacheBrick(msgRef.client); + SendCacheBrickDone(msgRef.client); + } - Say(new MsgReference(416, body, client, SendType.BroadcastRoomExclusive)); + private void HandleAddBrickRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + if (debugHandle) + Debug.Log("HandleAddBrickRequest from: " + msgRef.client.GetIdentifier()); + + msgRef.msg._msg.Read(out byte brick); + msgRef.msg._msg.Read(out byte x); + msgRef.msg._msg.Read(out byte y); + msgRef.msg._msg.Read(out byte z); + msgRef.msg._msg.Read(out byte rot); + + int seq = matchData.GetNextBrickSeq(); + List morphes = new List(); + BrickInst brickInst = matchData.cachedMap.AddBrickInst(seq, brick, x, y, z, 0, rot); + if (brickInst != null) + { + SendAddBrick(msgRef.client, brickInst); + } + } + + private void HandleDelBrickRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; - if (debugSend) - Debug.Log("Broadcasted SendPlayerWeaponChange for player: " + client.GetIdentifier()); - } - public void SendInventory(ClientReference client) - { - SendItemList(client); - SendShooterToolList(client); - SendWeaponSlotList(client); - SendItemProperties(client); - SendItemPimps(client); - SendPremiumItems(client); - } - public void SendIndividualMatchEnd() - { - MsgBody body = new MsgBody(); + if (debugHandle) + Debug.Log("HandleDelBrickRequest from: " + msgRef.client.GetIdentifier()); - body.Write(matchData.clientList.Count); - for (int i = 0; i < matchData.clientList.Count; i++) - { - body.Write(matchData.clientList[i].slot.isRed); - body.Write(matchData.clientList[i].seq); - body.Write(matchData.clientList[i].name); - body.Write(matchData.clientList[i].kills); - body.Write(matchData.clientList[i].deaths); - body.Write(matchData.clientList[i].assists); - body.Write(matchData.clientList[i].score); - body.Write(0); //points - body.Write(0); //xp - body.Write(0); //mission - body.Write(matchData.clientList[i].data.xp); - body.Write(matchData.clientList[i].data.xp); - body.Write((long)0); //buff - } - Say(new MsgReference(180, body, null, SendType.BroadcastRoom)); + msgRef.msg._msg.Read(out int seq); - if (debugSend) - Debug.Log("Broadcasted SendIndivudalMatchEnd for room no: " + matchData.room.No); - } + List morphes = new List(); + if (matchData.cachedMap.DelBrickInst(seq, ref morphes)) + SendDelBrick(msgRef.client, seq); + } - public void SendTeamMatchEnd() - { - for (int team = 0; team < 2; team++) - { - MsgBody body = new MsgBody(); - - body.Write(team == 0 ? matchData.GetWinningTeam() : (sbyte)-matchData.GetWinningTeam()); - body.Write(matchData.redScore); - body.Write(matchData.blueScore); - body.Write(matchData.blueScore); - body.Write(matchData.redScore); - body.Write(matchData.clientList.Count); - for (int i = 0; i < matchData.clientList.Count; i++) - { - body.Write(matchData.clientList[i].slot.isRed); - body.Write(matchData.clientList[i].seq); - body.Write(matchData.clientList[i].name); - body.Write(matchData.clientList[i].kills); - body.Write(matchData.clientList[i].deaths); - body.Write(matchData.clientList[i].assists); - body.Write(matchData.clientList[i].score); - body.Write(0); //points - body.Write(0); //xp - body.Write(0); //mission - body.Write(matchData.clientList[i].data.xp); - body.Write(matchData.clientList[i].data.xp); - body.Write((long)0); //buff - } - Say(new MsgReference(70, body, null, team == 0 ? SendType.BroadcastBlueTeam : SendType.BroadcastRedTeam)); - } + private void HandleRegisterMapRequest(MsgReference msgRef) + { + MatchData matchData = msgRef.matchData; + + if (debugHandle) + Debug.Log("HandleRegisterMap from: " + msgRef.client.GetIdentifier()); + + msgRef.msg._msg.Read(out int map); + msgRef.msg._msg.Read(out ushort modeMask); + msgRef.msg._msg.Read(out int regHow); + msgRef.msg._msg.Read(out int point); + msgRef.msg._msg.Read(out int downloadFee); + msgRef.msg._msg.Read(out string msgEval); + + if (map == matchData.cachedMap.map) + { + Texture2D thumbnail = new Texture2D(1, 1); + if (msgRef.client.chunkedBuffer.id == ExtensionOpcodes.opChunkedBufferThumbnailReq) + { + if (msgRef.client.chunkedBuffer.finished) + { + thumbnail.LoadImage(msgRef.client.chunkedBuffer.buffer); + thumbnail.Apply(); + if (debugSend) + Debug.Log("Load Thumbnail"); + } + else + Debug.LogError("HandleRegisterMapRequest: ChunkedBuffer not finished"); + } + + DateTime time = DateTime.Now; + int hashId = MapGenerator.instance.GetHashIdForTime(time); + RegMap regMap = new RegMap(hashId, msgRef.client.name + "@Aurora", matchData.cachedUMI.Alias, time, modeMask, true, false, 0, 0, 0, 0, 0, 0, 0, false); + regMap.Thumbnail = thumbnail; + matchData.cachedMap.map = hashId; + matchData.cachedUMI.regMap = regMap; + matchData.cachedUMI.slot = hashId; + + matchData.cachedUMI.regMap.Save(); + matchData.cachedMap.Save(hashId, matchData.cachedMap.skybox); + + SendCustomMessage("Saved " + matchData.cachedUMI.regMap.Alias + " with ID " + hashId); + } + + msgRef.client.chunkedBuffer = null; + } + + public void HandleBNDScoreRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + msg.Write(data.redScore); // red score + msg.Write(data.blueScore); // blue score + if (debugHandle) + Debug.Log("HandleBNDScoreReq from: " + msgRef.client.GetIdentifier() + " RedScore: " + data.redScore + " BluScore: " + data.blueScore); - if (debugSend) - Debug.Log("Broadcasted SendTeamMatchEnd for room no: " + matchData.room.No); - } + Say(new MsgReference(339, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } - public void SendChat(ClientReference client, ChatText.CHAT_TYPE type, string text) - { - MsgBody body = new MsgBody(); + public void HandleBNDShiftPhaseRequest(MsgReference msgRef) + { + Debug.LogWarning("recieved Shift Phase Req"); + msgRef.msg._msg.Read(out int repeat); + MatchData matchData = msgRef.client.matchData; + Debug.LogWarning("matchData old repeat: " + matchData.repeat + " msg repeat: " + repeat); + matchData.repeat = repeat; + if (repeat <= 0) + { + matchData.EndMatch(); + } + + msgRef.msg._msg.Read(out bool isBuildPhase); + Debug.LogWarning("matchData old isBuildPhase: " + matchData.isBuildPhase + " msg isBuild: " + isBuildPhase); + matchData.isBuildPhase = isBuildPhase; + SendShiftPhase(msgRef.client, repeat, isBuildPhase); + } + + public void SendShiftPhase(ClientReference client, int repeat, bool isBuildPhase) + { + MatchData matchData = client.matchData; + matchData.ResetForNewRound(); - body.Write(client.seq); - body.Write((byte)type); - body.Write(client.name); - body.Write(text); - body.Write(Convert.ToBoolean(client.data.gm)); + MsgBody body = new MsgBody(); + body.Write(repeat); + body.Write(isBuildPhase); - Say(new MsgReference(25, body, null, SendType.Broadcast)); + Say(new MsgReference(344, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); + } - if (debugSend) - Debug.Log("Broadcasted SendChat"); - } - public void SendRadioMsg(int seq, int category, int message) - { - MsgBody body = new MsgBody(); - body.Write(seq); - body.Write(category); - body.Write(message); + public void SendDelBrick(ClientReference client, int brickSeq) + { + MatchData matchData = client.matchData; - Say(new MsgReference(96, body, null, SendType.BroadcastRoom)); + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendRadioMsg for room no: " + matchData.room.No); - } + body.Write(client.seq); + body.Write(brickSeq); - public void SendItemPimps(ClientReference client) - { - List weapons = client.inventory.equipment.FindAll(x => x.Template.type == TItem.TYPE.WEAPON); - for (int i = 0; i < weapons.Count; i++) - { - SendItemPimp(client, weapons[i], PIMP.PROP_ATK_POW, 10); - SendItemPimp(client, weapons[i], PIMP.PROP_ACCURACY, 10); - SendItemPimp(client, weapons[i], PIMP.PROP_RECOIL, 10); - SendItemPimp(client, weapons[i], PIMP.PROP_RPM, weapons[i].Template.upgradeCategory == TItem.UPGRADE_CATEGORY.HAND_GUN ? 10 : 10); - SendItemPimp(client, weapons[i], PIMP.PROP_AMMO_MAX, 10); - SendItemPimp(client, weapons[i], PIMP.PROP_ATTACK_SPEED, 10); - } - } + Say(new MsgReference(16, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); - public void SendItemPimp(ClientReference client, Item item, PIMP pimp, int grade) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendDelBrick for room no " + matchData.room.No + " " + client.GetIdentifier()); + } - body.Write(item.Seq); - body.Write((int)pimp); - body.Write(grade); + public void SendAddBrick(ClientReference client, BrickInst brick) + { + MatchData matchData = client.matchData; - Say(new MsgReference(355, body, client)); - } + MsgBody body = new MsgBody(); - public void SendItemProperties(ClientReference client) - { - MsgBody body = new MsgBody(); + body.Write(client.seq); + body.Write(brick.Seq); + body.Write(brick.Template); + body.Write(brick.PosX); + body.Write(brick.PosY); + body.Write(brick.PosZ); + body.Write(brick.Rot); - List propertyItems = client.inventory.equipment.FindAll(x => x.Template.type == TItem.TYPE.ACCESSORY || x.Template.type == TItem.TYPE.CLOTH); - body.Write(propertyItems.Count); - for (int i = 0; i < propertyItems.Count; i++) - { - body.Write(propertyItems[i].Code); - body.Write("ARMOR"); - body.Write(propertyItems[i].Template.type != TItem.TYPE.ACCESSORY || propertyItems[i].Template.slot == TItem.SLOT.HEAD ? 20 : 10); - body.Write(""); - body.Write(0.2f); - } + Say(new MsgReference(14, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); - Say(new MsgReference(491, body, client)); + if (debugSend) + Debug.Log("SendAddBrick for room no " + matchData.room.No + " " + client.GetIdentifier()); + } - if (debugSend) - Debug.Log("SendItemProperties to: " + client.GetIdentifier()); - } + public void SendCacheBrick(ClientReference client) + { + MatchData matchData = client.matchData; + + List> brickList = new List>(); + brickList = matchData.cachedMap.dic.ToList(); + + int chunkSize = 100; + int chunkCount = Mathf.CeilToInt((float)brickList.Count / (float)chunkSize); + int processedCount = 0; + + for (int chunk = 0; chunk < chunkCount; chunk++) + { + int remaining = brickList.Count - processedCount; + if (remaining < chunkSize) + chunkSize = remaining; + + MsgBody body = new MsgBody(); + + body.Write(chunkSize); + + for (int i = 0; i < chunkSize; i++, processedCount++) + { + BrickInst brickInst = brickList[processedCount].Value; + body.Write(brickInst.Seq); + body.Write(brickInst.Template); + body.Write(brickInst.PosX); + body.Write(brickInst.PosY); + body.Write(brickInst.PosZ); + body.Write(brickInst.Code); + body.Write(brickInst.Rot); + if (brickInst.BrickForceScript != null) + { + body.Write((byte)brickInst.BrickForceScript.CmdList.Count); + + if (brickInst.BrickForceScript.CmdList.Count > 0) + { + body.Write(brickInst.BrickForceScript.Alias); + body.Write(brickInst.BrickForceScript.EnableOnAwake); + body.Write(brickInst.BrickForceScript.VisibleOnAwake); + body.Write(brickInst.BrickForceScript.GetCommandString()); + } + } + + else + body.Write((byte)0); + } + + Say(new MsgReference(21, body, client, SendType.Unicast)); + } + + if (debugSend) + Debug.Log("SendCacheBrick with " + chunkCount + " chunks to: " + client.GetIdentifier()); + } + + public void SendCacheBrickDone(ClientReference client) + { + MatchData matchData = client.matchData; - public void SendSetShooterTool(ClientReference client, sbyte slot, long itemSeq) - { - MsgBody body = new MsgBody(); + MsgBody body = new MsgBody(); - body.Write(slot); - body.Write(itemSeq); + body.Write(0); //mapIndex + body.Write(matchData.cachedMap.skybox); - Say(new MsgReference(332, body, client)); + Say(new MsgReference(22, body, client, SendType.Unicast)); - if (debugSend) - Debug.Log("SendSetShooterTool to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("SendCacheBrickDone for map " + matchData.cachedMap.map + " to: " + client.GetIdentifier()); + } - public void SendSetWeaponSlot(ClientReference client, int slot, long itemSeq) - { - MsgBody body = new MsgBody(); + public void SendCopyright(ClientReference client) + { + MsgBody body = new MsgBody(); - body.Write(slot); - body.Write(itemSeq); + MatchData matchData = client.matchData; - Say(new MsgReference(418, body, client)); + body.Write(matchData.masterSeq); + body.Write(matchData.cachedUMI.Slot); - if (debugSend) - Debug.Log("SendSetWeaponSlot to: " + client.GetIdentifier()); - } + Say(new MsgReference(53, body, client)); - public void SendShooterToolList(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendCopyRight to: " + client.GetIdentifier()); + } - body.Write(client.inventory.shooterTools.Length); - for (int i = 0; i < client.inventory.shooterTools.Length; i++) - { - if (client.inventory.shooterTools[i] == null) - { - body.Write((sbyte)i); - body.Write((long)-1); - } - - else - { - body.Write(client.inventory.shooterTools[i].toolSlot); - body.Write(client.inventory.shooterTools[i].Seq); - } - } + public void SendPremiumItems(ClientReference client) + { + MsgBody body = new MsgBody(); - Say(new MsgReference(462, body, client)); + body.Write(2); + body.Write("s20"); + body.Write("s21"); - if (debugSend) - Debug.Log("SendShooterToolList to: " + client.GetIdentifier()); - } + Say(new MsgReference(492, body, client)); + } - public void SendWeaponSlotList(ClientReference client) - { - MsgBody body = new MsgBody(); + public void SendKick(ClientReference client, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - body.Write(client.inventory.weaponChg.Length); - for (int i = 0; i < client.inventory.weaponChg.Length; i++) - { - if (client.inventory.weaponChg[i] == null) - { - body.Write(i); - body.Write((long)-1); - } - - else - { - body.Write((int)client.inventory.weaponChg[i].toolSlot); - body.Write(client.inventory.weaponChg[i].Seq); - } - } + body.Write(client.seq); - Say(new MsgReference(463, body, client)); + Say(new MsgReference(89, body, client, sendType)); + } + public void SendCannons(ClientReference client) + { + MatchData matchData = client.matchData; - if (debugSend) - Debug.Log("SendWeaponSlotList to: " + client.GetIdentifier()); - } + foreach (KeyValuePair entry in matchData.usedCannons) + { + SendGetCannon(entry.Value, entry.Key, matchData, client, SendType.Unicast); + } + } - public void SendEquip(ClientReference client, long itemSeq, string code) - { - MsgBody body = new MsgBody(); + public void SendTrains(ClientReference client) + { + MatchData matchData = client.matchData; - body.Write(client.seq); - body.Write(itemSeq); - body.Write(code); + foreach (KeyValuePair entry in matchData.usedTrains) + { + SendGetTrain(entry.Value, entry.Key, matchData, client, SendType.Unicast); + } + } - Say(new MsgReference(36, body, client, SendType.Broadcast)); + public void SendGetCannon(int seq, int brickSeq, MatchData matchData, ClientReference client = null, SendType sendType = SendType.BroadcastRoom) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendEquip for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(seq); + body.Write(brickSeq); - public void SendUnequip(ClientReference client, long itemSeq, string code) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(159, body, null, sendType, matchData.channel, matchData)); - body.Write(client.seq); - body.Write(itemSeq); - body.Write(code); + if (debugSend) + { + if (sendType == SendType.BroadcastRoom) + Debug.Log("Broadcasted SendGetCannon for room no: " + matchData.room.No); - Say(new MsgReference(38, body, client, SendType.Broadcast)); + else + Debug.Log("SendGetCannon to: " + client.GetIdentifier()); + } + } - if (debugSend) - Debug.Log("Broadcasted SendUnequip for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + public void SendEmptyCannon(int brickSeq, MatchData matchData) + { + MsgBody body = new MsgBody(); - public void SendInventoryRequest(ClientReference client) - { - MsgBody body = new MsgBody(); + body.Write(brickSeq); - body.Write(client.seq); + Say(new MsgReference(161, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - Say(new MsgReference(ExtensionOpcodes.opInventoryReq, body, client)); + if (debugSend) + Debug.Log("Broadcasted SendEmptyCannon for room no: " + matchData.room.No); + } - if (debugSend) - Debug.Log("SendInventoryRequest to: " + client.GetIdentifier()); - } + public void SendGetTrain(int seq, int trainId, MatchData matchData, ClientReference client = null, SendType sendType = SendType.BroadcastRoom) + { + MsgBody body = new MsgBody(); - public void SendDestroyBrick(int brick) - { - MsgBody body = new MsgBody(); + body.Write(seq); + body.Write(trainId); - body.Write(brick); + Say(new MsgReference(552, body, client, sendType, matchData.channel, matchData)); - Say(new MsgReference(77, body, null, SendType.BroadcastRoom)); + if (debugSend) + { + if (sendType == SendType.BroadcastRoom) + Debug.Log("Broadcasted SendGetTrain for room no: " + matchData.room.No); - if (debugSend) - Debug.Log("Broadcasted SendDestroyBrick for brick " + brick+ " for room no: " + matchData.room.No); - } + else + Debug.Log("SendGetTrain to: " + client.GetIdentifier()); + } + } - public void SendDestroyedBrick(ClientReference client, int brick, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + public void SendEmptyTrain(int trainId, MatchData matchData) + { + MsgBody body = new MsgBody(); - body.Write(brick); + body.Write(trainId); - Say(new MsgReference(78, body, client, sendType)); + Say(new MsgReference(554, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - if (debugSend) - { - if (sendType == SendType.Unicast) - Debug.Log("SendDestroyedBrick to: " + client.GetIdentifier()); - else - Debug.Log("Broadcasted SendDestroyedBrick for brick for room no: " + matchData.room.No); - } - } + if (debugSend) + Debug.Log("Broadcasted SendEmptyTrain for room no: " + matchData.room.No); + } - public void SendKillCount(ClientReference client) - { - MsgBody body = new MsgBody(); + public void SendDisconnect(ClientReference client, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - body.Write(client.seq); - body.Write(client.kills); + SayInstant(new MsgReference(ExtensionOpcodes.opDisconnectAck, body, client, sendType)); + } - Say(new MsgReference(69, body, null, SendType.BroadcastRoom)); + public void SendOpenDoor(int seq, MatchData matchData) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendKillCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(seq); - public void SendDeathCount(ClientReference client) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(450, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - body.Write(client.seq); - body.Write(client.deaths); + if (debugSend) + Debug.Log("Broadcasted SendOpenDoor for room no: " + matchData.room.No); + } - Say(new MsgReference(68, body, null, SendType.BroadcastRoom)); + public void SendWeaponChange(ClientReference client, long seq) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendDeatchCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(0); //errorcode + body.Write(0); //unused; + body.Write(seq); - public void SendAssistCount(ClientReference client) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(415, body, client)); - body.Write(client.seq); - body.Write(client.assists); - body.Write(client.score); + if (debugSend) + Debug.Log("SendWeaponChange to: " + client.GetIdentifier()); + } - Say(new MsgReference(185, body, null, SendType.BroadcastRoom)); + public void SendPlayerWeaponChange(ClientReference client, string prev, string next) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendAssistCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(client.seq); + body.Write(prev); + body.Write(next); - public void SendRoundScore(ClientReference client) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(416, body, client, SendType.BroadcastRoomExclusive, client.channel, client.matchData)); - body.Write(client.seq); - body.Write(client.score); + if (debugSend) + Debug.Log("Broadcasted SendPlayerWeaponChange for player: " + client.GetIdentifier()); + } + public void SendInventory(ClientReference client) + { + SendItemList(client); + SendShooterToolList(client); + SendWeaponSlotList(client); + SendItemProperties(client); + SendItemPimps(client); + SendPremiumItems(client); + } + public void SendIndividualMatchEnd(MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + body.Write(matchData.clientList[i].slot.isRed); + body.Write(matchData.clientList[i].seq); + body.Write(matchData.clientList[i].name); + body.Write(matchData.clientList[i].kills); + body.Write(matchData.clientList[i].deaths); + body.Write(matchData.clientList[i].assists); + body.Write(matchData.clientList[i].score); + body.Write(0); //points + body.Write(0); //xp + body.Write(0); //mission + body.Write(matchData.clientList[i].data.xp); + body.Write(matchData.clientList[i].data.xp); + body.Write((long)0); //buff + } + Say(new MsgReference(180, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendIndivudalMatchEnd for room no: " + matchData.room.No); + } + + public void SendTeamMatchEnd(MatchData matchData) + { + for (int team = 0; team < 2; team++) + { + MsgBody body = new MsgBody(); + + body.Write(team == 0 ? matchData.GetWinningTeam() : (sbyte)-matchData.GetWinningTeam()); + body.Write(matchData.redScore); + body.Write(matchData.blueScore); + body.Write(matchData.blueScore); + body.Write(matchData.redScore); + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + body.Write(matchData.clientList[i].slot.isRed); + body.Write(matchData.clientList[i].seq); + body.Write(matchData.clientList[i].name); + body.Write(matchData.clientList[i].kills); + body.Write(matchData.clientList[i].deaths); + body.Write(matchData.clientList[i].assists); + body.Write(matchData.clientList[i].score); + body.Write(0); //points + body.Write(0); //xp + body.Write(0); //mission + body.Write(matchData.clientList[i].data.xp); + body.Write(matchData.clientList[i].data.xp); + body.Write((long)0); //buff + } + Say(new MsgReference(70, body, null, team == 0 ? SendType.BroadcastBlueTeam : SendType.BroadcastRedTeam)); + } + + if (debugSend) + Debug.Log("Broadcasted SendTeamMatchEnd for room no: " + matchData.room.No); + } + + public void SendCTFMatchEnd(MatchData matchData) + { + for (int team = 0; team < 2; team++) + { + MsgBody body = new MsgBody(); + + body.Write(team == 0 ? matchData.GetWinningTeam() : (sbyte)-matchData.GetWinningTeam()); + body.Write(matchData.redScore); //RedScore + body.Write(matchData.blueScore); //BlueScore + body.Write(matchData.ctfRedKillCount); //RedTotalKill + body.Write(matchData.ctfBlueKillCount); //BluTotalKill + body.Write(matchData.ctfBlueKillCount); //RedTotalDeath + body.Write(matchData.ctfRedKillCount); //BlueTotalDeath + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + body.Write(matchData.clientList[i].slot.isRed); + body.Write(matchData.clientList[i].seq); + body.Write(matchData.clientList[i].name); + body.Write(matchData.clientList[i].kills); + body.Write(matchData.clientList[i].deaths); + body.Write(matchData.clientList[i].assists); + body.Write(matchData.clientList[i].score); + body.Write(0); //points + body.Write(0); //xp + body.Write(0); //mission + body.Write(matchData.clientList[i].data.xp); + body.Write(matchData.clientList[i].data.xp); + body.Write((long)0); //buff + } + Say(new MsgReference(292, body, null, team == 0 ? SendType.BroadcastBlueTeam : SendType.BroadcastRedTeam)); + } + + if (debugSend) + Debug.Log("Broadcasted SendCTFMatchEnd for room no: " + matchData.room.No); + } + + public void SendBNDMatchEnd(MatchData matchData) + { + for (int team = 0; team < 2; team++) + { + MsgBody body = new MsgBody(); + + body.Write(team == 0 ? matchData.GetWinningTeam() : (sbyte)-matchData.GetWinningTeam()); + body.Write(matchData.redScore); //RedScore + body.Write(matchData.blueScore); //BlueScore + body.Write(matchData.blueScore); //RedTotalKill + body.Write(matchData.redScore); //BluTotalKill + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + body.Write(matchData.clientList[i].slot.isRed); + body.Write(matchData.clientList[i].seq); + body.Write(matchData.clientList[i].name); + body.Write(matchData.clientList[i].kills); + body.Write(matchData.clientList[i].deaths); + body.Write(matchData.clientList[i].assists); + body.Write(matchData.clientList[i].score); + body.Write(0); //points + body.Write(0); //xp + body.Write(0); //mission + body.Write(matchData.clientList[i].data.xp); + body.Write(matchData.clientList[i].data.xp); + body.Write((long)0); //buff + } + Say(new MsgReference(338, body, null, team == 0 ? SendType.BroadcastBlueTeam : SendType.BroadcastRedTeam)); + } + + if (debugSend) + Debug.Log("Broadcasted SendBNDMatchEnd for room no: " + matchData.room.No); + } + + public void SendZombieMatchEnd(MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + int points = (int) (matchData.clientList[i].score * 0.4); + int xp = (int)(matchData.clientList[i].score * 0.5); + body.Write(matchData.clientList[i].slot.isRed); + body.Write(matchData.clientList[i].seq); + body.Write(matchData.clientList[i].name); + body.Write(0); // survival ensured + body.Write(0); // zombie victory + body.Write(matchData.clientList[i].assists); + body.Write(matchData.clientList[i].score); + body.Write(points); //points + body.Write(xp); //xp + body.Write(0); //mission + body.Write(matchData.clientList[i].data.xp); + body.Write(matchData.clientList[i].data.xp + xp); + body.Write((long)0); //buff + } + + Say(new MsgReference(537, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log($"Broadcasted SendZombieMatchEnd for room no: {matchData.room.No}"); + } + + public void SendChat(ClientReference client, ChatText.CHAT_TYPE type, string text) + { + MsgBody body = new MsgBody(); - Say(new MsgReference(300, body, null, SendType.BroadcastRoom)); + body.Write(client.seq); + body.Write((byte)type); + body.Write(client.name); + body.Write(text); + body.Write(Convert.ToBoolean(client.data.gm)); - if (debugSend) - Debug.Log("Broadcasted SendRoundScore for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + Say(new MsgReference(25, body, null, SendType.BroadcastChannel, client.channel, client.matchData)); - public void SendKillLogEntry(KillLogEntry entry) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("Broadcasted SendChat"); + } - body.Write(entry.id); - body.Write(entry.killerType); - body.Write(entry.killer); - body.Write(entry.victimType); - body.Write(entry.victim); - body.Write((int)entry.weaponBy); - body.Write(entry.hitpart); + public void SendRadioMsg(int seq, int category, int message, MatchData matchData) + { + MsgBody body = new MsgBody(); + body.Write(seq); + body.Write(category); + body.Write(message); - Say(new MsgReference(45, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(96, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - if (debugSend) - Debug.Log("Broadcasted SendKillLogEntry for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("Broadcasted SendRadioMsg for room no: " + matchData.room.No); + } - public void SendIndividualScore() - { - MsgBody body = new MsgBody(); + public void SendItemPimps(ClientReference client) + { + List weapons = client.inventory.equipment.FindAll(x => x.Template.type == TItem.TYPE.WEAPON); + for (int i = 0; i < weapons.Count; i++) + { + SendItemPimp(client, weapons[i], PIMP.PROP_ATK_POW, 10); + SendItemPimp(client, weapons[i], PIMP.PROP_ACCURACY, 10); + SendItemPimp(client, weapons[i], PIMP.PROP_RECOIL, 10); + SendItemPimp(client, weapons[i], PIMP.PROP_RPM, weapons[i].Template.upgradeCategory == TItem.UPGRADE_CATEGORY.HAND_GUN ? 10 : 10); + SendItemPimp(client, weapons[i], PIMP.PROP_AMMO_MAX, 10); + SendItemPimp(client, weapons[i], PIMP.PROP_ATTACK_SPEED, 10); + } + } + + public void SendItemPimp(ClientReference client, Item item, PIMP pimp, int grade) + { + MsgBody body = new MsgBody(); - body.Write(matchData.redScore); + body.Write(item.Seq); + body.Write((int)pimp); + body.Write(grade); - Say(new MsgReference(179, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(355, body, client)); + } - if (debugSend) - Debug.Log("Broadcasted SendIndividualScore for room no: " + matchData.room.No); - } + public void SendItemProperties(ClientReference client) + { + MsgBody body = new MsgBody(); + + List propertyItems = client.inventory.equipment.FindAll(x => x.Template.type == TItem.TYPE.ACCESSORY || x.Template.type == TItem.TYPE.CLOTH); + body.Write(propertyItems.Count); + for (int i = 0; i < propertyItems.Count; i++) + { + body.Write(propertyItems[i].Code); + body.Write("ARMOR"); + body.Write(propertyItems[i].Template.type != TItem.TYPE.ACCESSORY || propertyItems[i].Template.slot == TItem.SLOT.HEAD ? 20 : 10); + body.Write(""); + body.Write(0.2f); + } + + Say(new MsgReference(491, body, client)); + + if (debugSend) + Debug.Log("SendItemProperties to: " + client.GetIdentifier()); + } + + public void SendSetShooterTool(ClientReference client, sbyte slot, long itemSeq) + { + MsgBody body = new MsgBody(); - public void SendTeamScore() - { - MsgBody body = new MsgBody(); - body.Write(matchData.redScore); - body.Write(matchData.blueScore); + body.Write(slot); + body.Write(itemSeq); - Say(new MsgReference(67, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(332, body, client)); - if (debugSend) - Debug.Log("Broadcasted SendTeamScore for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("SendSetShooterTool to: " + client.GetIdentifier()); + } - public void SendMaster(ClientReference client) - { - MsgBody body = new MsgBody(); + public void SendSetWeaponSlot(ClientReference client, int slot, long itemSeq) + { + MsgBody body = new MsgBody(); - body.Write(matchData.masterSeq); + body.Write(slot); + body.Write(itemSeq); - if (client == null) - { - Say(new MsgReference(31, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(418, body, client)); - if (debugSend) - Debug.Log("Broadcasted SendMaster for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("SendSetWeaponSlot to: " + client.GetIdentifier()); + } - else - { - Say(new MsgReference(31, body, client)); + public void SendShooterToolList(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.inventory.shooterTools.Length); + for (int i = 0; i < client.inventory.shooterTools.Length; i++) + { + if (client.inventory.shooterTools[i] == null) + { + body.Write((sbyte)i); + body.Write((long)-1); + } + + else + { + body.Write(client.inventory.shooterTools[i].toolSlot); + body.Write(client.inventory.shooterTools[i].Seq); + } + } + + Say(new MsgReference(462, body, client)); + + if (debugSend) + Debug.Log("SendShooterToolList to: " + client.GetIdentifier()); + } + + public void SendWeaponSlotList(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.inventory.weaponChg.Length); + for (int i = 0; i < client.inventory.weaponChg.Length; i++) + { + if (client.inventory.weaponChg[i] == null) + { + body.Write(i); + body.Write((long)-1); + } + + else + { + body.Write((int)client.inventory.weaponChg[i].toolSlot); + body.Write(client.inventory.weaponChg[i].Seq); + } + } + + Say(new MsgReference(463, body, client)); + + if (debugSend) + Debug.Log("SendWeaponSlotList to: " + client.GetIdentifier()); + } + + public void SendEquip(ClientReference client, long itemSeq, string code) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("SendMaster to: " + client.GetIdentifier()); - } - } + body.Write(client.seq); + body.Write(itemSeq); + body.Write(code); - public void SendSlotLocks(ClientReference client) - { - for (sbyte i = 0; i < matchData.slots.Count; i++) - { - SendSlotLock(client, i); - } + Say(new MsgReference(36, body, client, SendType.Broadcast)); - if (debugSend) - Debug.Log("SendSlots to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("Broadcasted SendEquip for client " + client.GetIdentifier() + " for room no: "); + } - public void SendSlotLock(ClientReference client, sbyte index, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + public void SendUnequip(ClientReference client, long itemSeq, string code) + { + MsgBody body = new MsgBody(); - body.Write(index); - body.Write(Convert.ToSByte(matchData.slots[index].isLocked)); - Say(new MsgReference(86, body, client, sendType)); + body.Write(client.seq); + body.Write(itemSeq); + body.Write(code); - if (debugSend) - { - if (sendType == SendType.Unicast) - Debug.Log("SendSlotLock to: " + client.GetIdentifier()); - else - Debug.Log("Broadcasted SendSlotLock for room no " + matchData.room.No); - } - } - - public void SendRoomConfig(ClientReference client) - { - MsgBody body = new MsgBody(); - - body.Write(matchData.room.map); - body.Write(matchData.room.CurMapAlias); - body.Write(matchData.room.weaponOption); - body.Write(matchData.room.timelimit); - body.Write(matchData.room.goal); - body.Write(matchData.room.isBreakInto); - body.Write(matchData.isBalance); - body.Write(false); //useBuildGun - body.Write(""); //password - body.Write((byte)0); //commented - body.Write((int)matchData.room.Type); - body.Write(matchData.room.isDropItem); - body.Write(matchData.room.isWanted); - - if (client == null) - { - Say(new MsgReference(92, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(38, body, client, SendType.Broadcast)); - if (debugSend) - Debug.Log("Broadcasted SendRoomConfig for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("Broadcasted SendUnequip for client " + client.GetIdentifier() + " for room no: "); + } - else - { - Say(new MsgReference(92, body, client)); + public void SendInventoryRequest(ClientReference client) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("SendRoomConfig to: " + client.GetIdentifier()); - } - } - - public void SendAddRoom(ClientReference client) - { - MsgBody body = new MsgBody(); - - body.Write(matchData.room.No); - body.Write((int)matchData.room.Type); - body.Write(matchData.room.Title); - body.Write(matchData.room.Locked); - body.Write((int)matchData.room.Status); - body.Write(matchData.room.CurPlayer); - body.Write(matchData.room.MaxPlayer); - body.Write(matchData.room.map); - body.Write(matchData.room.CurMapAlias); - body.Write(matchData.room.goal); - body.Write(matchData.room.timelimit); - body.Write(matchData.room.weaponOption); - body.Write(matchData.room.ping); - body.Write(matchData.room.score1); - body.Write(matchData.room.score2); - body.Write(matchData.room.CountryFilter); - body.Write(matchData.room.isBreakInto); - body.Write(matchData.room.isDropItem); - body.Write(matchData.room.isWanted); - body.Write(matchData.room.Squad); - body.Write(matchData.room.SquadCounter); - - if (client == null) - { - Say(new MsgReference(5, body, null, SendType.BroadcastRoom)); + body.Write(client.seq); - if (debugSend) - Debug.Log("Broadcasted SendAddRoom for room no: " + matchData.room.No); - } + Say(new MsgReference(ExtensionOpcodes.opInventoryReq, body, client)); - else - { - Say(new MsgReference(5, body, client)); + if (debugSend) + Debug.Log("SendInventoryRequest to: " + client.GetIdentifier()); + } - if (debugSend) - Debug.Log("SendAddRoom to: " + client.GetIdentifier()); - } - } - - public void SendRoom(ClientReference client, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); - - body.Write(matchData.room.No); - body.Write((int)matchData.room.Type); - body.Write(matchData.room.Title); - body.Write(matchData.room.Locked); - body.Write((int)matchData.room.Status); - body.Write(matchData.room.CurPlayer); - body.Write(matchData.room.MaxPlayer); - body.Write(matchData.room.map); - body.Write(matchData.room.CurMapAlias); - body.Write(matchData.room.goal); - body.Write(matchData.room.timelimit); - body.Write(matchData.room.weaponOption); - body.Write(matchData.room.ping); - body.Write(matchData.room.score1); - body.Write(matchData.room.score2); - body.Write(matchData.room.CountryFilter); - body.Write(matchData.room.isBreakInto); - body.Write(matchData.room.isDropItem); - body.Write(matchData.room.isWanted); - body.Write(matchData.room.Squad); - body.Write(matchData.room.SquadCounter); - - Say(new MsgReference(470, body, client, sendType)); - - if (debugSend) - { - if (sendType == SendType.Unicast) - Debug.Log("SendRoom to: " + client.GetIdentifier()); + public void SendDestroyBrick(int brick, MatchData matchData) + { + MsgBody body = new MsgBody(); - else - Debug.Log("Broadcasted SendRoom for room no: " + matchData.room.No); - } + body.Write(brick); - } + Say(new MsgReference(77, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - public void SendDeleteRoom() - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("Broadcasted SendDestroyBrick for brick " + brick + " for room no: " + matchData.room.No); + } - body.Write(matchData.room.No); + public void SendDestroyedBrick(ClientReference client, int brick, MatchData matchData, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - Say(new MsgReference(6, body, null, SendType.Broadcast)); + body.Write(brick); - if (debugSend) - Debug.Log("Broadcasted SendDelRoom for room no: " + matchData.room.No); - } + Say(new MsgReference(78, body, client, sendType, matchData.channel, matchData)); - public void SendRoomList(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + { + if (sendType == SendType.Unicast) + Debug.Log("SendDestroyedBrick to: " + client.GetIdentifier()); + else + Debug.Log("Broadcasted SendDestroyedBrick for brick for room no: " + matchData.room.No); + } + } - body.Write(Convert.ToInt32(matchData.roomCreated)); //count - if (matchData.roomCreated) - { - body.Write(matchData.room.No); - body.Write((int)matchData.room.Type); - body.Write(matchData.room.Title); - body.Write(matchData.room.Locked); - body.Write((int)matchData.room.Status); - body.Write(matchData.room.CurPlayer); - body.Write(matchData.room.MaxPlayer); - body.Write(matchData.room.map); - body.Write(matchData.room.CurMapAlias); - body.Write(matchData.room.goal); - body.Write(matchData.room.timelimit); - body.Write(matchData.room.weaponOption); - body.Write(matchData.room.ping); - body.Write(matchData.room.score1); - body.Write(matchData.room.score2); - body.Write(matchData.room.CountryFilter); - body.Write(matchData.room.isBreakInto); - body.Write(matchData.room.isDropItem); - body.Write(matchData.room.isWanted); - body.Write(matchData.room.Squad); - body.Write(matchData.room.SquadCounter); - } + public void SendKillCount(ClientReference client) + { + MatchData matchData = client.matchData; - Say(new MsgReference(468, body, client)); + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("SendRoomList to: " + client.GetIdentifier()); - } + body.Write(client.seq); + body.Write(client.kills); - public void SendCreateRoom(ClientReference client, bool success = true) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(69, body, null, SendType.BroadcastRoom, client.channel, client.matchData)); - body.Write((int)matchData.room.Type); - body.Write(success ? matchData.room.No : -1); - body.Write(matchData.room.Title); + if (debugSend) + Debug.Log("Broadcasted SendKillCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } - Say(new MsgReference(8, body, client)); + public void SendDeathCount(ClientReference client) + { + MatchData matchData = client.matchData; - if (debugSend) - Debug.Log("SendCreateRoom to: " + client.GetIdentifier()); - } + MsgBody body = new MsgBody(); - public void SendJoin(ClientReference client) - { - MsgBody body = new MsgBody(); + body.Write(client.seq); + body.Write(client.deaths); - body.Write(matchData.room.No); - Say(new MsgReference(29, body, client)); + Say(new MsgReference(68, body, null, SendType.BroadcastRoom, client.channel, client.matchData)); - if (debugSend) - Debug.Log("SendJoin to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("Broadcasted SendDeatchCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } - public void SendBreakInto(ClientReference client, int reply) - { - MsgBody body = new MsgBody(); + public void SendAssistCount(ClientReference client) + { + MatchData matchData = client.matchData; - body.Write(reply); + MsgBody body = new MsgBody(); - Say(new MsgReference(74, body, client)); + body.Write(client.seq); + body.Write(client.assists); + body.Write(client.score); - if (debugSend) - Debug.Log("SendBreakInto to: " + client.GetIdentifier()); - } + Say(new MsgReference(185, body, null, SendType.BroadcastRoom, client.channel, client.matchData)); - public void SendEnter(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("Broadcasted SendAssistCount for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } - body.Write(client.slot.slotIndex); - body.Write(client.seq); - body.Write(client.name); - body.Write(client.ip); - body.Write(client.port); //port - body.Write(client.ip); - body.Write(client.port); //remotePort - body.Write(client.inventory.equipmentString.Length); - for (int i = 0; i < client.inventory.equipmentString.Length; i++) - { - body.Write(client.inventory.equipmentString[i]); - } - body.Write((int)client.status); - body.Write(client.data.xp); - body.Write(client.data.clanSeq); - body.Write(client.data.clanName); - body.Write(client.data.clanMark); - body.Write(client.data.rank); - body.Write((byte)1); //playerflag - body.Write(client.inventory.weaponChgString.Length); - for (int i = 0; i < client.inventory.weaponChgString.Length; i++) - { - body.Write(client.inventory.weaponChgString[i]); - } - body.Write(0); //drpItem count + public void SendRoundScore(ClientReference client) + { + MatchData matchData = client.matchData; - Say(new MsgReference(10, body, client, SendType.BroadcastRoomExclusive)); + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendEnter for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(client.seq); + body.Write(client.score); - public void SendLeave(ClientReference client) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(300, body, null, SendType.BroadcastRoom, client.channel, client.matchData)); - body.Write(client.seq); + if (debugSend) + Debug.Log("Broadcasted SendRoundScore for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } - Say(new MsgReference(11, body, client, SendType.BroadcastRoom)); + public void SendKillLogEntry(KillLogEntry entry, MatchData matchData) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendLeave for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + body.Write(entry.id); + body.Write(entry.killerType); + body.Write(entry.killer); + body.Write(entry.victimType); + body.Write(entry.victim); + body.Write((int)entry.weaponBy); + body.Write(entry.hitpart); - public void SendSlotData() - { - MsgBody body = new MsgBody(); + Say(new MsgReference(45, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - body.Write(matchData.clientList.Count); - for (int i = 0; i < matchData.clientList.Count; i++) - { - ClientReference client = matchData.clientList[i]; - body.Write(client.slot.slotIndex); - body.Write(client.seq); - body.Write(client.name); - body.Write(client.ip); - body.Write(client.port); //port - body.Write(client.ip); - body.Write(client.port); //remotePort - body.Write(client.inventory.equipmentString.Length); - for (int j = 0; j < client.inventory.equipmentString.Length; j++) - { - body.Write(client.inventory.equipmentString[j]); - } - body.Write((int)client.status); - body.Write(client.data.xp); - body.Write(client.data.clanSeq); - body.Write(client.data.clanName); - body.Write(client.data.clanMark); - body.Write(client.data.rank); - body.Write((byte)1); //playerflag - body.Write(client.inventory.weaponChgString.Length); - for (int j = 0; j < client.inventory.weaponChgString.Length; j++) - { - body.Write(client.inventory.weaponChgString[j]); - } - body.Write(0); //drpItem count - } + if (debugSend) + Debug.Log("Broadcasted SendKillLogEntry for room no: " + matchData.room.No); + } - Say(new MsgReference(ExtensionOpcodes.opSlotDataAck, body, null, SendType.BroadcastRoom)); - Say(new MsgReference(ExtensionOpcodes.opSlotDataAck, body, null, SendType.BroadcastRoom)); + public void SendIndividualScore(MatchData matchData) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendSlotData for room no: " + matchData.room.No); - } + body.Write(matchData.redScore); - public void SendTeamChange(ClientReference client) - { - MsgBody body = new MsgBody(); + Say(new MsgReference(179, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - body.Write(client.seq); - body.Write(0); //unused - body.Write(client.slot.slotIndex); + if (debugSend) + Debug.Log("Broadcasted SendIndividualScore for room no: " + matchData.room.No); + } - Say(new MsgReference(81, body, client, SendType.BroadcastRoom)); + public void SendTeamScore(MatchData matchData) + { + MsgBody body = new MsgBody(); + body.Write(matchData.redScore); + body.Write(matchData.blueScore); - if (debugSend) - Debug.Log("Broadcasted SendTeamChange for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + Say(new MsgReference(67, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - public void SendSetStatus(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("Broadcasted SendTeamScore for room no: " + matchData.room.No); + } - body.Write(client.seq); - body.Write((int)client.status); + public void SendBnDScore(MatchData matchData) + { + MsgBody body = new MsgBody(); + body.Write(matchData.redScore); + body.Write(matchData.blueScore); - Say(new MsgReference(48, body, null, SendType.BroadcastRoom)); + Say(new MsgReference(339, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - if (debugSend) - Debug.Log("Broadcasted SendSetStatus for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("Broadcasted SendTeamScore for room no: " + matchData.room.No); + } - public void SendStart() - { - MsgBody body = new MsgBody(); + public void SendMaster(ClientReference client, MatchData matchData) + { + MsgBody body = new MsgBody(); - body.Write(matchData.lobbyCountdownTime); + body.Write(matchData.masterSeq); - Say(new MsgReference(50, body, null, SendType.BroadcastRoom)); + if (client == null) + { + Say(new MsgReference(31, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); - if (debugSend) - Debug.Log("Broadcasted SendStart for room no: " + matchData.room.No); - } + if (debugSend) + Debug.Log("Broadcasted SendMaster for room no: " + matchData.room.No); + } - public void SendPostLoadInit(ClientReference client) - { - MsgBody body = new MsgBody(); + else + { + Say(new MsgReference(31, body, client)); - Say(new MsgReference(ExtensionOpcodes.opPostLoadInitAck, body, client)); + if (debugSend) + Debug.Log("SendMaster to: " + client.GetIdentifier()); + } + } - if (debugSend) - Debug.Log("SendPostLoadInit to: " + client.GetIdentifier()); - } + public void SendSlotLocks(ClientReference client) + { + MatchData matchData = client.matchData; + for (sbyte i = 0; i < matchData.slots.Count; i++) + { + SendSlotLock(client, matchData, i); + } - public void SendLoadComplete(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendSlots to: " + client.GetIdentifier()); + } - body.Write(client.seq); - Say(new MsgReference(43, body, null, SendType.BroadcastRoom)); + public void SendSlotLock(ClientReference client, MatchData matchData, sbyte index, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); + + body.Write(index); + body.Write(Convert.ToSByte(matchData.slots[index].isLocked)); + Say(new MsgReference(86, body, client, sendType, matchData.channel, matchData)); + + if (debugSend) + { + if (sendType == SendType.Unicast) + Debug.Log("SendSlotLock to: " + client.GetIdentifier()); + else + Debug.Log("Broadcasted SendSlotLock for room no " + matchData.room.No); + } + } + + public void SendRoomConfig(ClientReference client, MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.room.map); + body.Write(matchData.room.CurMapAlias); + body.Write(matchData.room.weaponOption); + body.Write(matchData.room.timelimit); + body.Write(matchData.room.goal); + body.Write(matchData.room.isBreakInto); + body.Write(matchData.isBalance); + body.Write(false); //useBuildGun + body.Write(""); //password + body.Write((byte)0); //commented + body.Write((int)matchData.room.Type); + body.Write(matchData.room.isDropItem); + body.Write(matchData.room.isWanted); + + if (client == null) + { + Say(new MsgReference(92, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendRoomConfig for room no: " + matchData.room.No); + } + + else + { + Say(new MsgReference(92, body, client)); + + if (debugSend) + Debug.Log("SendRoomConfig to: " + client.GetIdentifier()); + } + } + + public void SendAddRoom(ClientReference client, MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.room.No); + body.Write((int)matchData.room.Type); + body.Write(matchData.room.Title); + body.Write(matchData.room.Locked); + body.Write((int)matchData.room.Status); + body.Write(matchData.room.CurPlayer); + body.Write(matchData.room.MaxPlayer); + body.Write(matchData.room.map); + body.Write(matchData.room.CurMapAlias); + body.Write(matchData.room.goal); + body.Write(matchData.room.timelimit); + body.Write(matchData.room.weaponOption); + body.Write(matchData.room.ping); + body.Write(matchData.room.score1); + body.Write(matchData.room.score2); + body.Write(matchData.room.CountryFilter); + body.Write(matchData.room.isBreakInto); + body.Write(matchData.room.isDropItem); + body.Write(matchData.room.isWanted); + body.Write(matchData.room.Squad); + body.Write(matchData.room.SquadCounter); + + if (client == null) + { + Say(new MsgReference(5, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendAddRoom for room no: " + matchData.room.No); + } + + else + { + Say(new MsgReference(5, body, client)); + + if (debugSend) + Debug.Log("SendAddRoom to: " + client.GetIdentifier()); + } + } + + public void SendRoom(ClientReference client, MatchData matchData, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.room.No); + body.Write((int)matchData.room.Type); + body.Write(matchData.room.Title); + body.Write(matchData.room.Locked); + body.Write((int)matchData.room.Status); + body.Write(matchData.room.CurPlayer); + body.Write(matchData.room.MaxPlayer); + body.Write(matchData.room.map); + body.Write(matchData.room.CurMapAlias); + body.Write(matchData.room.goal); + body.Write(matchData.room.timelimit); + body.Write(matchData.room.weaponOption); + body.Write(matchData.room.ping); + body.Write(matchData.room.score1); + body.Write(matchData.room.score2); + body.Write(matchData.room.CountryFilter); + body.Write(matchData.room.isBreakInto); + body.Write(matchData.room.isDropItem); + body.Write(matchData.room.isWanted); + body.Write(matchData.room.Squad); + body.Write(matchData.room.SquadCounter); + + Say(new MsgReference(470, body, client, sendType, matchData.channel, matchData)); + + if (debugSend) + { + if (sendType == SendType.Unicast) + Debug.Log("SendRoom to: " + client.GetIdentifier()); + + else + Debug.Log("Broadcasted SendRoom for room no: " + matchData.room.No); + } + + } + + public void SendDeleteRoom(MatchData matchData, ChannelReference channel) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("Broadcasted SendLoadComplete for: " + client.GetIdentifier()); - } + body.Write(matchData.room.No); - public void SendMatchCountdown() - { - MsgBody body = new MsgBody(); + Say(new MsgReference(6, body, null, SendType.BroadcastChannel, channel, matchData)); - body.Write(matchData.countdownTime); - Say(new MsgReference(72, body, null, SendType.BroadcastRoom)); + if (debugSend) + Debug.Log("Broadcasted SendDelRoom for room no: " + matchData.room.No); + } - if (debugSend) - Debug.Log("Broadcasted SendMatchCountdown for: " + matchData.countdownTime); - } + public void SendRoomList(ClientReference client) + { + MsgBody body = new MsgBody(); + + if (client.channel == null) + body.Write(0); //count + else + { + body.Write(client.channel.matches.Count); //count + for (int i = 0; i < client.channel.matches.Count; i++) + { + MatchData matchData = client.channel.matches[i]; + body.Write(matchData.room.No); + body.Write((int)matchData.room.Type); + body.Write(matchData.room.Title); + body.Write(matchData.room.Locked); + body.Write((int)matchData.room.Status); + body.Write(matchData.room.CurPlayer); + body.Write(matchData.room.MaxPlayer); + body.Write(matchData.room.map); + body.Write(matchData.room.CurMapAlias); + body.Write(matchData.room.goal); + body.Write(matchData.room.timelimit); + body.Write(matchData.room.weaponOption); + body.Write(matchData.room.ping); + body.Write(matchData.room.score1); + body.Write(matchData.room.score2); + body.Write(matchData.room.CountryFilter); + body.Write(matchData.room.isBreakInto); + body.Write(matchData.room.isDropItem); + body.Write(matchData.room.isWanted); + body.Write(matchData.room.Squad); + body.Write(matchData.room.SquadCounter); + } + } + + Say(new MsgReference(468, body, client)); + + if (debugSend) + Debug.Log("SendRoomList to: " + client.GetIdentifier()); + } + + public void SendCreateRoom(ClientReference client, bool success = true) + { + MatchData matchData = client.matchData; - public void SendTimer(ClientReference client) - { - MsgBody body = new MsgBody(); + MsgBody body = new MsgBody(); - body.Write(matchData.remainTime); - body.Write(matchData.playTime); - Say(new MsgReference(66, body, client, SendType.BroadcastRoom)); + body.Write((int)matchData.room.Type); + body.Write(success ? matchData.room.No : -1); + body.Write(matchData.room.Title); - if (debugSend) - Debug.Log("SendTimer to: " + client.GetIdentifier()); - } + Say(new MsgReference(8, body, client)); - public void SendRendezvousInfo(ClientReference client) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendCreateRoom to: " + client.GetIdentifier()); + } - body.Write(0); //unused - body.Write(client.ip); - body.Write(client.port); + public void SendJoin(ClientReference client) + { + MatchData matchData = client.matchData; + MsgBody body = new MsgBody(); - Say(new MsgReference(320, body, client)); + body.Write(matchData.room.No); + Say(new MsgReference(29, body, client)); - if (debugSend) - Debug.Log("SendRendezvousInfo to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("SendJoin to: " + client.GetIdentifier()); + } - public void SendPlayerInitInfo(ClientReference client) - { - MsgBody body = new MsgBody(); + public void SendBreakInto(ClientReference client, int reply) + { + MsgBody body = new MsgBody(); - body.Write(client.data.xp); - body.Write(client.data.tutorialed); - body.Write(client.data.countryFilter); - body.Write(client.data.tos); - body.Write(client.data.extraSlots); - body.Write(client.data.rank); - body.Write(client.data.firstLoginFp); - Say(new MsgReference(148, body, client)); + body.Write(reply); - if (debugSend) - Debug.Log("SendPlayerInitInfo to: " + client.GetIdentifier()); - } + Say(new MsgReference(74, body, client)); - public void SendChannels(ClientReference client, Channel[] channels) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendBreakInto to: " + client.GetIdentifier()); + } - body.Write(channels.Length); + public void SendEnter(ClientReference client) + { + MatchData matchData = client.matchData; + + MsgBody body = new MsgBody(); + + body.Write(client.slot.slotIndex); + body.Write(client.seq); + body.Write(client.name); + body.Write(client.ip); + body.Write(client.port); //port + body.Write(client.ip); + body.Write(client.port); //remotePort + body.Write(client.inventory.equipmentString.Length); + for (int i = 0; i < client.inventory.equipmentString.Length; i++) + { + body.Write(client.inventory.equipmentString[i]); + } + body.Write((int)client.status); + body.Write(client.data.xp); + body.Write(client.data.clanSeq); + body.Write(client.data.clanName); + body.Write(client.data.clanMark); + body.Write(client.data.rank); + body.Write((byte)1); //playerflag + body.Write(client.inventory.weaponChgString.Length); + for (int i = 0; i < client.inventory.weaponChgString.Length; i++) + { + body.Write(client.inventory.weaponChgString[i]); + } + body.Write(0); //drpItem count + + Say(new MsgReference(10, body, client, SendType.BroadcastRoomExclusive, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendEnter for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } + + public void SendLeave(ClientReference client) + { + MatchData matchData = client.matchData; + + MsgBody body = new MsgBody(); + + body.Write(client.seq); + + Say(new MsgReference(11, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendLeave for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } + + public void SendSlotData(MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.clientList.Count); + for (int i = 0; i < matchData.clientList.Count; i++) + { + ClientReference client = matchData.clientList[i]; + body.Write(client.slot.slotIndex); + body.Write(client.seq); + body.Write(client.name); + body.Write(client.ip); + body.Write(client.port); //port + body.Write(client.ip); + body.Write(client.port); //remotePort + body.Write(client.inventory.equipmentString.Length); + for (int j = 0; j < client.inventory.equipmentString.Length; j++) + { + body.Write(client.inventory.equipmentString[j]); + } + body.Write((int)client.status); + body.Write(client.data.xp); + body.Write(client.data.clanSeq); + body.Write(client.data.clanName); + body.Write(client.data.clanMark); + body.Write(client.data.rank); + body.Write((byte)1); //playerflag + body.Write(client.inventory.weaponChgString.Length); + for (int j = 0; j < client.inventory.weaponChgString.Length; j++) + { + body.Write(client.inventory.weaponChgString[j]); + } + body.Write(0); //drpItem count + } + + Say(new MsgReference(ExtensionOpcodes.opSlotDataAck, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + Say(new MsgReference(ExtensionOpcodes.opSlotDataAck, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendSlotData for room no: " + matchData.room.No); + } + + public void SendTeamChange(ClientReference client) + { + MatchData matchData = client.matchData; + + MsgBody body = new MsgBody(); + + body.Write(client.seq); + body.Write(0); //unused + body.Write(client.slot.slotIndex); + + Say(new MsgReference(81, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendTeamChange for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } + + public void SendSetStatus(ClientReference client) + { + MatchData matchData = client.matchData; + + MsgBody body = new MsgBody(); + + body.Write(client.seq); + body.Write((int)client.status); + + Say(new MsgReference(48, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendSetStatus for client " + client.GetIdentifier() + " for room no: " + matchData.room.No); + } + + public void SendStart(MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.lobbyCountdownTime); + + Say(new MsgReference(50, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendStart for room no: " + matchData.room.No); + } + + public void SendPostLoadInit(ClientReference client) + { + MsgBody body = new MsgBody(); + + Say(new MsgReference(ExtensionOpcodes.opPostLoadInitAck, body, client)); + + if (debugSend) + Debug.Log("SendPostLoadInit to: " + client.GetIdentifier()); + } + + public void SendLoadComplete(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.seq); + Say(new MsgReference(43, body, null, SendType.BroadcastRoom, client.channel, client.matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendLoadComplete for: " + client.GetIdentifier()); + } + + public void SendMatchCountdown(MatchData matchData) + { + MsgBody body = new MsgBody(); + + body.Write(matchData.countdownTime); + Say(new MsgReference(72, body, null, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("Broadcasted SendMatchCountdown for: " + matchData.countdownTime); + } + + public void SendTimer(ClientReference client) + { + MatchData matchData = client.matchData; + + MsgBody body = new MsgBody(); + + body.Write(matchData.remainTime); + body.Write(matchData.playTime); + Say(new MsgReference(66, body, client, SendType.BroadcastRoom, matchData.channel, matchData)); + + if (debugSend) + Debug.Log("SendTimer to: " + client.GetIdentifier()); + } + + public void SendRendezvousInfo(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(0); //unused + body.Write(client.ip); + body.Write(client.port); + + Say(new MsgReference(320, body, client)); + + if (debugSend) + Debug.Log("SendRendezvousInfo to: " + client.GetIdentifier()); + } + + public void SendPlayerInitInfo(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.data.xp); + body.Write(client.data.tutorialed); + body.Write(client.data.countryFilter); + body.Write(client.data.tos); + body.Write(client.data.extraSlots); + body.Write(client.data.rank); + body.Write(client.data.firstLoginFp); + Say(new MsgReference(148, body, client)); + + if (debugSend) + Debug.Log("SendPlayerInitInfo to: " + client.GetIdentifier()); + } + + public void SendChannels(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(channelManager.channels.Count); + foreach (ChannelReference channelRef in channelManager.channels) + { + body.Write(channelRef.channel.Id); + body.Write(channelRef.channel.Mode); + body.Write(channelRef.channel.Name); + body.Write(channelRef.channel.Ip); + body.Write(channelRef.channel.Port); + body.Write(channelRef.channel.UserCount); + body.Write(channelRef.channel.MaxUserCount); + body.Write(channelRef.channel.Country); + body.Write((byte)channelRef.channel.MinLvRank); + body.Write((byte)channelRef.channel.MaxLvRank); + body.Write((ushort)channelRef.channel.XpBonus); + body.Write((ushort)channelRef.channel.FpBonus); + body.Write(channelRef.channel.LimitStarRate); + } + + /*body.Write(channels.Length); for (int i = 0; i < channels.Length; i++) { body.Write(channels[i].Id); @@ -2525,73 +3550,73 @@ public void SendChannels(ClientReference client, Channel[] channels) body.Write((ushort)channels[i].XpBonus); body.Write((ushort)channels[i].FpBonus); body.Write(channels[i].LimitStarRate); - } - Say(new MsgReference(141, body, client)); - - if (debugSend) - Debug.Log("SendChannels to: " + client.GetIdentifier()); - } - - public void SendCurChannel(ClientReference client, int curChannelId = 1) - { - MsgBody body = new MsgBody(); - - body.Write(curChannelId); - Say(new MsgReference(147, body, client)); - - if (debugSend) - Debug.Log("SendCurChannel to: " + client.GetIdentifier()); - } - - public void SendLogin(ClientReference client, int loginChannelId = 1) - { - MsgBody body = new MsgBody(); - - body.Write(client.seq); - body.Write(loginChannelId); - Say(new MsgReference(2, body, client)); - - if (debugSend) - Debug.Log("SendLogin to: " + client.GetIdentifier()); - } - - public void SendPlayerInfo(ClientReference client) - { - MsgBody body = new MsgBody(); - - body.Write(client.name); - body.Write(client.data.xp); - body.Write(client.data.forcePoints); - body.Write(client.data.brickPoints); - body.Write(client.data.tokens); - body.Write(0); - body.Write(client.data.coins); - body.Write(client.data.starDust); - body.Write(6); - body.Write(5); - body.Write(client.data.gm); - body.Write(client.data.clanSeq); - body.Write(client.data.clanName); - body.Write(client.data.clanLv); - body.Write(client.data.rank); - body.Write(client.data.heavy); - body.Write(client.data.assault); - body.Write(client.data.sniper); - body.Write(client.data.subMachine); - body.Write(client.data.handGun); - body.Write(client.data.melee); - body.Write(client.data.special); - Say(new MsgReference(27, body, client)); - - if (debugSend) - Debug.Log("SendPlayerInfo to: " + client.GetIdentifier()); - } - - public void SendItemList(ClientReference client) - { - MsgBody body = new MsgBody(); - - /*body.Write(client.inventory.equipment.Count); + }*/ + Say(new MsgReference(141, body, client)); + + if (debugSend) + Debug.Log("SendChannels to: " + client.GetIdentifier()); + } + + public void SendCurChannel(ClientReference client, int curChannelId = 1) + { + MsgBody body = new MsgBody(); + + body.Write(curChannelId); + Say(new MsgReference(147, body, client)); + + if (debugSend) + Debug.Log("SendCurChannel to: " + client.GetIdentifier()); + } + + public void SendLogin(ClientReference client, int loginChannelId = 1) + { + MsgBody body = new MsgBody(); + + body.Write(client.seq); + body.Write(loginChannelId); + Say(new MsgReference(2, body, client)); + + if (debugSend) + Debug.Log("SendLogin to: " + client.GetIdentifier()); + } + + public void SendPlayerInfo(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.name); + body.Write(client.data.xp); + body.Write(client.data.forcePoints); + body.Write(client.data.brickPoints); + body.Write(client.data.tokens); + body.Write(0); + body.Write(client.data.coins); + body.Write(client.data.starDust); + body.Write(6); + body.Write(5); + body.Write(client.data.gm); + body.Write(client.data.clanSeq); + body.Write(client.data.clanName); + body.Write(client.data.clanLv); + body.Write(client.data.rank); + body.Write(client.data.heavy); + body.Write(client.data.assault); + body.Write(client.data.sniper); + body.Write(client.data.subMachine); + body.Write(client.data.handGun); + body.Write(client.data.melee); + body.Write(client.data.special); + Say(new MsgReference(27, body, client)); + + if (debugSend) + Debug.Log("SendPlayerInfo to: " + client.GetIdentifier()); + } + + public void SendItemList(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(client.inventory.equipment.Count); for (int i = 0; i < client.inventory.equipment.Count; i++) { body.Write(client.inventory.equipment[i].Seq); @@ -2600,117 +3625,967 @@ public void SendItemList(ClientReference client) body.Write(client.inventory.equipment[i].Amount); body.Write(client.inventory.equipment[i].IsPremium); body.Write(client.inventory.equipment[i].Durability); - }*/ + } - Say(new MsgReference(464, body, client)); + Say(new MsgReference(464, body, client)); - if (debugSend) - Debug.Log("SendItemList to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("SendItemList to: " + client.GetIdentifier()); + } - public void SendUserList(ClientReference client, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + public void SendUserList(ClientReference client, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - body.Write(clientList.Count); - for (int i = 0; i < clientList.Count; i++) - { - body.Write(clientList[i].seq); - body.Write(clientList[i].name); - body.Write(clientList[i].data.xp); - body.Write(clientList[i].data.rank); + body.Write(client.channel.clientList.Count); + for (int i = 0; i < client.channel.clientList.Count; i++) + { + body.Write(client.channel.clientList[i].seq); + body.Write(client.channel.clientList[i].name); + body.Write(client.channel.clientList[i].data.xp); + body.Write(client.channel.clientList[i].data.rank); - } - Say(new MsgReference(467, body, client, sendType)); + } + Say(new MsgReference(467, body, client, sendType)); - if (debugPing) - Debug.Log("SendUserList to: " + client.GetIdentifier()); - } + if (debugPing) + Debug.Log("SendUserList to: " + client.GetIdentifier()); + } - public void SendRoamin(ClientReference client, SendType sendType = SendType.Unicast) - { - MsgBody body = new MsgBody(); + public void SendRoamout(ClientReference client, int src, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - body.Write(1); - Say(new MsgReference(146, body, client, sendType)); + body.Write(src); + Say(new MsgReference(144, body, client, sendType)); - if (debugSend) - Debug.Log("SendRoamin to: " + client.GetIdentifier()); - } + if (debugSend) + Debug.Log("SendRoamout to: " + client.GetIdentifier()); + } - public void SendConnected(ClientReference client) - { - MsgBody body = new MsgBody(); - Say(new MsgReference(ExtensionOpcodes.opConnectedAck, body, client)); + public void SendRoamin(ClientReference client, int dest, SendType sendType = SendType.Unicast) + { + MsgBody body = new MsgBody(); - if (debugSend) - Debug.Log("SendConnected to: " + client.GetIdentifier()); - } + body.Write(dest); + Say(new MsgReference(146, body, client, sendType)); - public void SendDownloadedMaps(ClientReference client, int offset = 0) - { - MsgBody body = new MsgBody(); + if (debugSend) + Debug.Log("SendRoamin to: " + client.GetIdentifier()); + } - body.Write(Mathf.FloorToInt(offset / 100f)); //page - body.Write(regMaps.Count - offset > 100 ? 100 : regMaps.Count); - int i; - bool recursiveFlag = false; - for (i = offset; i < regMaps.Count; i++) - { - KeyValuePair entry = regMaps[i]; - body.Write(entry.Value.Map); - body.Write(entry.Value.Developer); - body.Write(entry.Value.Alias); - body.Write(entry.Value.ModeMask); - body.Write((byte)(Room.clanMatch | Room.official)); - body.Write(entry.Value.tagMask); - body.Write(entry.Value.RegisteredDate.Year); - body.Write((sbyte)entry.Value.RegisteredDate.Month); - body.Write((sbyte)entry.Value.RegisteredDate.Day); - body.Write((sbyte)entry.Value.RegisteredDate.Hour); - body.Write((sbyte)entry.Value.RegisteredDate.Minute); - body.Write((sbyte)entry.Value.RegisteredDate.Second); - body.Write(entry.Value.DownloadFee); - body.Write(entry.Value.Release); - body.Write(entry.Value.LatestRelease); - body.Write(entry.Value.Likes); - body.Write(entry.Value.DisLikes); - body.Write(entry.Value.DownloadCount); - - if (i - offset == 100) - { - recursiveFlag = true; - break; - } - } - Say(new MsgReference(426, body, client)); + public void SendConnected(ClientReference client) + { + MsgBody body = new MsgBody(); + Say(new MsgReference(ExtensionOpcodes.opConnectedAck, body, client)); + + if (debugSend) + Debug.Log("SendConnected to: " + client.GetIdentifier()); + } + + public void SendAllDownloadedMaps(ClientReference client) + { + int chunkSize = 100; + int chunkCount = Mathf.CeilToInt((float)regMaps.Count / (float)chunkSize); + int processedCount = 0; + + for (int chunk = 0; chunk < chunkCount; chunk++) + { + int remaining = regMaps.Count - processedCount; + if (remaining < chunkSize) + chunkSize = remaining; + + MsgBody body = new MsgBody(); + + body.Write(-1); //page + body.Write(chunkSize); //count + for (int i = 0; i < chunkSize; i++, processedCount++) + { + KeyValuePair entry = regMaps[processedCount]; + body.Write(entry.Value.Map); + body.Write(entry.Value.Developer); + body.Write(entry.Value.Alias); + body.Write(entry.Value.ModeMask); + body.Write((byte)(Room.clanMatch | Room.official)); + body.Write(entry.Value.tagMask); + body.Write(entry.Value.RegisteredDate.Year); + body.Write((sbyte)entry.Value.RegisteredDate.Month); + body.Write((sbyte)entry.Value.RegisteredDate.Day); + body.Write((sbyte)entry.Value.RegisteredDate.Hour); + body.Write((sbyte)entry.Value.RegisteredDate.Minute); + body.Write((sbyte)entry.Value.RegisteredDate.Second); + body.Write(entry.Value.DownloadFee); + body.Write(entry.Value.Release); + body.Write(entry.Value.LatestRelease); + body.Write(entry.Value.Likes); + body.Write(entry.Value.DisLikes); + body.Write(entry.Value.DownloadCount); + } + + Say(new MsgReference(426, body, client)); + } + + if (debugSend) + Debug.Log("SendAllDownloadedMaps to: " + client.GetIdentifier()); + } + + public void SendAllUserMaps(ClientReference client) + { + MsgBody body = new MsgBody(); + + int chunkSize = 200; + int chunkCount = Mathf.CeilToInt((float)regMaps.Count / (float)chunkSize); + int processedCount = 0; + Debug.LogWarning("RegMapCount: " + regMaps.Count); + + for (int chunk = 0; chunk < chunkCount; chunk++) + { + int remaining = regMaps.Count - processedCount; + if (remaining < chunkSize) + chunkSize = remaining; + + body.Write(-1); //page + body.Write(chunkSize); //count + for (int i = 0; i < chunkSize; i++, processedCount++) + { + KeyValuePair entry = regMaps[processedCount]; + body.Write(entry.Key); //slot + body.Write(entry.Value.Alias); + body.Write(-1); //brick count + body.Write(entry.Value.RegisteredDate.Year); + body.Write((sbyte)entry.Value.RegisteredDate.Month); + body.Write((sbyte)entry.Value.RegisteredDate.Day); + body.Write((sbyte)entry.Value.RegisteredDate.Hour); + body.Write((sbyte)entry.Value.RegisteredDate.Minute); + body.Write((sbyte)entry.Value.RegisteredDate.Second); + body.Write((sbyte)0); + } + Say(new MsgReference(430, body, client)); + } + + if (debugSend) + Debug.Log("SendAllUserMaps to: " + client.GetIdentifier()); + } + + public void SendEmptyUserMap(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(-1); //page + body.Write(1); //count + body.Write(0); //slot + body.Write(""); + body.Write(-1); //brick count + body.Write(2000); + body.Write((sbyte)0); + body.Write((sbyte)0); + body.Write((sbyte)0); + body.Write((sbyte)0); + body.Write((sbyte)0); + body.Write((sbyte)0); + + Say(new MsgReference(430, body, client)); + + if (debugSend) + Debug.Log("SendEmptyUserMap to: " + client.GetIdentifier()); + } + + public void SendDownloadedMaps(ClientReference client, int page) + { + MsgBody body = new MsgBody(); + + const int mapsPerPage = 12; + int offset = page * mapsPerPage; + int remaining = regMaps.Count - offset; + int count = remaining < mapsPerPage ? remaining : mapsPerPage; + + body.Write(page); //page + body.Write(count); //count + for (int i = offset; i < offset + count; i++) + { + KeyValuePair entry = regMaps[i]; + body.Write(entry.Value.Map); + body.Write(entry.Value.Developer); + body.Write(entry.Value.Alias); + body.Write(entry.Value.ModeMask); + body.Write((byte)(Room.clanMatch | Room.official)); + body.Write(entry.Value.tagMask); + body.Write(entry.Value.RegisteredDate.Year); + body.Write((sbyte)entry.Value.RegisteredDate.Month); + body.Write((sbyte)entry.Value.RegisteredDate.Day); + body.Write((sbyte)entry.Value.RegisteredDate.Hour); + body.Write((sbyte)entry.Value.RegisteredDate.Minute); + body.Write((sbyte)entry.Value.RegisteredDate.Second); + body.Write(entry.Value.DownloadFee); + body.Write(entry.Value.Release); + body.Write(entry.Value.LatestRelease); + body.Write(entry.Value.Likes); + body.Write(entry.Value.DisLikes); + body.Write(entry.Value.DownloadCount); + } + Say(new MsgReference(426, body, client)); + + if (debugSend) + Debug.Log("SendDownloadedMaps to: " + client.GetIdentifier()); + } + + public void SendRegisteredMaps(ClientReference client, int page) + { + MsgBody body = new MsgBody(); + + const int mapsPerPage = 12; + int offset = page * mapsPerPage; + int remaining = regMaps.Count - offset; + int count = remaining < mapsPerPage ? remaining : mapsPerPage; + + body.Write(page); //page + body.Write(count); //count + for (int i = offset; i < offset + count; i++) + { + KeyValuePair entry = regMaps[i]; + body.Write(entry.Value.Map); + body.Write(entry.Value.Developer); + body.Write(entry.Value.Alias); + body.Write(entry.Value.ModeMask); + body.Write((byte)(Room.clanMatch | Room.official)); + body.Write(entry.Value.tagMask); + body.Write(entry.Value.RegisteredDate.Year); + body.Write((sbyte)entry.Value.RegisteredDate.Month); + body.Write((sbyte)entry.Value.RegisteredDate.Day); + body.Write((sbyte)entry.Value.RegisteredDate.Hour); + body.Write((sbyte)entry.Value.RegisteredDate.Minute); + body.Write((sbyte)entry.Value.RegisteredDate.Second); + body.Write(entry.Value.DownloadFee); + body.Write(entry.Value.Release); + body.Write(entry.Value.LatestRelease); + body.Write(entry.Value.Likes); + body.Write(entry.Value.DisLikes); + body.Write(entry.Value.DownloadCount); + } + Say(new MsgReference(428, body, client)); + + if (debugSend) + Debug.Log("SendRegisteredMaps to: " + client.GetIdentifier()); + } + + public void SendUserMaps(ClientReference client, int page) + { + MsgBody body = new MsgBody(); + + const int mapsPerPage = 12; + int offset = page * mapsPerPage; + int remaining = regMaps.Count - offset; + int count = remaining < mapsPerPage ? remaining : mapsPerPage; + + body.Write(page); //page + body.Write(count); //count + for (int i = offset; i < offset + count; i++) + { + KeyValuePair entry = regMaps[i]; + body.Write(entry.Key); //slot + body.Write(entry.Value.Alias); + body.Write(10000); //brick count + body.Write(entry.Value.RegisteredDate.Year); + body.Write((sbyte)entry.Value.RegisteredDate.Month); + body.Write((sbyte)entry.Value.RegisteredDate.Day); + body.Write((sbyte)entry.Value.RegisteredDate.Hour); + body.Write((sbyte)entry.Value.RegisteredDate.Minute); + body.Write((sbyte)entry.Value.RegisteredDate.Second); + body.Write((sbyte)0); + } + Say(new MsgReference(430, body, client)); + + if (debugSend) + Debug.Log("SendUserMaps to: " + client.GetIdentifier()); + } + + public void SendCustomMessage(string message, ClientReference client = null, SendType sendType = SendType.Broadcast) + { + MsgBody body = new MsgBody(); + + body.Write(message); + + Say(new MsgReference(ExtensionOpcodes.opCustomMessageAck, body, client, sendType)); + } + + public void SendRespawnTicket(ClientReference client) + { + MsgBody body = new MsgBody(); + + body.Write(UnityEngine.Random.Range(1, 64)); + + Say(new MsgReference(64, body, client)); + + if (debugSend) + Debug.Log("SendRespawnTicket to: " + client.GetIdentifier()); + } + + private void HandleBeginChunkedBuffer(MsgReference msgRef) + { + msgRef.msg._msg.Read(out ushort opcode); + msgRef.msg._msg.Read(out int size); + msgRef.msg._msg.Read(out uint crc); + + if (debugHandle) + Debug.Log("HandleBeginChunkedBuffer from: " + msgRef.client.GetIdentifier()); + + const int maxBufferSize = 1000000000; + if (size > maxBufferSize) + { + Debug.LogWarning("ServerEmulator.HandleBeginChunkedBuffer: Buffer was " + size + " bytes"); + return; + } + + if (msgRef.client.chunkedBuffer == null) + { + msgRef.client.chunkedBuffer = new ChunkedBuffer((uint)size, crc, opcode); + } + + else + { + Debug.LogWarning("ServerEmulator.HandleBeginChunkedBuffer: ChunkedBuffer with id " + msgRef.client.chunkedBuffer.id + " is already assigned"); + return; + } + } + + private void HandleChunkedBuffer(MsgReference msgRef) + { + msgRef.msg._msg.Read(out ushort opcode); + msgRef.msg._msg.Read(out int chunk); + msgRef.msg._msg.Read(out byte[] next); + + if (msgRef.client.chunkedBuffer != null && msgRef.client.chunkedBuffer.id == opcode) + { + msgRef.client.chunkedBuffer.WriteNext(next, chunk); + } + } + + private void HandleEndChunkedBuffer(MsgReference msgRef) + { + + if (debugHandle) + Debug.Log("HandleEndChunkedBuffer from: " + msgRef.client.GetIdentifier()); - if (recursiveFlag) - SendDownloadedMaps(client, i); + msgRef.msg._msg.Read(out ushort opcode); - if (debugSend) - Debug.Log("SendDownloadedMaps to: " + client.GetIdentifier()); - } + if (msgRef.client.chunkedBuffer != null) + { + msgRef.client.chunkedBuffer.finished = true; + uint crc = CRC32.computeUnsigned(msgRef.client.chunkedBuffer.buffer); + if (crc != (msgRef.client.chunkedBuffer.crc)) + { + Debug.LogError("HandleEndChunkedBuffer: crc mismatch"); + } - public void SendCustomMessage(string message, ClientReference client = null, SendType sendType = SendType.Broadcast) - { - MsgBody body = new MsgBody(); + File.WriteAllBytes("test.png", msgRef.client.chunkedBuffer.buffer); + } + } - body.Write(message); + private void HandlePickFlagRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + msgRef.msg._msg.Read(out int flag); + if (debugHandle) + Debug.Log("HandlePickFlag from: " + msgRef.client.GetIdentifier() + " FlagId: " + flag); + MsgBody msg = new MsgBody(); + // i think the response needs to be the plaxer seq which picked up the flag + + msg.Write(msgRef.client.seq); + Say(new MsgReference(286, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleDropFlagRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + msgRef.msg._msg.Read(out int x); + msgRef.msg._msg.Read(out int y); + msgRef.msg._msg.Read(out int z); + if (debugHandle) + Debug.Log("HandleFlagDrop from: " + msgRef.client.GetIdentifier() + " Flag: x: " + x + " y: " + y + " z: " + z); + MsgBody msg = new MsgBody(); + msg.Write(0); //unused + msg.Write(0); // unused + msg.Write(x); + msg.Write(y); + msg.Write(z); + + Say(new MsgReference(290, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleCaptureFlagRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + msgRef.msg._msg.Read(out int flag); + msgRef.msg._msg.Read(out bool opponent); + if (msgRef.client.slot.slotIndex > 7) + { + data.blueScore++; + } + else + { + data.redScore++; + } + SendTeamScore(data); + data.ResetForNewRound(); + if (debugHandle) + Debug.Log("HandleCaptureFlag from: " + msgRef.client.GetIdentifier() + " FlagId: " + flag + " IsOpponent: " + opponent); + MsgBody msg = new MsgBody(); + msg.Write(msgRef.client.seq); // Player sequence + //Round only starts for one player (oponent?) + + Say(new MsgReference(288, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleCTFScoreRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + msg.Write(data.redScore); // red score + msg.Write(data.blueScore); // blue score + if (debugHandle) + Debug.Log("HandleCTFScoreReq from: " + msgRef.client.GetIdentifier() + " RedScore: " + data.redScore + " BluScore: " + data.blueScore); + + Say(new MsgReference(296, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleFlagReturnRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + msgRef.msg._msg.Read(out float x); + msgRef.msg._msg.Read(out float y); + msgRef.msg._msg.Read(out float z); + if (debugHandle) + Debug.Log("HandleFlagReturn from: " + msgRef.client.GetIdentifier() + " Flag: x: " + x + " y: " + y + " z: " + z); + MsgBody msg = new MsgBody(); + + Say(new MsgReference(367, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleGetBack2SpawnerRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + Say(new MsgReference(263, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } - Say(new MsgReference(ExtensionOpcodes.opCustomMessageAck, body, client, sendType)); - } + private void HandleMatchRestartCountRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int count); + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + msg.Write(count); + Say(new MsgReference(265, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleMatchRestartRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + Say(new MsgReference(267, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } - public void SendRespawnTicket(ClientReference client) - { - MsgBody body = new MsgBody(); + private void HandleLineBrickRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out long item); + msgRef.msg._msg.Read(out string code); + msgRef.msg._msg.Read(out byte brick); + msgRef.msg._msg.Read(out byte x); + msgRef.msg._msg.Read(out byte y); + msgRef.msg._msg.Read(out byte z); + msgRef.msg._msg.Read(out byte rot); + + //Line Brick Success 326 + /*MyInfoManager.Instance.IsModified = true; + Brick brick = BrickManager.Instance.GetBrick(val3); + if (brick != null) + { + BrickManager.Instance.AddBrickCreator(val2, val3, new Vector3((float)(int)val4, (float)(int)val5, (float)(int)val6), val7); + } + if (val == MyInfoManager.Instance.Seq) + { + ((LineToolDialog)DialogManager.Instance.GetDialog(DialogManager.DIALOG_INDEX.LINE_TOOL))?.MoveNext(success: true); + }*/ + //Line Brick Fail 330 + /*msg.Read(out int val); + ShowBuildErrorMessage(val); + ((LineToolDialog)DialogManager.Instance.GetDialog(DialogManager.DIALOG_INDEX.LINE_TOOL))?.MoveNext(success: false);*/ + } + + private void HandleReplaceBrickRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out long item); + msgRef.msg._msg.Read(out string code); + msgRef.msg._msg.Read(out int existing); + msgRef.msg._msg.Read(out byte brick); + msgRef.msg._msg.Read(out byte x); + msgRef.msg._msg.Read(out byte y); + msgRef.msg._msg.Read(out byte z); + msgRef.msg._msg.Read(out byte rot); + //Replace Brick Success 328 + /*MyInfoManager.Instance.IsModified = true; + BrickManager.Instance.DelBrick(val2, shrink: true); + Brick brick = BrickManager.Instance.GetBrick(val4); + if (brick != null) + { + BrickManager.Instance.AddBrickCreator(val3, val4, new Vector3((float)(int)val5, (float)(int)val6, (float)(int)val7), val8); + } + if (val == MyInfoManager.Instance.Seq) + { + ((ReplaceToolDialog)DialogManager.Instance.GetDialog(DialogManager.DIALOG_INDEX.REPLACE_TOOL))?.MoveNext(success: true); + }*/ + //Replace Brick Fail 331 + /*msg.Read(out int val); + ShowBuildErrorMessage(val); + ((ReplaceToolDialog)DialogManager.Instance.GetDialog(DialogManager.DIALOG_INDEX.REPLACE_TOOL))?.MoveNext(success: false);*/ + } + + private void HandleZombieInfectionRequest(MsgReference msgRef) + { + MatchData data = msgRef.matchData; + //Debug.LogWarning("InfectionRequest current status: " + data.zombieStatus); + + if (data.roundInit) + { + int numPlayers = data.clientList.Count; + int numZombies; + + if (numPlayers <= 4) + { + numZombies = 1; + } + else if (numPlayers <= 10) + { + numZombies = 2; + } + else if (numPlayers <= 15) + { + numZombies = 3; + } + else + { + numZombies = 4; + } + + // Clone the client list to select randomly + List shuffledClients = new List(data.clientList); + + // Shuffle the list to ensure randomness + for (int i = 0; i < shuffledClients.Count; i++) + { + int randomIndex = UnityEngine.Random.Range(i, shuffledClients.Count); + + // Manually swap elements + var temp = shuffledClients[i]; + shuffledClients[i] = shuffledClients[randomIndex]; + shuffledClients[randomIndex] = temp; + } + + // Select the first `numZombies` clients as zombies + data.zombiePlayers.Clear(); + for (int i = 0; i < numZombies; i++) + { + data.clientList.Find(x => x.seq == shuffledClients[i].seq).isZombie = true; + data.zombiePlayers.Add(shuffledClients[i].seq); + } + + // Add the remaining clients to the human players list + data.humanPlayers.Clear(); + for (int i = numZombies; i < shuffledClients.Count; i++) + { + data.humanPlayers.Add(shuffledClients[i].seq); + } + + // Mark the round as initialized + data.roundInit = false; + + if (debugSend) + { + Debug.Log($"Initialized round: {numZombies} zombies and {data.humanPlayers.Count} humans."); + } + } + + // Create a new message body for the response + MsgBody msg = new MsgBody(); + + // Add human IDs + msg.Write(data.humanPlayers.Count); // Write the count of humans + foreach (int humanId in data.humanPlayers) + { + msg.Write(humanId); // Write each human player ID + } + + // Add zombie IDs + msg.Write(data.zombiePlayers.Count); // Write the count of zombies + foreach (int zombieId in data.zombiePlayers) + { + msg.Write(zombieId); // Write each zombie player ID + } + + // Add IDs of players who died (killed) + msg.Write(data.killedPlayers.Count); // Write the count of killed players + foreach (int killedId in data.killedPlayers) + { + msg.Write(killedId); // Write each killed player ID + } + + // Add IDs of players who became infected (turned into zombies) + msg.Write(data.infectedPlayers.Count); // Write the count of infected players + foreach (int infectedId in data.infectedPlayers) + { + msg.Write(infectedId); // Write each infected player ID + } + + // Broadcast the response to all players in the room + Say(new MsgReference(539, msg, null, SendType.BroadcastRoom, data.channel, data)); + + if (debugSend) + { + Debug.Log("Zombie infection state updated and broadcasted."); + } + } + + private void HandleZombieInfectRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int brickMan); + msgRef.msg._msg.Read(out int zombie); + + MatchData data = msgRef.matchData; + // Update human and zombie player lists + if (data.humanPlayers.Contains(brickMan)) + { + data.humanPlayers.Remove(brickMan); + data.zombiePlayers.Add(brickMan); + ClientReference client = data.clientList[zombie]; + client.kills += 1; + } + + if (data.humanPlayers.Count == 0) + { + SendRoundEnd(msgRef, data); + } + + MsgBody msg = new MsgBody(); + msg.Write(brickMan); // Infected player + msg.Write(zombie); // Infecting player + Say(new MsgReference(541, msg, null, SendType.BroadcastRoom, data.channel, data)); + + if (debugSend) + { + Debug.Log($"Zombie Infection: {zombie} infected {brickMan}. Remaining humans: {data.humanPlayers.Count}, Remaining Zombies: {data.zombiePlayers.Count}"); + } + } + + private void HandleZombieScoreRequest(MsgReference msgRef) + { + // Ensure debug logging is only performed if debugSend is enabled + if (debugSend) + { + Debug.Log($"Zombie Score Request: Total Rounds: {msgRef.matchData.room.goal}, " + + $"Current Round: {msgRef.matchData.zombieCurrentRound}"); + } + + // Prepare the message body with total rounds and current round + MsgBody msg = new MsgBody(); + msg.Write(msgRef.matchData.room.goal); // Total rounds + msg.Write(msgRef.matchData.zombieCurrentRound); // Current round + + // Send the message as a broadcast + Say(new MsgReference(536, msg, null, SendType.BroadcastRoom, msgRef.matchData.channel, msgRef.matchData)); + } + + private void SendRoundEnd(MsgReference msgRef, MatchData data) + { + Debug.LogWarning($"Send RoundEnd client {msgRef.client.GetIdentifier()} data: {data.ToString()}"); + + if (data.zombieCurrentRound >= data.room.goal) + { + data.EndMatch(); + return; + } + + MsgBody msg = new MsgBody(); + msg.Write(msgRef.client.seq); + if (data.humanPlayers.Count == 0) + { + //Zombies win + msg.Write((sbyte)-1); + msg.Write((sbyte)1); + } + else + { + //Humans win + msg.Write((sbyte)1); + msg.Write((sbyte)-1); + } + msg.Write((sbyte)data.zombieCurrentRound); + data.ResetForNewRound(); + data.zombieCurrentRound += 1; + data.zombieRoundsLeft -= 1; + + HandleZombieScoreRequest(msgRef); + + Say(new MsgReference(205, msg, null, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleZombieStatusRequest(MsgReference msgRef) + { + if (msgRef.client.seq != msgRef.matchData.masterSeq) + { + return; + } + msgRef.msg._msg.Read(out int status); + msgRef.msg._msg.Read(out int time); + msgRef.msg._msg.Read(out int countDown); + + MatchData data = msgRef.matchData; + MsgBody msg = new MsgBody(); + data.zombieStatus = (ZombieMatch.STEP)status; + + if (debugPing) + { + Debug.Log($"ZombieStatus: {status} Time: {time} Countdown: {countDown}"); + } + + switch ((ZombieMatch.STEP)status) + { + case ZombieMatch.STEP.WAITING: + Debug.Log("Waiting"); + data.zombieCountdown = 0; + //status = 1; + break; + case ZombieMatch.STEP.SET_POSITION: + // Countdown for setting positions + Debug.Log("SetPosition"); + if (countDown > 0) + { + data.zombieCountdown = countDown - 1; + } + else + { + data.zombieCountdown = 10; + //status = 2; + } + break; + case ZombieMatch.STEP.ZOMBIE: + Debug.Log("Zombie"); + break; + case ZombieMatch.STEP.ZOMBIE_PLAY: + Debug.Log("Zombie Play"); + /*if (data.humanPlayers.Count == 0 || data.zombiePlayers.Count == 0) + { + if (!data.roundInit) + { + SendRoundEnd(msgRef.client, data); + } + } + if (data.remainTime <= 0 && data.zombieRoundsLeft < 0) + { + data.EndMatch(); + return; + }*/ + //time = 0;\ + if (data.zombieCountdown != 10) + { + data.zombieCountdown = 10; + } + break; + default: + Debug.LogWarning("Unknown ZombieMatch.STEP received."); + break; + } + + msg.Write(status); + msg.Write(data.playTime); + msg.Write(data.zombieCountdown); + + Say(new MsgReference(548, msg, msgRef.client, SendType.BroadcastRoom, data.channel, data)); + } + + private void HandleZombieObserverRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); //MyInfoManager.Instance.Seq + /*MatchData data = msgRef.client.matchData; + data.zombiePlayers.Remove(seq); + data.killedPlayers.Add(seq); + if (debugSend) + { + Debug.LogWarning("ZombieObserver: Zombies:" + data.zombiePlayers.Count + " Humans: " + data.humanPlayers.Count); + } + if (data.zombiePlayers.Count == 0) + { + if (data.zombieRoundsLeft > 0) + { + SendRoundEnd(msgRef.client, data); + } + else + { + data.EndMatch(); + } + }*/ + // No Response + } + + private void HandleSaveMap(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int slot); + + MatchData matchData = msgRef.matchData; + + //Generate ModeMask by counting the special bricks + ushort modeMask = GenerateModeMask(matchData.cachedMap.dic); + + int hashId = slot; + DateTime time = DateTime.Now; + RegMap regMap = null; + + if (hashId == 0) + { + hashId = MapGenerator.instance.GetHashIdForTime(time); + //todo ModeMask + regMap = new RegMap(hashId, msgRef.client.name + "@Aurora", matchData.cachedUMI.Alias, time, modeMask, true, false, 0, 0, 0, 0, 0, 0, 0, false); + if (debugHandle) + Debug.Log("Generated new Hash"); + } else + { + regMap = RegMapManager.Instance.dicRegMap.FirstOrDefault(map => map.Value != null && map.Value.map == hashId).Value; + regMap.ModeMask = modeMask; + if (debugHandle) + Debug.Log("Saving Map: " + regMap.map); + } + + Texture2D thumbnail = new Texture2D(128, 128, TextureFormat.RGB24, mipmap: false); + + if (msgRef.client.chunkedBuffer.id == ExtensionOpcodes.opChunkedBufferThumbnailReq) + { + if (msgRef.client.chunkedBuffer.finished) + { + thumbnail.LoadImage(msgRef.client.chunkedBuffer.buffer); + thumbnail.Apply(); + if (debugSend) + Debug.Log("Load Thumbnail"); + } + else + Debug.LogError("HandleRegisterMapRequest: ChunkedBuffer not finished"); + } + regMap.Thumbnail = thumbnail; + if (slot == 0) + RegMapManager.Instance.Add(regMap); + else + RegMapManager.Instance.UpdateMap(regMap); + RegMapManager.Instance.SetThumbnail(regMap.map, thumbnail); + // It is important that we first add the thumbnail and regmap to the RegMapManager + // and then add the map to the User Info Manager + // Because when a new UserMap is created with a slot > 0 the regMap is retrieved from the RegMapManager + UserMapInfoManager.Instance.AddOrUpdate(hashId, regMap.Alias, matchData.cachedUMI.BrickCount, time, 0); + UserMapInfoManager.Instance.SetThumbnail(hashId, thumbnail); + + //Update MatchData + matchData.cachedMap.map = hashId; + matchData.cachedUMI.regMap = regMap; + matchData.cachedUMI.slot = hashId; + //Save Files + matchData.cachedUMI.regMap.Save(); + matchData.cachedMap.Save(hashId, matchData.cachedMap.skybox); + + // Reset chunkedBuffer to be able to recieve the next thumbnail + msgRef.client.chunkedBuffer = null; + + // Pull current map list into the emulator + regMaps = RegMapManager.Instance.dicRegMap.ToList(); + + // Answer the Request + MsgBody msgBody = new MsgBody(); + + msgBody.Write(hashId); + msgBody.Write(0); //success + + Say(new MsgReference(40, msgBody, msgRef.client, SendType.BroadcastRoom, matchData.channel, matchData)); + } + + private void HandleChangeEditorPermissionRequest(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int seq); + msgRef.msg._msg.Read(out bool isEditor); + + MatchData matchData = msgRef.matchData; + MsgBody msgBody = new MsgBody(); + + msgBody.Write(seq); + msgBody.Write(isEditor); + Say(new MsgReference(305, msgBody, msgRef.client, SendType.BroadcastRoom, matchData.channel, matchData)); + } + + private void HandleCommonOpt(MsgReference msgRef) + { + msgRef.msg._msg.Read(out int opt); + Debug.LogWarning("SaveCommonOpt: " + opt); + } + + public static ushort GenerateModeMask(Dictionary brickInstances) + { + ushort modeMask = 0; + // Count occurrences of each Template + var templateCounts = brickInstances + .GroupBy(brick => brick.Value.Template) + .ToDictionary(group => group.Key, group => group.Count()); + + // Retrieve counts for specific templates + int count23 = templateCounts.TryGetValue(23, out var c23) ? c23 : 0; + int count22 = templateCounts.TryGetValue(22, out var c22) ? c22 : 0; + int count24 = templateCounts.TryGetValue(24, out var c24) ? c24 : 0; + int count121 = templateCounts.TryGetValue(121, out var c121) ? c121 : 0; + int count122 = templateCounts.TryGetValue(122, out var c122) ? c122 : 0; + int count123 = templateCounts.TryGetValue(123, out var c123) ? c123 : 0; + int count124 = templateCounts.TryGetValue(124, out var c124) ? c124 : 0; + int count134 = templateCounts.TryGetValue(134, out var c134) ? c134 : 0; + int count135 = templateCounts.TryGetValue(135, out var c135) ? c135 : 0; + int count136 = templateCounts.TryGetValue(136, out var c136) ? c136 : 0; + int count181 = templateCounts.TryGetValue(181, out var c181) ? c181 : 0; + + // Calculate mode mask + if (count23 >= 8 && count22 >= 8) + { + modeMask |= 1; // Team match mode + } + if (count24 >= 16) + { + modeMask |= 2; // Individual match mode + modeMask |= 0x100; // Zombie mode + } + if (count23 >= 8 && count22 >= 8 && count121 >= 1 && count122 >= 1 && count123 >= 1) + { + modeMask |= 4; // CTF match mode + } + if (count124 >= 2 && count23 >= 8 && count22 >= 8) + { + modeMask |= 8; // Explosion match mode + } + if (count23 >= 8 && count22 >= 8 && count134 > 0 && count135 > 0 && count136 > 0) + { + modeMask |= 0x10; // Defense match mode + } + if (count24 >= 16 && count181 >= 1) + { + modeMask |= 0x80; // Escape mode + } + + return modeMask; + } + + public static void UnpackTimerOption(int packed, out int build, out int battle, out int rpt) + { + // Extract `rpt` (last 8 bits) + rpt = packed & 0xFF; - body.Write(UnityEngine.Random.Range(1, 64)); + // Extract `battle` (middle 8 bits) + battle = (packed >> 8) & 0xFF; - Say(new MsgReference(64, body, client)); + // Extract `build` (first 8 bits) + build = (packed >> 16) & 0xFF; - if (debugSend) - Debug.Log("SendRespawnTicket to: " + client.GetIdentifier()); - } - } -} + // Convert back to seconds + build *= 60; + battle *= 60; + } + } +} \ No newline at end of file diff --git a/Assembly-CSharp/_Emulator/Network/ShopEmulator.cs b/Assembly-CSharp/_Emulator/Network/ShopEmulator.cs new file mode 100644 index 0000000..20c4fe4 --- /dev/null +++ b/Assembly-CSharp/_Emulator/Network/ShopEmulator.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; +using UnityEngine; + +namespace _Emulator +{ + class ShopEmulator + { + private Dictionary dic; + + public void LoadAndSave() + { + Debug.Log("http://" + BuildOption.Instance.Props.GetResourceServer + "/BfData/"); + string text = Path.Combine(Application.dataPath, "Resources"); + if (!Directory.Exists(text)) + { + Debug.LogError("ERROR, Fail to find directory for Resources"); + } + string text2 = Path.Combine(text, "Template/shop.txt"); + string text3 = Path.Combine(text, "Template/shopCategory.txt"); + CSVLoader cSVLoader = new CSVLoader(); + CSVLoader cSVLoader2 = new CSVLoader(); + cSVLoader.SecuredLoadAndSave(text2, "Config\\shop.txt"); + cSVLoader2.SecuredLoadAndSave(text3, "Config\\shopCategory.txt"); + } + + public void ParseData() + { + dic = new Dictionary(); + //FileStream fileStream = File.OpenRead("Config\\shopCategory.txt"); + //StreamReader streamReader = new StreamReader(fileStream, Encoding.ASCII); + string resourceName = "_Emulator.DATA.shopCategory.txt"; + + // Get the current assembly + var assembly = Assembly.GetExecutingAssembly(); + Stream stream = assembly.GetManifestResourceStream(resourceName); + StreamReader streamReader = new StreamReader(stream); + streamReader.ReadLine(); + + while (!streamReader.EndOfStream) + { + string line = streamReader.ReadLine(); + string[] splitLine = line.Split(','); + splitLine[0] = splitLine[0].ToLower(); + TItem tItem = TItemManager.Instance.Get(splitLine[0]); + if (dic.ContainsKey(splitLine[0])) + { + Debug.LogError("Duplicated good found for " + splitLine[0]); + } + else if (tItem == null) + { + Debug.LogError("Fail to find item template : " + splitLine[0]); + } + else + { + string code = splitLine[0]; + int isNew = Int32.Parse(splitLine[1]); + int isHot = Int32.Parse(splitLine[2]); + int isVisible = Int32.Parse(splitLine[3]); + int isSpecialOffer = Int32.Parse(splitLine[5]); + int isOfferOnce = Int32.Parse(splitLine[6]); + int isGiftable = Int32.Parse(splitLine[7]); + int isPromo = Int32.Parse(splitLine[8]); + int rebuyInvisible = Int32.Parse(splitLine[9]); + sbyte minLevelFp = (sbyte)Int32.Parse(splitLine[10]); + sbyte minLevelTk = (sbyte)Int32.Parse(splitLine[11]); + tItem._StarRate = Int32.Parse(splitLine[4]); + dic.Add(splitLine[0], new Good(code, tItem, isNew == 1, isHot == 1, isVisible == 1, isSpecialOffer == 1, + isOfferOnce == 1, isGiftable == 1, isPromo == 1, rebuyInvisible == 1, (sbyte)Int32.Parse(splitLine[10]), (sbyte)Int32.Parse(splitLine[11]))); + } + } + resourceName = "_Emulator.DATA.shop.txt"; + stream = assembly.GetManifestResourceStream(resourceName); + streamReader = new StreamReader(stream); + streamReader.ReadLine(); + while (!streamReader.EndOfStream) + { + string line = streamReader.ReadLine(); + string[] splitLine = line.Split(','); + int option = Int32.Parse(splitLine[1]); + int pointPrice = Int32.Parse(splitLine[2]); + int brickPrice = Int32.Parse(splitLine[3]); + int cashPrice = Int32.Parse(splitLine[4]); + int cashBack = Int32.Parse(splitLine[5]); + splitLine[0] = splitLine[0].ToLower(); + if (!dic.ContainsKey(splitLine[0])) + { + Debug.Log("Fail to find good : %d" + splitLine[0]); + } + else + { + dic[splitLine[0]].AddPrice(option, pointPrice, brickPrice, cashPrice, cashBack, 0, 1, 0, 0, 0, 0, 314816281); + } + } + ShopManager.Instance.dic = dic; + } + } +} diff --git a/Assembly-CSharp/_Emulator/Utils/CRC32.cs b/Assembly-CSharp/_Emulator/Utils/CRC32.cs new file mode 100644 index 0000000..160443c --- /dev/null +++ b/Assembly-CSharp/_Emulator/Utils/CRC32.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace _Emulator +{ + public static class CRC32 + { + private static readonly UInt32[] crctab = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d + }; + + public static int compute(byte[] data) + { + UInt32 crc = 0xffffffff; + for (int i = 0; i < data.Length; i++) + crc = (crc >> 8) ^ crctab[(crc & 0xff) ^ data[i]]; + crc ^= 0xffffffff; + byte[] output = new byte[4]; + + output[0] = (byte)(crc >> 24); + output[1] = (byte)(crc >> 16); + output[2] = (byte)(crc >> 8); + output[3] = (byte)(crc); + + int abs = Math.Abs(BitConverter.ToInt32(output, 0)); + + return abs; + } + + public static uint computeUnsigned(byte[] data) + { + UInt32 crc = 0xffffffff; + for (int i = 0; i < data.Length; i++) + crc = (crc >> 8) ^ crctab[(crc & 0xff) ^ data[i]]; + crc ^= 0xffffffff; + byte[] output = new byte[4]; + + output[0] = (byte)(crc >> 24); + output[1] = (byte)(crc >> 16); + output[2] = (byte)(crc >> 8); + output[3] = (byte)(crc); + + return BitConverter.ToUInt32(output, 0); + } + } +} diff --git a/Assembly-CSharp/_Emulator/Utils/Zip.cs b/Assembly-CSharp/_Emulator/Utils/Zip.cs new file mode 100644 index 0000000..22826b5 --- /dev/null +++ b/Assembly-CSharp/_Emulator/Utils/Zip.cs @@ -0,0 +1,54 @@ +using ICSharpCode.SharpZipLib.GZip; +using ICSharpCode.SharpZipLib.Zip.Compression; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; + +namespace _Emulator +{ + class Zip + { + public static byte[] Compress(byte[] input) + { + // Create the compressor with highest level of compression + Deflater compressor = new Deflater(); + compressor.SetLevel(Deflater.BEST_COMPRESSION); + + // Give the compressor the data to compress + compressor.SetInput(input); + compressor.Finish(); + + /* + * Create an expandable byte array to hold the compressed data. + * You cannot use an array that's the same size as the orginal because + * there is no guarantee that the compressed data will be smaller than + * the uncompressed data. + */ + MemoryStream bos = new MemoryStream(input.Length); + + // Compress the data + byte[] buf = new byte[1024]; + while (!compressor.IsFinished) + { + int count = compressor.Deflate(buf); + bos.Write(buf, 0, count); + } + + // Get the compressed data + return bos.ToArray(); + } + + /*public static byte[] Decompress(byte[] data) + { + MemoryStream input = new MemoryStream(data); + MemoryStream output = new MemoryStream(); + using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress)) + { + dstream.Read(output, ) + } + return output.ToArray(); + }*/ + } +} diff --git a/Assembly-CSharp/bin/Debug/Assembly-CSharp-firstpass.dll b/Assembly-CSharp/bin/Debug/Assembly-CSharp-firstpass.dll deleted file mode 100644 index a2dd534..0000000 Binary files a/Assembly-CSharp/bin/Debug/Assembly-CSharp-firstpass.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/Assembly-UnityScript-firstpass.dll b/Assembly-CSharp/bin/Debug/Assembly-UnityScript-firstpass.dll deleted file mode 100644 index 373a4a3..0000000 Binary files a/Assembly-CSharp/bin/Debug/Assembly-UnityScript-firstpass.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/Assembly-UnityScript.dll b/Assembly-CSharp/bin/Debug/Assembly-UnityScript.dll deleted file mode 100644 index 825cd66..0000000 Binary files a/Assembly-CSharp/bin/Debug/Assembly-UnityScript.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/Boo.Lang.dll b/Assembly-CSharp/bin/Debug/Boo.Lang.dll deleted file mode 100644 index d25d57a..0000000 Binary files a/Assembly-CSharp/bin/Debug/Boo.Lang.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/Mono.Security.dll b/Assembly-CSharp/bin/Debug/Mono.Security.dll deleted file mode 100644 index 178acbd..0000000 Binary files a/Assembly-CSharp/bin/Debug/Mono.Security.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/System.Core.dll b/Assembly-CSharp/bin/Debug/System.Core.dll deleted file mode 100644 index 7718ca8..0000000 Binary files a/Assembly-CSharp/bin/Debug/System.Core.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/System.dll b/Assembly-CSharp/bin/Debug/System.dll deleted file mode 100644 index eca328b..0000000 Binary files a/Assembly-CSharp/bin/Debug/System.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/UnityEngine.dll b/Assembly-CSharp/bin/Debug/UnityEngine.dll deleted file mode 100644 index 146090c..0000000 Binary files a/Assembly-CSharp/bin/Debug/UnityEngine.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Debug/UnityScript.Lang.dll b/Assembly-CSharp/bin/Debug/UnityScript.Lang.dll deleted file mode 100644 index 8f14509..0000000 Binary files a/Assembly-CSharp/bin/Debug/UnityScript.Lang.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/Assembly-CSharp-firstpass.dll b/Assembly-CSharp/bin/Release/Assembly-CSharp-firstpass.dll deleted file mode 100644 index a2dd534..0000000 Binary files a/Assembly-CSharp/bin/Release/Assembly-CSharp-firstpass.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/Assembly-UnityScript-firstpass.dll b/Assembly-CSharp/bin/Release/Assembly-UnityScript-firstpass.dll deleted file mode 100644 index 373a4a3..0000000 Binary files a/Assembly-CSharp/bin/Release/Assembly-UnityScript-firstpass.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/Assembly-UnityScript.dll b/Assembly-CSharp/bin/Release/Assembly-UnityScript.dll deleted file mode 100644 index 825cd66..0000000 Binary files a/Assembly-CSharp/bin/Release/Assembly-UnityScript.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/Boo.Lang.dll b/Assembly-CSharp/bin/Release/Boo.Lang.dll deleted file mode 100644 index d25d57a..0000000 Binary files a/Assembly-CSharp/bin/Release/Boo.Lang.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/Mono.Security.dll b/Assembly-CSharp/bin/Release/Mono.Security.dll deleted file mode 100644 index 178acbd..0000000 Binary files a/Assembly-CSharp/bin/Release/Mono.Security.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/System.Core.dll b/Assembly-CSharp/bin/Release/System.Core.dll deleted file mode 100644 index 7718ca8..0000000 Binary files a/Assembly-CSharp/bin/Release/System.Core.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/System.dll b/Assembly-CSharp/bin/Release/System.dll deleted file mode 100644 index eca328b..0000000 Binary files a/Assembly-CSharp/bin/Release/System.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/UnityEngine.dll b/Assembly-CSharp/bin/Release/UnityEngine.dll deleted file mode 100644 index 146090c..0000000 Binary files a/Assembly-CSharp/bin/Release/UnityEngine.dll and /dev/null differ diff --git a/Assembly-CSharp/bin/Release/UnityScript.Lang.dll b/Assembly-CSharp/bin/Release/UnityScript.Lang.dll deleted file mode 100644 index 8f14509..0000000 Binary files a/Assembly-CSharp/bin/Release/UnityScript.Lang.dll and /dev/null differ diff --git a/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.AssemblyReference.cache b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.AssemblyReference.cache new file mode 100644 index 0000000..2909716 Binary files /dev/null and b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.AssemblyReference.cache differ diff --git a/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..7c519a1 --- /dev/null +++ b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +f7000ddb8ffb53a7af6306c86881bd4d278920b63c5abe36abd0ce6d8d4194a6 diff --git a/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.FileListAbsolute.txt b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..600df05 --- /dev/null +++ b/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.FileListAbsolute.txt @@ -0,0 +1,6 @@ +C:\Users\Jan\Documents\GitHub\Brick-Force\Assembly-CSharp\obj\Debug\Assembly-CSharp.csproj.CoreCompileInputs.cache +C:\Users\Jan\Documents\GitHub\BfLauncher\BrickForce_Data\Managed\Assembly-CSharp.pdb +C:\Users\Jan\Documents\GitHub\Brick-Force\Assembly-CSharp\obj\Debug\Assembly-CSharp.dll +C:\Users\Jan\Documents\GitHub\Brick-Force\Assembly-CSharp\obj\Debug\Assembly-CSharp.pdb +C:\Users\Jan\Documents\GitHub\Brick-Force\Assembly-CSharp\obj\Debug\Assembly-CSharp.csproj.AssemblyReference.cache +C:\Users\Jan\Documents\GitHub\Brick-Force\Assembly-CSharp\obj\Debug\Assembly.44154EF1.Up2Date diff --git a/Assembly-CSharp/obj/Debug/Assembly-CSharp.dll b/Assembly-CSharp/obj/Debug/Assembly-CSharp.dll new file mode 100644 index 0000000..586fa64 Binary files /dev/null and b/Assembly-CSharp/obj/Debug/Assembly-CSharp.dll differ diff --git a/Assembly-CSharp/obj/Debug/Assembly-CSharp.pdb b/Assembly-CSharp/obj/Debug/Assembly-CSharp.pdb new file mode 100644 index 0000000..7917e1e Binary files /dev/null and b/Assembly-CSharp/obj/Debug/Assembly-CSharp.pdb differ diff --git a/Assembly-CSharp/obj/Debug/Assembly.44154EF1.Up2Date b/Assembly-CSharp/obj/Debug/Assembly.44154EF1.Up2Date new file mode 100644 index 0000000..e69de29 diff --git a/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferences.cache new file mode 100644 index 0000000..43cfbcf Binary files /dev/null and b/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..0b00fef Binary files /dev/null and b/Assembly-CSharp/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/Assembly-CSharp/obj/Debug/TempPE/_Emulator.Network.DataSet1.Designer.cs.dll b/Assembly-CSharp/obj/Debug/TempPE/_Emulator.Network.DataSet1.Designer.cs.dll new file mode 100644 index 0000000..9aa842d Binary files /dev/null and b/Assembly-CSharp/obj/Debug/TempPE/_Emulator.Network.DataSet1.Designer.cs.dll differ diff --git a/Assembly-CSharp.sln b/Brick-Force.sln similarity index 100% rename from Assembly-CSharp.sln rename to Brick-Force.sln diff --git a/Changelog.txt b/Changelog.txt index 35dbdd0..0489b55 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -19,4 +19,38 @@ Changelog v1.1.0: Other Changes +Added string lookup for CSV loader - +Refactored match ending \ No newline at end of file + +Refactored match ending + +Changelog v1.2.0: + Game Features: + +Added Ingame Shop + +Changelog v1.3.0: + Game Features: + +Added Build and Destroy Mode + +Changelog v1.3.1: + Game Features: + +Added Capture the Flag Mode + + Bugfixes: + -Fixed BnD Bugs + +Changelog v1.4.0: + Game Features: + +Added Zombie Mode + +Added Build Mode + + Bugfixes: + -Fixed Shop and Inventory System + -Migrated Config File to JSON + -Fixed Build Mode Load and Save + -Fixed Brick-Gun Equip + + Other: + -Merged to Main Repo + -Update available in the Brick-Force Launcher + + Known Issues: + -Maps get out of sync when Players disconnect from host (To fix, manually serve the .regmap and .geometry files) + -Build Room does not get terminated if host leaves (when another user leaves after the host, the room persists) \ No newline at end of file diff --git a/README.md b/README.md index 816038c..ba62ba6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ ![](https://i.imgur.com/fThs88a.png) -[

Join The Discord

](https://discord.gg/qktjAYsKwH) -[

Latest Release

](https://github.com/Brick-Force-Aurora/Brick-Force/releases/latest) - -[

Gameplay Video

](https://www.youtube.com/watch?v=mslPRyCIKgo) - -[

Tutorial by Amorph (German)

](https://www.youtube.com/watch?v=OuJ-qxDsTrA) +

Full rewrite of the original server emulator project with more features and better stability, now available for everyone!

@@ -39,15 +40,6 @@ ![](https://i.imgur.com/6ncbt4O.png) -## Inventory Editor -![](https://i.imgur.com/teJ36Lz.png) - -- Click on items in the left list to add them to the inventory. -- Click on items in the inventory to remove them. -- Hold CTRL while clicking in the inventory to equip items. -- Click Update Inventory to apply changes to your ingame inventory. -- Click Save Inventory to update and save the current inventory to Inventory.csv. - ## Host Menu ![](https://i.imgur.com/zg6pEny.png) @@ -69,14 +61,32 @@ - F8: Debug Console ## Limitations -- Only TDM & Deathmtach are fully implemented currently, other modes should load but might not fully work. -- Future support for Build Mode is planned. -- Only one room per host to simplify server. +- There are still a lot of bugs, if you encounter any, open an Issue or head to our Discord +- Freefall, Defense and Defusion don't work +- No ingame progression +- No Missions +- No Pick'n'Win +- No Clans or Friends +- Map Manager does not work +- Weapon Upgrading does not work +- Performance needs improvement +- Temporary Shop prices +- No user information persists apart from Inventory and Config +- Action Panel untested +- Build Mode: No Swappie or Streamliner - Item stats are mostly backup values loaded from disk and are different from Infernum servers. -- Most rare weapons and max up variants have empty stats and are therefore useless in game. +- ~Most rare weapons and max up variants have empty stats and are therefore useless in game.~ - Game languages need to be english, otherwise you will get stuck in the loading screen. - Can be changed under registry path HKEY_CURRENT_USER\SOFTWARE\EXE Games\BrickForce (set BfVoice & BfLanguage to 1 for english). +## How to develop +- Install Visual Studio +- Open the solution file Brick-Force.sln +- Install the Launcher and the Game into the same folder where the Brick-Force Repository Folder is to resolve all Dependencies +- Change Build Output Path to Brick-Force_Data/Managed in project properties to match original game folder +- If necessary reimport ICSharpCode.SharpZipLib.dll as reference +- To Debug select the Brick-Force.exe as the external Program + ## Notes - This is a non-commercial fan project and not associated with any of the companies originally involved in the development and publishing of the game. - Code in _Emulator folder is newly added to the game.