using System; using System.Collections.Generic; using System.Linq; using System.Text; using GenericNetplayImplementation; using System.IO; namespace DEServer { class Program : GNIServer { public List creatures = new List(); public Dictionary knownCreatures = new Dictionary(); static void Main(string[] args) { new Program().DoStuff(); } public void DoStuff() { LoadAllCreatures(); StartServer(5847); Log("Server started."); while (true) { this.Update(); System.Threading.Thread.Sleep(50); } } public override void OnDataReceived(GNIData data, uint source = 0) { switch (data.keyString) { case "serialize": Creature creature = new Creature(data.valueBytes); int toRemove = -1; for (int i = 0; i < creatures.Count; i++) { if (creatures[i].pass == creature.pass) toRemove = i; } List knownPasses = new List(); if (toRemove != -1) { for (int i = 0; i < creatures[toRemove].evolvedPasses.Count; i++) { knownPasses.Add(creatures[toRemove].evolvedPasses[i]); } creatures.RemoveAt(toRemove); } creature.evolvedPasses = knownPasses; creatures.Add(creature); SaveCreature(creature); //Store client/creature connection if (!knownCreatures.ContainsKey(source)) knownCreatures.Add(source, creature); break; case "getpass": { byte[] pass = null; bool acceptable = false; Random random = new Random(); while (!acceptable) { pass = new byte[16]; for (int i = 0; i < 16; i++) { pass[i] = (byte)random.Next(255); } acceptable = true; //Check if there's already a creature with this pass for (int i = 0; i < creatures.Count; i++) { if (creatures[i].pass == pass) acceptable = false; } } GNIData toSend = new GNIData(true); toSend.keyType = GNIDataType.String; toSend.valueType = GNIDataType.ByteArray; toSend.keyString = "freepass"; toSend.valueBytes = pass; SendSignal(source, toSend); break; } case "getcode": { string code = ""; bool acceptable = false; Random random = new Random(); while (!acceptable) { string[] parts = new string[4]; for (int i = 0; i < 4; i++) { parts[i] = words[random.Next(words.Length)]; } acceptable = true; //Make sure there are no repeat words for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { if (parts[i1] == parts[i2] && i1 != i2) acceptable = false; } } code = parts[0] + " " + parts[1] + " " + parts[2] + " " + parts[3]; if (acceptable) //Skip if already confirmed wrong { //Check if there's already a creature with this code for (int i = 0; i < creatures.Count; i++) { if (creatures[i].code == code) acceptable = false; } } } SendSignal(source, new GNIData("freecode", code)); break; } case "enterpass": { GNIData toSend = new GNIData(true); toSend.keyType = GNIDataType.String; toSend.valueType = GNIDataType.ByteArray; toSend.keyString = "yourcreature"; bool found = false; Creature foundCreate = new Creature(); for (int i = 0; i < creatures.Count; i++) { string askedString = ""; for (int ii = 0; ii < data.valueBytes.Length; ii++) askedString += Convert.ToString(data.valueBytes[ii]) + " "; string checkedString = ""; for (int ii = 0; ii < creatures[i].pass.Length; ii++) checkedString += Convert.ToString(creatures[i].pass[ii]) + " "; if (askedString == checkedString) //Normally compares the bytes but for some reason that went wrong, so ugly fix { toSend.valueBytes = creatures[i].Serialize(); foundCreate = creatures[i]; found = true; } } if (found) { SendSignal(source, toSend); //Store client/creature connection if (!knownCreatures.ContainsKey(source)) knownCreatures.Add(source, foundCreate); } else { SendSignal(source, new GNIData("donothave", 0)); } break; } case "entercode": { GNIData toSend = new GNIData(true); toSend.keyType = GNIDataType.String; toSend.valueType = GNIDataType.ByteArray; toSend.keyString = "thatcreature"; Creature ThatCreature = new Creature(); bool found = false; for (int i = 0; i < creatures.Count; i++) { if (creatures[i].code == data.valueString) { ThatCreature = creatures[i]; toSend.valueBytes = creatures[i].Serialize(); found = true; } } if (found) { //First send the evolution allowed/disallowed signal int allowed = 1; { for (int i = 0; i < knownCreatures[source].evolvedPasses.Count; i++) { if (knownCreatures[source].evolvedPasses[i] == ThatCreature.pass) allowed = 0; if (data.valueString == knownCreatures[source].code) allowed = 0; } } SendSignal(source, new GNIData("mayevolve", allowed)); //Then send the data SendSignal(source, toSend); } else { SendSignal(source, new GNIData("donotexist", 0)); } break; } case "evolvedfrom": for (int i = 0; i < creatures.Count; i++) { if(creatures[i].code == data.valueString) knownCreatures[source].evolvedPasses.Add(creatures[i].pass); } break; case "randombattle": Random theRandom = new Random(); Creature theEnemy = new Creature(); bool foundCreature = false; int desiredBattleRating = data.valueInt; float variation = 0.1f; int attempt = 0; while (!foundCreature) { theEnemy = creatures[theRandom.Next(creatures.Count)]; //Make sure player is not fighting himself if (theEnemy.name != knownCreatures[source].name) { //Be above minimum BR if (theEnemy.totalEXP > desiredBattleRating * (1 - variation)) { //Be below maximum BR if (theEnemy.totalEXP < desiredBattleRating * (1 + variation)) { foundCreature = true; Log(knownCreatures[source].name + " random battles " + theEnemy.name + "!"); } } } attempt++; //Increase search range if it really can't find anyone if (attempt > 100) { attempt = 0; variation += 0.1f; } } GNIData toSend2 = new GNIData("randomenemy", 0); toSend2.valueType = GNIDataType.ByteArray; toSend2.valueBytes = theEnemy.Serialize(); SendSignal(source, toSend2); break; } } public override void OnClientConnected(GNIClientInformation client) { Program.Log("Client connected."); base.OnClientConnected(client); } public string[] words = new string[] { "VIRUS", "DIGITAL", "BATTLE", "FIRE", "WATER", "GRASS", "LIGHT", "DARK", "NORMAL", "LARGE", "SMALL", "DATA", "TRANSFER", "CYBER", "NET", "LINK", "FILE", "MODE", "CPU", "INIT", "TRAIT", "MOVE", "EVO", "DISK", "COMBAT", "INPUT", "OUTPUT", "FINAL", "GRID", "MEGA", "GIGA", "TERA" }; public static void Log(string message) { Console.Out.WriteLine("[" + DateTime.Now.ToString() + "] " + message); } public void SaveCreature(Creature creature) { Log("Saving creature " + creature.name); string passString = ""; for (int i = 0; i < creature.pass.Length; i++) { passString += Convert.ToString(creature.pass[i]); if (i < creature.pass.Length - 1) passString += "-"; } FileStream fs = new FileStream("creatures\\" + passString + ".crt", FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); byte[] serialization = creature.Serialize(true); bw.Write(serialization); bw.Close(); fs.Close(); Log("Saved."); } public void LoadAllCreatures() { Log("Loading creatures..."); creatures = new List(); DirectoryInfo di = new DirectoryInfo("creatures"); FileInfo[] fi = di.GetFiles(); for (int i = 0; i < fi.Length; i++) { try { FileStream fs = new FileStream(fi[i].FullName, FileMode.Open); BinaryReader br = new BinaryReader(fs); byte[] buffer = new byte[br.BaseStream.Length]; br.Read(buffer, 0, (int)br.BaseStream.Length); creatures.Add(new Creature(buffer)); br.Close(); fs.Close(); Log("Loaded " + creatures[creatures.Count - 1].name); } catch { } } Log("Loading finished."); } } }