using System; using System.Collections.Generic; using System.Linq; using System.Text; using GenericNetplayImplementation; namespace mmoRL { public class Client : GNIClient { public Client(string host = "vdzserver.org", int port = 51515) { StartClient(host, port); this.autoPollInterval = 10; AutoPoll(); } public bool mapLock = false; //Temporary data public string attackedEnemy = ""; public string invitee = ""; public Item discoveryItem = null; public bool monsterLock = false; //-------------------------------------------------- public void SendChat(string message) { SendSignal(this.tcpClient, new GNIData("chat", message)); } public void SendVersion() { SendSignal(this.tcpClient, new GNIData("version", MainClass.CURRENTVERSION)); } public void RequestMap(string id) { SendSignal(this.tcpClient, new GNIData("map", id)); } public void SendPosition(int x, int y, bool silent = false) { GNIData toSend = new GNIData() { keyType = GNIDataType.Short, valueType = GNIDataType.Short, keyInt = 17, valueInt = MainClass.player.y * 100 + MainClass.player.x }; if (silent) toSend.keyInt = 18; SendSignal(this.tcpClient, toSend); } public void SendName() { SendSignal(this.tcpClient, new GNIData("name", MainClass.player.name)); } public void SendKey(string key) { SendSignal(this.tcpClient, new GNIData("key", key)); } public void ChangeObject(int x, int y, int id) { SendSignal(this.tcpClient, new GNIData("object|" + x + "|" + y, id)); } public void AddItem(int x, int y, int id) { SendSignal(this.tcpClient, new GNIData("itemadd|" + x + "|" + y, id)); } public void RemoveItem(int x, int y, int id) { SendSignal(this.tcpClient, new GNIData("itemrem|" + x + "|" + y, id)); } public void AttackEnemy(int x, int y, string enemyName) { GNIData toSend = new GNIData() { keyType = GNIDataType.String, valueType = GNIDataType.Short, keyString = "attack", valueInt = y * 100 + x }; Graphics.SetStatus(""); attackedEnemy = enemyName; LockAction(); SendSignal(this.tcpClient, toSend); } public void StartParty(string playerName) { LockAction(); invitee = playerName; SendSignal(this.tcpClient, new GNIData("startparty", playerName)); } public void InviteToParty(string playerName) { LockAction(); invitee = playerName; SendSignal(this.tcpClient, new GNIData("addparty", playerName)); } public void LeaveParty() { LockAction(); SendSignal(this.tcpClient, new GNIData("leaveparty", 0)); } public void DisbandParty() { LockAction(); SendSignal(this.tcpClient, new GNIData("disbandparty", 0)); } public void ToggleFastMode() { SendSignal(this.tcpClient, new GNIData("togglefast", 0)); } public void LearnSkill(int id) { LockAction(); SendSignal(this.tcpClient, new GNIData("learn", id)); } public void DiscoverSkill(Item item) { LockAction(); discoveryItem = item; SendSignal(this.tcpClient, new GNIData("discover", item.parameter1)); } public void AddItem(Item item) { SendSignal(this.tcpClient, new GNIData("ai", item.id)); } public void RemoveItem(int itemID) { SendSignal(this.tcpClient, new GNIData("ri", itemID)); } public void Equip(int itemID) { LockAction(); SendSignal(this.tcpClient, new GNIData("equip", itemID)); } public void UnEquip(int itemID) { LockAction(); SendSignal(this.tcpClient, new GNIData("unequip", itemID)); } public void GainXP(int amount) { SendSignal(this.tcpClient, new GNIData("gainxp", amount)); } public void SkipTurn() { if (MainClass.map.turnBased) { LockAction(); SendSignal(this.tcpClient, new GNIData("skipturn", 0)); } } public void RequestTown(string id) { SendSignal(this.tcpClient, new GNIData("town", id)); } //-------------------------------------------------- public List toParse = new List(); public override void OnDataReceived(GNIData data, uint source = 0) { toParse.Add(data); } public void DoUpdate() { bool didStuff = false; List working = new List(); for (int i = 0; i < toParse.Count; i++) { working.Add(toParse[i]); didStuff = true; } toParse.Clear(); foreach (GNIData data in working) { switch (data.keyType) { case GNIDataType.String: switch (data.keyString) { case "msg": MainClass.Chat(data.valueString); break; case "key": Console.Clear(); Input.enteringString = ""; MainClass.mode = GameMode.KeyEntry; break; case "newchar": Console.Clear(); Input.enteringString = ""; MainClass.mode = GameMode.NameEntry; break; case "noname": //Name was invalid MainClass.failedName = true; Input.enteringString = ""; MainClass.mode = GameMode.NameEntry; break; case "start": MainClass.StartGame(); break; case "map": MainClass.map = new Map(data.valueBytes); MainClass.player.location = MainClass.map.id; SendSignal(this.tcpClient, new GNIData("loc", MainClass.map.id)); SendPosition(MainClass.player.x, MainClass.player.y); //Use 'Recovery' skill if (MainClass.player.HasSkill(1)) { if (!MainClass.map.turnBased) { if (MainClass.player.HP < 25) MainClass.player.RecoverTo(25); } } mapLock = false; break; case "smap": MainClass.map = new Map(data.valueBytes); mapLock = false; break; case "id": MainClass.myID = data.valueInt; break; case "left": MainClass.RemoveOtherPlayer(data.valueInt); break; case "hit": { bool valid = false; while (!valid) { string targetStatus = Util.PickRandom(new string[] { "You hit the $ENEMY$!", "You strike the $ENEMY$!", "You injure the $ENEMY$." }).Replace("$ENEMY$", attackedEnemy); if (targetStatus != Graphics.status) { valid = true; Graphics.SetStatus(targetStatus); } } } break; case "miss": { bool valid = false; while (!valid) { string targetStatus = Util.PickRandom(new string[] { "You miss the $ENEMY$!", "The $ENEMY$ dodges your attack!" }).Replace("$ENEMY$", attackedEnemy); if (targetStatus != Graphics.status) { valid = true; Graphics.SetStatus(targetStatus); } } } break; case "air": Graphics.SetStatus("Your attack hits only empty air!"); break; case "hitandkill": //MainClass.map.KillMonster(MainClass.GetMonsterAtPosition(Util.GetX(data.valueInt), Util.GetY(data.valueInt))); Graphics.SetStatus("You hit and slay the " + attackedEnemy + "!"); break; case "killmonster": Monster monster = MainClass.GetMonsterAtPosition(Util.GetX(data.valueInt), Util.GetY(data.valueInt)); if (monster != null) { Graphics.SetStatus("The " + monster.name + " dies!"); MainClass.map.KillMonster(monster); } break; case "t": //Take turn MainClass.waitingForPartyMembers = false; //Use 'Regeneration' skill if (MainClass.mode != GameMode.Dead) { if (MainClass.player.HasSkill(2)) MainClass.player.Recover(1); } Graphics.ClearStatusBuffer(); UnlockAction(); break; case "partycreated": MainClass.partyMembers.Add(invitee); MainClass.Chat("Created a party with " + invitee + "!"); Graphics.SetStatus("Party created!"); UnlockAction(); break; case "partyfailed": MainClass.Chat(invitee + " is already in a party."); MainClass.partyLeader = ""; MainClass.partyMembers.Clear(); Graphics.SetStatus("Party creation failed!"); UnlockAction(); break; case "invitesuccess": //MainClass.Chat(invitee + " joined your party!"); //Now in newmember //MainClass.partyMembers.Add(invitee); Graphics.SetStatus("Player added to party!"); UnlockAction(); break; case "invitefailed": MainClass.Chat(invitee + " is already in a party."); Graphics.SetStatus("Invitation failed!"); UnlockAction(); break; case "joinparty": { string[] split = data.valueString.Split(new string[] { "," }, StringSplitOptions.None); MainClass.partyLeader = split[0]; MainClass.partyMembers.Clear(); for (int i = 0; i < split.Length; i++) { MainClass.partyMembers.Add(split[i]); } MainClass.Chat("You joined " + split[0] + "'s party!"); } break; case "delparty": { MainClass.partyLeader = ""; MainClass.partyMembers.Clear(); MainClass.Chat("The party was disbanded!"); UnlockAction(); } break; case "leaveparty": { MainClass.partyLeader = ""; MainClass.partyMembers.Clear(); MainClass.Chat("You left the party!"); UnlockAction(); } break; case "leftparty": { MainClass.partyMembers.Remove(data.valueString); MainClass.Chat(data.valueString + " left the party!"); } break; case "newmember": { MainClass.Chat(data.valueString + " joined your party!"); MainClass.partyMembers.Add(data.valueString); } break; case "w": //Wait { MainClass.waitingForPartyMembers = true; } break; //Stat updates case "xp": MainClass.player.experience = data.valueInt; break; case "hp": MainClass.player.HP = data.valueInt; break; case "mhp": MainClass.player.maxHP = data.valueInt; break; case "str": MainClass.player.strength = data.valueInt; break; case "arm": MainClass.player.armor = data.valueInt; break; case "mu": case "md": case "ml": case "mr": case "mc": case "ma": case "mm": try { if (!monsterLock) { switch (data.keyString) { case "mu": MoveMonster(Util.GetX(data.valueInt), Util.GetY(data.valueInt), 0, -1); break; case "md": MoveMonster(Util.GetX(data.valueInt), Util.GetY(data.valueInt), 0, 1); break; case "ml": MoveMonster(Util.GetX(data.valueInt), Util.GetY(data.valueInt), -1, 0); break; case "mr": MoveMonster(Util.GetX(data.valueInt), Util.GetY(data.valueInt), 1, 0); break; case "mc": MoveMonster(Util.GetX(data.valueInt), Util.GetY(data.valueInt), 0, 0); break; case "ma": Graphics.SetStatus("The " + MainClass.GetMonsterAtPosition(Util.GetX(data.valueInt), Util.GetY(data.valueInt)).name + " hits!"); break; case "mm": Graphics.SetStatus("The " + MainClass.GetMonsterAtPosition(Util.GetX(data.valueInt), Util.GetY(data.valueInt)).name + " misses!"); break; } } } catch (Exception) { monsterLock = true; mapLock = true; SendSignal(this.tcpClient, new GNIData("refresh", 0)); } break; case "die": { Graphics.SetStatus("You die!"); MainClass.mode = GameMode.Dead; MainClass.dead = true; LockAction(); } break; case "pool": //Silent discovery { MainClass.player.AddLearnable(data.valueInt); } break; case "disc": //Discovery: Add skill to learnables { MainClass.player.AddLearnable(data.valueInt); MainClass.RemoveItem(discoveryItem); Graphics.SetStatus("Discovered '" + Skill.GetSkill(data.valueInt).name + "'!"); UnlockAction(); } break; case "nodisc": { switch (data.valueInt) { case 0: Graphics.SetStatus("Could not discover skill.", true); break; case 1: Graphics.SetStatus("You do not understand this item.", true); break; case 2: Graphics.SetStatus("You already know about this skill.", true); break; } UnlockAction(); } break; case "teach": //Learn skill { Skill toLearn = Skill.GetSkill(data.valueInt); MainClass.player.experience -= toLearn.expCost; MainClass.player.RemLearnable(data.valueInt); MainClass.player.AddSkill(data.valueInt); MainClass.Chat("@bYou have learned '" + toLearn.name + "'!"); Graphics.SetStatus("Skill learned!", true); UnlockAction(); } break; case "steach": //Silent teach { Skill toLearn = Skill.GetSkill(data.valueInt); MainClass.player.experience -= toLearn.expCost; MainClass.player.RemLearnable(data.valueInt); MainClass.player.AddSkill(data.valueInt); } break; case "myname": //Set player name { MainClass.player.name = data.valueString; } break; case "faillearn": { switch (data.valueInt) { case 1: Graphics.SetStatus("Insufficient experience.", true); break; case 2: Graphics.SetStatus("You are not yet aware of this skill.", true); break; default: Graphics.SetStatus("Could not learn skill.", true); break; } UnlockAction(); } break; case "gi": //GetItem { MainClass.AddItem(new Item(data.valueInt), true); } break; case "setx": { MainClass.player.x = data.valueInt; } break; case "sety": { MainClass.player.y = data.valueInt; } break; case "unequip": Graphics.SetStatus("You unequip the item."); UnlockAction(); break; case "error": //FATAL ERROR MainClass.Crash(data.valueString); break; case "finishrefresh": monsterLock = false; Graphics.SetStatus("The universe distorts."); break; } if (data.keyString.StartsWith("loc")) { int playerID = Convert.ToInt32(data.keyString.Substring(3)); if(MainClass.AddOtherPlayer(playerID)) MainClass.otherPlayers[playerID].location = data.valueString; } else if (data.keyString.StartsWith("name")) { int playerID = Convert.ToInt32(data.keyString.Substring(4)); if(MainClass.AddOtherPlayer(playerID)) MainClass.otherPlayers[playerID].name = data.valueString; } else if (data.keyString.StartsWith("object")) { if (!mapLock) { mapLock = true; string[] split = data.keyString.Split(new string[] { "|" }, StringSplitOptions.None); MainClass.map.objects[Convert.ToInt32(split[1]), Convert.ToInt32(split[2])] = new Object(data.valueInt); mapLock = false; } } else if (data.keyString.StartsWith("itemadd")) { if (!mapLock) { mapLock = true; string[] split = data.keyString.Split(new string[] { "|" }, StringSplitOptions.None); MainClass.map.items.Add(new Item(data.valueInt, Convert.ToInt32(split[1]), Convert.ToInt32(split[2]))); mapLock = false; } } else if (data.keyString.StartsWith("itemrem")) { if (!mapLock) { mapLock = true; string[] split = data.keyString.Split(new string[] { "|" }, StringSplitOptions.None); MainClass.map.RemoveItem(Convert.ToInt32(split[1]), Convert.ToInt32(split[2]), data.valueInt); mapLock = false; } } else if (data.keyString.StartsWith("equip")) { string equipType = data.keyString.Substring(5); Graphics.SetStatus("You equip the " + new Item(data.valueInt).Describe() + "."); EquipItem(equipType, data.valueInt); UnlockAction(); } else if (data.keyString.StartsWith("sequip")) //Silent equip { string equipType = data.keyString.Substring(6); EquipItem(equipType, data.valueInt); } break; case GNIDataType.Short: if (MainClass.AddOtherPlayer(data.keyInt)) { MainClass.otherPlayers[data.keyInt].y = (int)Math.Floor((float)data.valueInt / 100f); MainClass.otherPlayers[data.keyInt].x = data.valueInt - (MainClass.otherPlayers[data.keyInt].y * 100); } break; } } if (didStuff) { DoUpdate(); } } public void EquipItem(string equipType, int itemID) { bool foundItem = false; for (int i = 0; i < MainClass.inventory.Count; i++) { if (MainClass.inventory[i].id == itemID && !foundItem) { MainClass.inventory[i].equipped = true; foundItem = true; MainClass.CheckWaterWalking(); } else { if (MainClass.inventory[i].equipmentType == equipType) MainClass.inventory[i].equipped = false; } } } public void LockAction() { MainClass.actionLock = true; } public void UnlockAction() { if (MainClass.mode != GameMode.Dead) { MainClass.actionLock = false; } } public void MoveMonster(int monsterLocationX, int monsterLocationY, int moveX, int moveY) { Monster monster = MainClass.GetMonsterAtPosition(monsterLocationX, monsterLocationY); //if (monster != null) { monster.x += moveX; monster.y += moveY; } } public override void OnConnectionLost() { MainClass.running = false; Console.Clear(); Console.WriteLine("ERROR: Lost connection with server."); Console.WriteLine("Press any key to exit."); System.Threading.Thread.Sleep(1000); base.OnConnectionLost(); } } }