aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichaelTheShifter <[email protected]>2016-06-29 18:36:17 -0400
committerMichaelTheShifter <[email protected]>2016-06-29 18:36:17 -0400
commit20fcece26d3c54d87dd3c66702b71d5c13f05199 (patch)
tree159f5d4396fd688ae1445ca659ad007197d6234c
parentdec9dfac5eebfbfd3a21ba5cfd0ca320cd5f1bfb (diff)
downloadshiftos-c-_theultimatehacker-20fcece26d3c54d87dd3c66702b71d5c13f05199.tar.gz
shiftos-c-_theultimatehacker-20fcece26d3c54d87dd3c66702b71d5c13f05199.tar.bz2
shiftos-c-_theultimatehacker-20fcece26d3c54d87dd3c66702b71d5c13f05199.zip
Stop AI from controlling enemy in online sessions
Also added bidirectional data transfer to online battles so that I can send damage requests to the opponent when needed.
-rw-r--r--source/WindowsFormsApplication1/Controls/Computer.cs10
-rw-r--r--source/WindowsFormsApplication1/Gameplay/HackUI.cs147
-rw-r--r--source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs102
-rw-r--r--source/WindowsFormsApplication1/Resources/NetBrowser_Enemies.txt3
4 files changed, 229 insertions, 33 deletions
diff --git a/source/WindowsFormsApplication1/Controls/Computer.cs b/source/WindowsFormsApplication1/Controls/Computer.cs
index 1d287f8..ad33a58 100644
--- a/source/WindowsFormsApplication1/Controls/Computer.cs
+++ b/source/WindowsFormsApplication1/Controls/Computer.cs
@@ -168,6 +168,16 @@ namespace ShiftOS
public string Hostname { get; set; }
+ internal void throw_repaired()
+ {
+ OnRepair?.Invoke(this, new EventArgs());
+ }
+
+ internal void throw_damaged()
+ {
+ HP_Decreased?.Invoke(this, new EventArgs());
+ }
+
public event EventHandler HP_Decreased;
public void Deteriorate(int amount)
diff --git a/source/WindowsFormsApplication1/Gameplay/HackUI.cs b/source/WindowsFormsApplication1/Gameplay/HackUI.cs
index f62ae62..efafb25 100644
--- a/source/WindowsFormsApplication1/Gameplay/HackUI.cs
+++ b/source/WindowsFormsApplication1/Gameplay/HackUI.cs
@@ -24,7 +24,9 @@ namespace ShiftOS
private bool InOnlineBattle = false;
private Online.Hacking.NetTransmitter transmitter = null;
+ private Online.Hacking.NetTransmitter _playerTransmitter = null;
private Online.Hacking.NetListener receiver = null;
+ private Online.Hacking.NetListener player_listener = null;
public HackUI(EnemyHacker enemy)
{
@@ -32,11 +34,13 @@ namespace ShiftOS
InitializeComponent();
}
- public HackUI(Online.Hacking.NetTransmitter t, Online.Hacking.NetListener l)
+ public HackUI(Online.Hacking.NetTransmitter t, Online.Hacking.NetListener l, Online.Hacking.NetListener playerListener, Online.Hacking.NetTransmitter playerTransmitter)
{
InOnlineBattle = true;
transmitter = t;
receiver = l;
+ player_listener = playerListener;
+ _playerTransmitter = playerTransmitter;
InitializeComponent();
}
@@ -74,6 +78,8 @@ namespace ShiftOS
{
SetupTutorialUI(0);
}
+ if (InOnlineBattle)
+ LoadOnlinePlayer();
}
private void VisualizePlayerNetwork()
@@ -101,7 +107,60 @@ namespace ShiftOS
AddModule(c);
}
}
-
+
+ private void player_listener_ModuleRemoved(object sender, Online.Hacking.Events.ModuleRemoved e)
+ {
+ Computer c = null;
+ foreach (var m in AllPlayerComputers)
+ {
+ if (m.Hostname == e.new_module)
+ {
+ c = m;
+ }
+ }
+ AllPlayerComputers.Remove(c);
+ c.Dispose();
+ }
+
+ private void player_listener_ModuleHealthSet(object sender, Online.Hacking.Events.Health e)
+ {
+ var mod = new Computer();
+ foreach (var m in AllPlayerComputers)
+ {
+ if (m.Hostname == e.host_name)
+ mod = m;
+ }
+ mod.HP = e.health;
+ int old_hp = mod.HP;
+ mod.HP = e.health;
+ if (mod.HP > old_hp)
+ {
+ mod.throw_repaired();
+ }
+ else
+ {
+ mod.throw_damaged();
+ }
+ }
+
+
+ public void LoadOnlinePlayer()
+ {
+ //register event handlers
+ player_listener.ModuleHealthSet += player_listener_ModuleHealthSet;
+ player_listener.ModuleRemoved += player_listener_ModuleRemoved;
+ player_listener.ModuleDisabled += (o, e) =>
+ {
+ foreach (var c in AllPlayerComputers)
+ {
+ if (c.Hostname == e.hostName)
+ {
+ c.Disable();
+ }
+ }
+ };
+ }
+
public List<Computer> AllPlayerComputers = null;
private void tmrplayerhealthdetect_Tick(object sender, EventArgs e)
@@ -1360,7 +1419,7 @@ namespace ShiftOS
lbenemycompromised.Location = new Point(location, y);
lbenemycompromised.Show();
c.Flash(lbenemycompromised);
-
+ _playerTransmitter?.send_message(Online.Hacking.NetTransmitter.Messages.SetHealth, $"{c.Hostname} {c.HP}");
}
@@ -1375,6 +1434,7 @@ namespace ShiftOS
lbenemycompromised.Location = new Point(location, y);
lbenemycompromised.Show();
c.Flash(lbenemycompromised);
+ _playerTransmitter?.send_message(Online.Hacking.NetTransmitter.Messages.SetHealth, $"{c.Hostname} {c.HP}");
}
private decimal TotalEnemyHP = 0;
@@ -1390,44 +1450,46 @@ namespace ShiftOS
lbcodepoints.Text = $"Codepoints: {API.Codepoints}";
var rnd = new Random();
int chance = 0;
- foreach (var pc in AllEnemyComputers)
+ if (!InOnlineBattle)
{
- if (pc.Disabled == false)
+ foreach (var pc in AllEnemyComputers)
{
- var elist = new List<Computer>();
- if (pc.Enslaved)
- elist = AllEnemyComputers;
- else
- elist = AllPlayerComputers;
- foreach (var enemy in elist)
+ if (pc.Disabled == false)
{
- chance = rnd.Next(1, 20);
- if (chance == 10)
+ var elist = new List<Computer>();
+ if (pc.Enslaved)
+ elist = AllEnemyComputers;
+ else
+ elist = AllPlayerComputers;
+ foreach (var enemy in elist)
{
- if (IsTutorial)
+ chance = rnd.Next(1, 20);
+ if (chance == 10)
{
- if (TutorialProgress == 9)
+ if (IsTutorial)
{
- ThisPlayerPC.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
- }
- else if (TutorialProgress == 32)
- {
- enemy.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
+ if (TutorialProgress == 9)
+ {
+ ThisPlayerPC.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
+ }
+ else if (TutorialProgress == 32)
+ {
+ enemy.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
+ }
+ else
+ {
+ enemy.Enemies.Clear();
+ }
}
else
{
- enemy.Enemies.Clear();
+ enemy.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
}
}
- else
- {
- enemy.LaunchAttack(pc.GetProperType(), pc.GetDamageRate());
- }
}
}
}
}
-
foreach (var pc in AllEnemyComputers)
{
health += (decimal)pc.HP;
@@ -1581,6 +1643,30 @@ namespace ShiftOS
}
}
};
+ receiver.Won += (o, e) =>
+ {
+ //the enemy won!
+ tmrplayerhealthdetect.Stop();
+ tmrenemyhealthdetect.Stop();
+ //dispose all the modules.
+ while(AllPlayerComputers.Count > 0)
+ {
+ AllPlayerComputers[0].Dispose();
+ AllPlayerComputers.RemoveAt(0);
+ }
+ while (AllEnemyComputers.Count > 0)
+ {
+ AllEnemyComputers[0].Dispose();
+ AllEnemyComputers.RemoveAt(0);
+ }
+ //Destroy server connection.
+ Online.Hacking.Matchmaker.DestroySession();
+ //Display win message.
+ API.CreateInfoboxSession($"{e.Winner.Name} won.", $"{e.Winner.Name} has overthrown your defenses and compromised your system.", infobox.InfoboxMode.Info);
+ //Kill the hacker UI.
+ UserRequestedClose = false;
+ this.Close();
+ };
}
private void Receiver_ModuleRemoved(object sender, Online.Hacking.Events.ModuleRemoved e)
@@ -1623,7 +1709,16 @@ namespace ShiftOS
if (m.Hostname == e.host_name)
mod = m;
}
+ int old_hp = mod.HP;
mod.HP = e.health;
+ if(mod.HP > old_hp)
+ {
+ mod.throw_repaired();
+ }
+ else
+ {
+ mod.throw_damaged();
+ }
}
#endregion
diff --git a/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs b/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs
index ecb68ca..2c7d45b 100644
--- a/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs
+++ b/source/WindowsFormsApplication1/Online/Hacking/Matchmaker.cs
@@ -1,4 +1,18 @@
-using Newtonsoft.Json;
+/* ShiftOS Online Hacker Battles - Matchmaker
+ *
+ * These classes deal with keeping things in line on the client-side of things.
+ * They deal with CSP (Client-Side Prediction), sending and receiving messages to
+ * and from the ShiftOS server, as well as making sure that when you join or leave a
+ * lobby, the server and other clients actually KNOW you did.
+ *
+ * I wouldn't mess with this unless you really, really understand what you're doing,
+ * as in most cases, modification to the server is required as well (in the case of
+ * adding new commands). I'd leave modification to the system creator (Michael VanOverbeek) who
+ * actually wrote this. He's the guy who knows all about how the server works. Wait... why am
+ * I talking in third person?
+ */
+
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -10,16 +24,35 @@ namespace ShiftOS.Online.Hacking
{
public class Matchmaker
{
+ //All available lobbies.
public static List<ServerInfo> Servers = null;
+
+ //All players in the lobby.
public static List<Network> Players = null;
+ //Some useful info about the lobby in which the player is.
+ //Also contains server IP to be sent to Package_Grabber.SendMessage().
public static ServerInfo SelectedServer = null;
+
+ //Enemy network information (name, codepoints, etc)
public static Network SelectedNetwork = null;
- public static NetListener SelectedNetworkListener = null;
- public static NetTransmitter SelectedNetworkTransmitter = null;
+ //There's only one transmitter because generally the player
+ //won't be interacting with the enemy playfield enough to
+ //warrent a request to the server.
+ public static NetListener SelectedNetworkListener = null; //Listen for updates from the opponent.
+ public static NetTransmitter SelectedNetworkTransmitter = null; //Send messages to the server for enemy updates on opponent clients.
+ public static NetListener PlayerListener = null; //For receiving non-CSP updates from the server.
+ public static NetTransmitter SecondaryTransmitter = null; //For sending CSP-created update requests to the opponent (enemy health damage, etc)
+
+ //Timer that'll run during matchmaking.
public static Timer MakerTimer = null;
+ /// <summary>
+ /// This either starts matchmaking or grabs server info. Try it out I guess.
+ ///
+ /// Fires: Matchmaker.Initiated
+ /// </summary>
public static void Initiate()
{
MakerTimer = new Timer();
@@ -53,6 +86,12 @@ namespace ShiftOS.Online.Hacking
}
}
+ /// <summary>
+ /// Matchmake in the supplied lobby.
+ ///
+ /// Fires: MorePlayersFound upon player leave/join.
+ /// </summary>
+ /// <param name="si">The server to matchmake in.</param>
public static void Matchmake(ServerInfo si)
{
SelectedServer = si;
@@ -88,8 +127,12 @@ namespace ShiftOS.Online.Hacking
{
SelectedNetwork = Players[index];
MakerTimer.Stop();
+ PlayerListener = new NetListener(si, SelectedNetwork);
+ SecondaryTransmitter = new NetTransmitter(si, API.CurrentSave.MyOnlineNetwork);
SelectedNetworkListener = new NetListener(si, API.CurrentSave.MyOnlineNetwork);
SelectedNetworkTransmitter = new NetTransmitter(si, SelectedNetwork);
+ var h = new HackUI(SelectedNetworkTransmitter, SelectedNetworkListener, PlayerListener, SecondaryTransmitter);
+ h.Show();
Package_Grabber.SendMessage(SelectedServer.IPAddress, $"leave_lobby {JsonConvert.SerializeObject(API.CurrentSave.MyOnlineNetwork)}");
}
else
@@ -106,14 +149,42 @@ namespace ShiftOS.Online.Hacking
}
-
+ /// <summary>
+ /// Fired when Initiate() finishes.
+ /// </summary>
public static event EventHandler Initiated;
+
+ /// <summary>
+ /// Fired when someone enters/exits a lobby that we are in.
+ /// </summary>
public static event EventHandler MorePlayersFound;
+
+ /// <summary>
+ /// Helper method to allow me to invoke some code on the ShiftOS desktop thread (for UI access)
+ /// </summary>
+ /// <param name="method">The code to invoke (use a lambda expression or just pump a void through.)</param>
public static void invoke(Action method)
{
API.CurrentSession.Invoke(method);
}
+ internal static void DestroySession()
+ {
+ Servers.Clear();
+ Players.Clear();
+ ClearEvents();
+ SelectedNetwork = null;
+ SelectedNetworkTransmitter = null;
+ SelectedNetworkListener = null;
+ PlayerListener = null;
+ //Good to go, I guess.
+ }
+
+ public static void ClearEvents()
+ {
+ Initiated = null;
+ MorePlayersFound = null;
+ }
}
public class NetListener
@@ -181,6 +252,11 @@ namespace ShiftOS.Online.Hacking
ModuleUpgraded?.Invoke(this, new Events.ModuleUpgraded { hostname = hostnametoupgrade, grade = newgrade });
});
break;
+ case "finish":
+ string json = data.Command.Remove(0, 7);
+ var winner = JsonConvert.DeserializeObject<Network>(json);
+ Won?.Invoke(this, new Events.Won(winner));
+ break;
case "disable":
invoke(() =>
{
@@ -205,6 +281,7 @@ namespace ShiftOS.Online.Hacking
public event EventHandler<Events.ModuleRemoved> ModuleRemoved;
public event EventHandler<Events.ModuleUpgraded> ModuleUpgraded;
public event EventHandler<Events.Disabled> ModuleDisabled;
+ public event EventHandler<Events.Won> Won;
}
public class NetTransmitter
@@ -216,8 +293,6 @@ namespace ShiftOS.Online.Hacking
{
EnemyIdent = enemy;
serverInfo = si;
- var h = new HackUI(this, Matchmaker.SelectedNetworkListener);
- h.Show();
//HackUI will handle everything else to do with our network.
}
@@ -241,6 +316,10 @@ namespace ShiftOS.Online.Hacking
string healthsetstr = value as string;
Package_Grabber.SendMessage(serverInfo.IPAddress, $"set_health {healthsetstr}", EnemyIdent);
break;
+ case Messages.FinishBattle:
+ string json = JsonConvert.SerializeObject(value as Network);
+ Package_Grabber.SendMessage(serverInfo.IPAddress, $"finish {json}");
+ break;
case Messages.Disabled:
string hnamestr = value as string;
Package_Grabber.SendMessage(serverInfo.IPAddress, $"disable {hnamestr}", EnemyIdent);
@@ -255,6 +334,7 @@ namespace ShiftOS.Online.Hacking
RemoveModule,
SetHealth,
Disabled,
+ FinishBattle,
}
}
@@ -271,6 +351,16 @@ namespace ShiftOS.Online.Hacking
public string hostName { get; set; }
}
+ public class Won : EventArgs
+ {
+ public Network Winner { get; private set; }
+
+ public Won(Network winner)
+ {
+ Winner = winner;
+ }
+ }
+
public class ModulePlaced : EventArgs
{
public Module new_module { get; set; }
diff --git a/source/WindowsFormsApplication1/Resources/NetBrowser_Enemies.txt b/source/WindowsFormsApplication1/Resources/NetBrowser_Enemies.txt
index bc8d7f9..8ab0596 100644
--- a/source/WindowsFormsApplication1/Resources/NetBrowser_Enemies.txt
+++ b/source/WindowsFormsApplication1/Resources/NetBrowser_Enemies.txt
@@ -4,5 +4,6 @@
"Orange Inc.":{"IsLeader":false,"Name":"Orange Inc.","FriendDesc":"Orange is a computer industry giant. Let's see how they can compete in a Hacker Battle.","Description":"Orange is a computer industry giant, creators of the Tangerine Operating System, and various portable devices like the TangerineBook, OrangePad, and OrangePhone.","FriendSpeed":100,"FriendSkill":200,"Difficulty":"hard","Network":[{"Hostname":"orange_inc.","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"blood_orange","ModuleType":0,"Type":6,"HP":0,"Grade":4,"X":484,"Y":203},{"Hostname":"yummy","ModuleType":0,"Type":2,"HP":0,"Grade":3,"X":497,"Y":150},{"Hostname":"juicy","ModuleType":0,"Type":5,"HP":0,"Grade":4,"X":356,"Y":212},{"Hostname":"sweet","ModuleType":0,"Type":9,"HP":0,"Grade":2,"X":316,"Y":212},{"Hostname":"orange","ModuleType":0,"Type":2,"HP":0,"Grade":3,"X":490,"Y":270}]},
"UltraDOS Foundation":{"IsLeader":false,"Name":"UltraDOS Foundation","FriendDesc":"UltraDOS Foundation is a group of competent programmers responsible for the ShiftOS-based UltraDOS operating system.","Description":"UltraDOS Foundation is a group of competent programmers responsible for the ShiftOS-based UltraDOS operating system.","FriendSpeed":65,"FriendSkill":75,"Difficulty":"medium","Network":[{"Hostname":"ultrados_foundation","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"ud_trt1","ModuleType":0,"Type":3,"HP":0,"Grade":2,"X":361,"Y":171},{"Hostname":"ud_trt2","ModuleType":0,"Type":3,"HP":0,"Grade":2,"X":358,"Y":220},{"Hostname":"ud_repairer","ModuleType":0,"Type":9,"HP":0,"Grade":4,"X":494,"Y":215}]},
"LadouceurNet":{"IsLeader":false,"Name":"LadouceurNet","FriendDesc":"The LadouceurNet - the Shiftnet that never happened.","Description":"The LadouceurNet - the Shiftnet that never happened.","FriendSpeed":140,"FriendSkill":125,"Difficulty":"medium","Network":[{"Hostname":"ladouceurnet","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"mod4","ModuleType":0,"Type":3,"HP":0,"Grade":4,"X":479,"Y":127},{"Hostname":"mod5","ModuleType":0,"Type":3,"HP":0,"Grade":4,"X":382,"Y":131},{"Hostname":"mod5_1","ModuleType":0,"Type":1,"HP":0,"Grade":2,"X":482,"Y":302},{"Hostname":"mod5_2","ModuleType":0,"Type":9,"HP":0,"Grade":4,"X":359,"Y":304},{"Hostname":"mod8","ModuleType":0,"Type":5,"HP":0,"Grade":4,"X":403,"Y":336},{"Hostname":"mod1","ModuleType":0,"Type":3,"HP":0,"Grade":4,"X":444,"Y":335}]},
-"GimmeX":{"IsLeader":false,"Name":"GimmeX","FriendDesc":"The data stealer","Description":"The data stealer","FriendSpeed":10,"FriendSkill":15,"Difficulty":"medium","Network":[{"Hostname":"gimmex","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"Repairman","ModuleType":0,"Type":9,"HP":0,"Grade":1,"X":442,"Y":145},{"Hostname":"Stealer","ModuleType":0,"Type":8,"HP":0,"Grade":4,"X":371,"Y":121},{"Hostname":"Attacker","ModuleType":0,"Type":3,"HP":0,"Grade":1,"X":359,"Y":218},{"Hostname":"Defense","ModuleType":0,"Type":5,"HP":0,"Grade":4,"X":494,"Y":227},{"Hostname":"IGiveBreaks","ModuleType":0,"Type":6,"HP":0,"Grade":1,"X":522,"Y":156}]}
+"GimmeX":{"IsLeader":false,"Name":"GimmeX","FriendDesc":"The data stealer","Description":"The data stealer","FriendSpeed":10,"FriendSkill":15,"Difficulty":"medium","Network":[{"Hostname":"gimmex","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"Repairman","ModuleType":0,"Type":9,"HP":0,"Grade":1,"X":442,"Y":145},{"Hostname":"Stealer","ModuleType":0,"Type":8,"HP":0,"Grade":4,"X":371,"Y":121},{"Hostname":"Attacker","ModuleType":0,"Type":3,"HP":0,"Grade":1,"X":359,"Y":218},{"Hostname":"Defense","ModuleType":0,"Type":5,"HP":0,"Grade":4,"X":494,"Y":227},{"Hostname":"IGiveBreaks","ModuleType":0,"Type":6,"HP":0,"Grade":1,"X":522,"Y":156}]},
+"A-Labs":{"IsLeader":false,"Name":"A-Labs","FriendDesc":"A-Labs is a group that is attempting to find a cure for cancer.","Description":"A-Labs is a group that is attempting to find a cure for cancer.","FriendSpeed":9999,"FriendSkill":9999,"Difficulty":"hard","Network":[{"Hostname":"a-labs","ModuleType":0,"Type":0,"HP":100,"Grade":1,"X":0,"Y":0},{"Hostname":"Subject_1","ModuleType":0,"Type":1,"HP":0,"Grade":2,"X":512,"Y":211},{"Hostname":"Subject_2","ModuleType":0,"Type":7,"HP":0,"Grade":4,"X":330,"Y":194},{"Hostname":"Subject_3","ModuleType":0,"Type":9,"HP":0,"Grade":4,"X":427,"Y":270},{"Hostname":"Subject_4","ModuleType":0,"Type":9,"HP":0,"Grade":4,"X":437,"Y":155},{"Hostname":"Subject_5","ModuleType":0,"Type":2,"HP":0,"Grade":3,"X":284,"Y":204}]}
} \ No newline at end of file