347 lines
15 KiB
C#
347 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Drawing;
|
|
|
|
namespace EduNetworkBuilder
|
|
{
|
|
public class ActionCollection
|
|
{
|
|
Network StartingState = null;
|
|
public List<NetworkAction> NetActions = new List<NetworkAction>();
|
|
NetworkAction CurrentNetAction = null;
|
|
public bool HasUnsavedChanges = false;
|
|
|
|
public Network GetNet { get { return StartingState; } }
|
|
public int GetActionCount { get { if (CurrentNetAction == null) return 0; return CurrentNetAction.Actions.Count; } }
|
|
|
|
public void RegisterNet(Network starting)
|
|
{
|
|
StartingState = Network.DeepClone(starting);
|
|
CurrentNetAction = FindAction(starting);
|
|
if(CurrentNetAction == null)
|
|
CurrentNetAction = new NetworkAction(starting);
|
|
}
|
|
|
|
public NetworkAction GetCurrentNetAction()
|
|
{
|
|
return CurrentNetAction;
|
|
}
|
|
|
|
public void Add(ActionClass What)
|
|
{
|
|
if(CurrentNetAction == null || CurrentNetAction.HasBeenStored == true)
|
|
{
|
|
Network start = NB.GetNetwork();
|
|
if (start == null) return;//Do nothing
|
|
CurrentNetAction = new NetworkAction(start);
|
|
}
|
|
CurrentNetAction.HasBeenStored = false;// We have a change. That change has not been pushed
|
|
CurrentNetAction.Add(What);
|
|
}
|
|
|
|
public NetworkAction FindAction(Network Fitting)
|
|
{
|
|
return FindAction(NameFromNet(Fitting));
|
|
}
|
|
public NetworkAction FindAction(string Fitting)
|
|
{
|
|
foreach(NetworkAction one in NetActions)
|
|
{
|
|
if (one.NetworkName == Fitting)
|
|
return one;
|
|
}
|
|
return null;
|
|
}
|
|
public bool CurrentNeedsStoring
|
|
{ get {
|
|
if (CurrentNetAction == null) return false;
|
|
return (CurrentNetAction.HasBeenStored == false);
|
|
}
|
|
}
|
|
|
|
public ActionClass RunAction(int WhichIndex)
|
|
{
|
|
if (CurrentNetAction == null) return null;
|
|
if (WhichIndex < CurrentNetAction.Actions.Count)
|
|
{
|
|
CurrentNetAction.Actions[WhichIndex].DoAction();
|
|
return CurrentNetAction.Actions[WhichIndex];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Take the current actionlist and save it to the stored actionlists.
|
|
/// We use this when we have successfully solved a network and want to store
|
|
/// this solution process
|
|
/// </summary>
|
|
public void PushActionToList()
|
|
{
|
|
//remove an old one if it exists
|
|
if (CurrentNetAction != null)
|
|
{
|
|
NetworkAction NA = GetActionlistFromName(CurrentNetAction.NetworkName);
|
|
if (NA != null) NetActions.Remove(NA);
|
|
}
|
|
//Add this one
|
|
CurrentNetAction.HasBeenStored = true; //Note that we have stored it
|
|
NetActions.Add(CurrentNetAction);
|
|
//Note that the long-term action list has some new actions which have not been saved
|
|
HasUnsavedChanges = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return true if we already have a solved state for this network
|
|
/// </summary>
|
|
/// <param name="starting"></param>
|
|
/// <returns></returns>
|
|
public bool AlreadyHaveNet(Network starting)
|
|
{
|
|
//Look up the network to see if we have it already
|
|
return AlreadyHaveNet(NameFromNet(starting));
|
|
}
|
|
public bool AlreadyHaveNet(string starting)
|
|
{
|
|
NetworkAction NA = GetActionlistFromName(starting);
|
|
if (NA != null) return true; //one exists
|
|
return false;
|
|
}
|
|
public NetworkAction GetActionlistFromNet(Network starting)
|
|
{
|
|
return GetActionlistFromName(NameFromNet(starting));
|
|
}
|
|
public NetworkAction GetActionlistFromName(string starting)
|
|
{
|
|
foreach (NetworkAction NA in NetActions)
|
|
{
|
|
if (NA.NetworkName == starting) return NA;
|
|
}
|
|
return null;
|
|
}
|
|
private string NameFromNet(Network theNet)
|
|
{
|
|
return theNet.PuzzleName;
|
|
}
|
|
}
|
|
|
|
public class NetworkAction
|
|
{
|
|
public string NetworkName = "";
|
|
public List<ActionClass> Actions = new List<ActionClass>();
|
|
/// <summary>
|
|
/// This tells us if it has been stored to the long-term action list.
|
|
/// </summary>
|
|
public bool HasBeenStored = false;
|
|
public bool HasPassed = false;
|
|
public bool HasFailed = false;
|
|
public NetworkAction() { }
|
|
public NetworkAction(string Name)
|
|
{
|
|
NetworkName = Name;
|
|
Actions.Clear();
|
|
}
|
|
public NetworkAction(Network Start)
|
|
{
|
|
if (Start == null)
|
|
Start = NB.GetNetwork();
|
|
if (Start != null)
|
|
NetworkName = Start.PuzzleName;
|
|
else
|
|
NetworkName = "Empty";
|
|
Actions.Clear();
|
|
}
|
|
public void Add(ActionClass What)
|
|
{
|
|
Actions.Add(What);
|
|
}
|
|
public void SetPassed()
|
|
{
|
|
HasPassed = true;
|
|
HasFailed = false;
|
|
}
|
|
public void SetFailed()
|
|
{
|
|
HasPassed = false;
|
|
HasFailed = true;
|
|
}
|
|
}
|
|
|
|
public class ActionClass
|
|
{
|
|
public NBAction Action = NBAction.none;
|
|
public int SourceID = -1; //used for basically everything
|
|
public NB_IPAddress Destination; //used for pinging, arp, traceroute
|
|
public HostNicID SourceNIC; //used for links
|
|
public HostNicID DestNic; //Used for links
|
|
public Point Location; //Used when making a new device or moving an old device
|
|
public NetworkComponentType newItemType = NetworkComponentType.none; //Making new device
|
|
public NetworkComponent ChangedComponent = null;
|
|
|
|
public void DoAction()
|
|
{
|
|
Network myNet = NB.GetNetwork();
|
|
NetworkDevice source = myNet.GetDeviceFromID(SourceID);
|
|
NetworkComponent sourceC = myNet.GetComponentFromID(SourceID);
|
|
NetworkLink sourceNL;
|
|
switch (Action)
|
|
{
|
|
case NBAction.changecomponent:
|
|
//This could be a link or a device we are changing.
|
|
if(ChangedComponent is NetworkDevice)
|
|
{
|
|
source.UpdateFromComponent(ChangedComponent); //Copy any changes across
|
|
source.SetImageFromType(); //The image was not saved. Re-make it
|
|
}
|
|
else
|
|
{ //It is a link. Delete the old, make the new. Mark as linked
|
|
if(source != null)
|
|
myNet.RemoveComponent(source);
|
|
sourceNL = (NetworkLink)ChangedComponent;
|
|
myNet.MarkAsLinked(sourceNL.Src, sourceNL.GetUniqueIdentifier);
|
|
myNet.MarkAsLinked(sourceNL.Dst, sourceNL.GetUniqueIdentifier);
|
|
myNet.AddItem(ChangedComponent);
|
|
}
|
|
if(NB.DebugActions) { Console.WriteLine("Changing a component: " + source.hostname); }
|
|
break;
|
|
case NBAction.changelocation:
|
|
if (source != null)
|
|
{
|
|
source.ChangeLocation(Location);
|
|
source.UnHide(); //In case it was hidden
|
|
if (NB.DebugActions) { Console.WriteLine("Changing location for: " + source + " " + Location.X + ":" +Location.Y); }
|
|
}
|
|
break;
|
|
case NBAction.deletecomponent:
|
|
//Deleting the item is easy, but we also need to delete any links to that item
|
|
List<HostNicID> NicIDs = new List<HostNicID>();
|
|
if (source != null)
|
|
{
|
|
if (myNet.ItemIsCritical(source.hostname))
|
|
return; //we cannot delete this
|
|
NicIDs = source.GetHostNicIDs();
|
|
foreach (HostNicID nicID in NicIDs)
|
|
{
|
|
myNet.RemoveLinksToNic(nicID);
|
|
}
|
|
myNet.RemoveComponent(source);
|
|
if (NB.DebugActions) { Console.WriteLine("Deleting a device: " + source.hostname); }
|
|
} else if(sourceC != null && sourceC is NetworkLink)
|
|
{
|
|
if (myNet.ItemIsCritical(sourceC.hostname))
|
|
return; //We cannot remove this link
|
|
NetworkLink SourceL = (NetworkLink)sourceC;
|
|
SourceL.Destroy(); //Mark both ends as being deleted
|
|
myNet.RemoveComponent(SourceL); //Get rid of this link
|
|
if (NB.DebugActions) { Console.WriteLine("Deleting a link: " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.newdevice:
|
|
bool CanDo = true;
|
|
Point tLoc = myNet.clickedPosCentered(Location);
|
|
Point CenteredLocation = new Point(Location.X - (Location.X - tLoc.X), Location.Y - ((Location.Y - tLoc.Y)));
|
|
Point TopLeft = Location;
|
|
Point TopRight = new Point(TopLeft.X + myNet.itemsize, TopLeft.Y);
|
|
Point BottomRight = new Point(TopLeft.X + myNet.itemsize, TopLeft.Y + myNet.itemsize);
|
|
Point BottomLeft = new Point(TopLeft.X, TopLeft.Y + myNet.itemsize);
|
|
ChangedComponent = null; //if we cannot place it, this = null for reference
|
|
if (myNet.BlockedByTree(Location)) CanDo = false;
|
|
if (myNet.BlockedByTree(TopLeft)) CanDo = false;
|
|
if (myNet.BlockedByTree(TopRight)) CanDo = false;
|
|
if (myNet.BlockedByTree(BottomRight)) CanDo = false;
|
|
if (myNet.BlockedByTree(BottomLeft)) CanDo = false;
|
|
if (CanDo)
|
|
{
|
|
ChangedComponent = (NetworkDevice)myNet.AddItem(newItemType, Location);
|
|
if (NB.DebugActions) { Console.WriteLine("Adding a Device: " + source.hostname); }
|
|
}
|
|
else
|
|
{
|
|
NB.SetBuilderWindowStatis(NB.Translate("NB_TreePlacementError"));
|
|
if (NB.DebugActions) { Console.WriteLine("Unable to add device: " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.dhcp:
|
|
if (source != null)
|
|
{
|
|
source.DHCPRequestFromHere();
|
|
if (NB.DebugActions) { Console.WriteLine("Requesting DHCP: " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.arp:
|
|
if (source != null)
|
|
{
|
|
source.AskArpFromHere(Destination);
|
|
if (NB.DebugActions) { Console.WriteLine("Requesting DHCP: " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.cleararp:
|
|
if (source != null)
|
|
{
|
|
source.ClearArps();
|
|
if (NB.DebugActions) { Console.WriteLine("Clearing ARP: " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.ping:
|
|
if (source != null)
|
|
{
|
|
source.PingFromHere(Destination);
|
|
if (NB.DebugActions) { Console.WriteLine("Pinging " + Destination.GetIPString + " from " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.traceroute:
|
|
if (source != null)
|
|
{
|
|
source.TracerouteFromHere(Destination);
|
|
if (NB.DebugActions) { Console.WriteLine("Traceroute: " + Destination.GetIPString + " from " + source.hostname); }
|
|
}
|
|
break;
|
|
case NBAction.replace:
|
|
if(sourceC is NetworkDevice)
|
|
{
|
|
source.ClearIPs(); //reset the device
|
|
source.IsBurned = false; //If it had been burned before, it is no longer burned
|
|
source.PowerOff = true;
|
|
source.BadSprayCount = 0;
|
|
//Mark the replace test as "done"
|
|
myNet.RegisterDeviceReset(source.hostname); //replacing something powers it off
|
|
|
|
myNet.RegisterDeviceReplaced(source.hostname); //replace it.
|
|
if (NB.DebugActions) { Console.WriteLine("Replacing device: " + source.hostname); }
|
|
}
|
|
else if (sourceC is NetworkLink)
|
|
{
|
|
sourceNL = (NetworkLink)sourceC;
|
|
|
|
if (sourceNL.theLinkType != LinkType.wireless)
|
|
{
|
|
HostNicID sourceID = sourceNL.Src;
|
|
HostNicID destID = sourceNL.Dst;
|
|
myNet.RemoveComponent(sourceNL);
|
|
NetworkLink nNL = new NetworkLink(sourceID, destID, LinkType.normal);
|
|
myNet.AddItem(nNL);
|
|
if (NB.DebugActions) { Console.WriteLine("Replacing link: " + source.hostname); }
|
|
}
|
|
}
|
|
break;
|
|
case NBAction.replaceUPS:
|
|
myNet.RegisterUPSAdded(source.hostname);
|
|
if (NB.DebugActions) { Console.WriteLine("Replacing UPS on: " + source.hostname); }
|
|
break;
|
|
case NBAction.poweroff:
|
|
source.PowerOff = true;
|
|
myNet.RegisterDeviceReset(source.hostname);
|
|
if (NB.DebugActions) { Console.WriteLine("Powering off: " + source.hostname); }
|
|
break;
|
|
case NBAction.poweron:
|
|
source.PowerOff = false;
|
|
if (NB.DebugActions) { Console.WriteLine("Powering on: " + source.hostname); }
|
|
//We might see about exploding the device here.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|