2015-08-01 19:58:53 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2017-06-10 02:09:59 +02:00
|
|
|
|
//using System.Deployment.Application;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.Resources;
|
|
|
|
|
using System.Xml;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Media;
|
|
|
|
|
using System.Reflection;
|
2015-08-08 19:09:22 +02:00
|
|
|
|
using System.Text.RegularExpressions;
|
2017-07-30 21:55:37 +02:00
|
|
|
|
using System.Xml.Serialization;
|
|
|
|
|
using System.IO;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
|
|
|
|
|
namespace EduNetworkBuilder
|
|
|
|
|
{
|
|
|
|
|
public enum PacketStatus {
|
|
|
|
|
processing, //It is inside a device. It needs to be routed, masqueraded, or whatever
|
|
|
|
|
input, //It is hitting the interface/nic of a device.
|
|
|
|
|
output, //It is leaving a device. Make sure the mac address is what it should be & that we are going out the right link
|
|
|
|
|
waiting_for_arp, //It is in the output chain, has been procesed, but is waiting for an arp packet to give it the dest MAC
|
|
|
|
|
moving, //It is traveling along a link. We increment the distance it has gone and re-draw the packet.
|
|
|
|
|
encapsulated, //It has been put inside another packet.
|
|
|
|
|
finished_ok,//The packet has finished and is ready to be removed from the network
|
|
|
|
|
finished_failed, //The packet is finished (failed) and is ready to be removed from the network.
|
|
|
|
|
finished //There was an appropriate reason this packet finished. It stopped
|
|
|
|
|
}
|
2016-10-04 02:49:05 +02:00
|
|
|
|
public enum VLANTagType { Tagged, Untagged, Forbidden }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum LinkType { normal, wireless, broken }
|
2017-03-13 08:36:40 +01:00
|
|
|
|
public enum PacketType { none, ping_request, ping_answer, arp_request, arp_answer, dhcp_request,
|
|
|
|
|
dhcp_answer, vpn_packet, tun_packet, tracert_request, tracert_reply }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum ResponseToPacket { none, accept, masq, drop, reject }
|
|
|
|
|
public enum DebugLevel { none=0, info=1, routing=2, switching=4, natting=8, filtering=16, debug=32 , packet=64, all=127}
|
|
|
|
|
public enum NetworkComponentType { none, router, net_switch, net_hub, laptop, pc, server, wap ,
|
2015-09-02 00:46:03 +02:00
|
|
|
|
wrouter, wbridge, wrepeater, link, firewall, ip_phone, printer, copier, microwave, fluorescent, cellphone, tablet }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum NicType { none, lo, eth, wlan, wan, vpn, tun, management_interface, port, wport }
|
|
|
|
|
public enum IPAddressType { ip, gw, route, ip_only }
|
|
|
|
|
public enum nb_direction { none, to_src, to_dst }
|
|
|
|
|
public enum GeneralComponentType { none, link, device }
|
2015-11-01 14:25:20 +01:00
|
|
|
|
public enum NBSoundType { none, success, saved_ok, saved_failed }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum RTFWindowContents { help, about, release_notes }
|
2016-10-14 00:15:17 +02:00
|
|
|
|
public enum NetTestType { NeedsLocalIPTo, NeedsDefaultGW, NeedsLinkToDevice, NeedsRouteToNet,
|
|
|
|
|
NeedsUntaggedVLAN, NeedsTaggedVLAN, NeedsForbiddenVLAN,
|
2015-11-23 00:01:56 +01:00
|
|
|
|
SuccessfullyPings, SuccessfullyPingsAgain, SuccessfullyArps, SuccessfullyDHCPs, HelpRequest, ReadContextHelp, FailedPing,
|
2017-03-13 14:32:40 +01:00
|
|
|
|
DHCPServerEnabled, SuccessfullyTraceroutes,
|
2016-10-14 00:15:17 +02:00
|
|
|
|
LockAll, LockIP, LockRoute, LockNic, LockDHCP, LockGateway,
|
2016-10-20 21:53:23 +02:00
|
|
|
|
LockVLANsOnHost, LockNicVLAN, LockInterfaceVLAN, LockVLANNames,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
2017-03-13 14:32:40 +01:00
|
|
|
|
public enum ContextTest { ping, arp, traceroute }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum NetTestVerbosity { none, basic, hints, full }
|
|
|
|
|
public enum LBContents { routes, messages, dhcp, puzzles }
|
|
|
|
|
public enum HelpTopics {
|
2015-08-08 15:12:34 +02:00
|
|
|
|
None, DHCP, DHCPServer, Firewall, Gateway, Help, IPAddress, Link, Subnet, Ping,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
VPN, Hub, Switch, ARP, StaticRoute, Subnetting, WhenToSubnet, ComparingAddresses, MACAddress,
|
2015-11-16 16:20:17 +01:00
|
|
|
|
Network, Packet, NIC, Interface, Router, PacketCorruption, GeneralWireless, WirelessSSID, WirelessKey,
|
2017-03-13 14:32:40 +01:00
|
|
|
|
WirelessAP, WirelessRouter, WirelessRepeater, WirelessBridge, VLAN, Power, Traceroute
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
2016-11-04 21:08:47 +01:00
|
|
|
|
public enum FirewallRuleType { Allow, Drop }
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public enum PuzzleNames
|
|
|
|
|
{
|
|
|
|
|
Level0_IP, Level1_NoGateway, Level0_NeedsLink, Level0_NoSwitch, Level1_BadDHCP, Level1_BadGateway,
|
2017-03-11 09:07:24 +01:00
|
|
|
|
Level0_SimpleDHCP, Level1_BadIP, Level0_Help, Level0_Ping, Level0_HubVsSwitch, Level0_Power,
|
2017-06-21 22:19:19 +02:00
|
|
|
|
Level0_NetworkLoop2, Level0_BrokenLink, Level0_HiddenSwitch,
|
2017-03-13 14:32:40 +01:00
|
|
|
|
Level0_PacketCorruption1, Level0_PacketCorruption2, Level0_Traceroute, Level1_AddingDevices,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
Level1_MidDHCP, Level1_OneNetTwoSubnets, Level1_DuplicateIPs, Level0_NetworkLoop, Level1_DuplicateMAC,
|
2017-06-28 17:24:53 +02:00
|
|
|
|
Level1_BadNetmask, Level1_VPNTraceroute,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
Level2_FirewallDemo, Level1_OneNetTwoSubnets2, Level2_VPN_Demo, Level2_Bad_VPN_IP, Level2_Bad_Encryption,
|
|
|
|
|
Level2_Bad_Route, Level2_Blast_From_Past, Level2_Not_Working, Level2_Build_A_VPN, Level2_Connect_The_Dots,
|
2017-03-11 09:07:24 +01:00
|
|
|
|
Level2_VPN_woes, Level2_FirewallTest2, Level2_CannotConnect,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
Level3_BlackHole, Level3_Busted, Level3_Middle_Man_Out, Level3_PhoneyNetwork, Level3_VPNify, Level3_EncryptionTroubles,
|
2017-06-21 22:19:19 +02:00
|
|
|
|
Level3_NowhereToGo, Level3_GrandCentralStation, Level3_Dead,
|
|
|
|
|
Level3_TwoDHCPServers, Level3_invisible,
|
2015-08-01 19:58:53 +02:00
|
|
|
|
Level4_DualWans, Level4_SinglesLife, Level4_SmallSubnets, Level4_OneRoute, Level4_RouterReplacement,
|
2017-06-23 22:39:01 +02:00
|
|
|
|
Level4_InternalSubnetting, Level4_Internalhemorrhage, Level4_WhoDidThat,
|
2015-11-02 01:04:46 +01:00
|
|
|
|
Level5_WirelessRouters, Level5_WirelessDevices, Level5_WirelessBridge, Level5_WirelessRepeater, Level5_WirelessRepeater2,
|
2016-10-28 17:17:13 +02:00
|
|
|
|
Level5_WirelessAccessPoint, Level5_WirelessCorruption, Level5_Failed, Level5_LostPacket, Level5_HereComesTrouble,
|
2017-03-11 09:38:09 +01:00
|
|
|
|
Level5_APProblems,
|
2016-11-04 21:08:47 +01:00
|
|
|
|
Level6_VLAN_Intro, Level6_VLAN_Intro2, Level6_Intro3_LockedOut, Level6_ForbiddenVLAN, Level6_TaggedBetweenSwitches,
|
|
|
|
|
Level6_VLANRouting, Level6_VLANRouting2, level6_UntaggedAndDHCP, Level6_SorryBoss, Level6_VLANFrustrations,
|
2017-01-27 04:08:12 +01:00
|
|
|
|
Level6_TwoAccessPoints, Level6_VlanRouting3, Level6_ConnectTheLaptop, Level6_CleanSlate, Level6_WhereFrom,
|
|
|
|
|
Level6_NeedVLANs, Level6_SwitchedUp,
|
2016-10-28 17:17:13 +02:00
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
public enum DebugPausePoint { none=0, packet_create=1, packet_kill=2,
|
|
|
|
|
packet_in=4, packet_out=8, packet_duplicate=16, all=63,
|
|
|
|
|
dump=256, pause=512}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
public struct HostNicID //This holds a unique identifier for a network card. Links use this to know what it is connected to
|
|
|
|
|
{
|
|
|
|
|
public int HostID;
|
|
|
|
|
public int NicID;
|
|
|
|
|
public string HostName;
|
|
|
|
|
public string NicName;
|
|
|
|
|
public HostNicID(int host, int nic, string hostname, string nicname)
|
|
|
|
|
{
|
|
|
|
|
HostID = host;
|
|
|
|
|
NicID = nic;
|
|
|
|
|
HostName = hostname;
|
|
|
|
|
NicName = nicname;
|
|
|
|
|
}
|
|
|
|
|
public HostNicID(XmlNode theNode)
|
|
|
|
|
{
|
|
|
|
|
HostID = 0;
|
|
|
|
|
NicID = 0;
|
|
|
|
|
HostName = "";
|
|
|
|
|
NicName = "";
|
|
|
|
|
foreach (XmlNode Individual in theNode.ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
XmlNodeType myNodetype = Individual.NodeType;
|
|
|
|
|
if (myNodetype == XmlNodeType.Element)
|
|
|
|
|
{
|
|
|
|
|
switch (Individual.Name.ToLower())
|
|
|
|
|
{
|
|
|
|
|
case "hostid":
|
|
|
|
|
int.TryParse(Individual.InnerText, out HostID);
|
|
|
|
|
break;
|
|
|
|
|
case "nicid":
|
|
|
|
|
int.TryParse(Individual.InnerText, out NicID);
|
|
|
|
|
break;
|
|
|
|
|
case "hostname":
|
|
|
|
|
HostName = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "nicname":
|
|
|
|
|
NicName = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Save(XmlWriter writer, string tag)
|
|
|
|
|
{
|
|
|
|
|
writer.WriteStartElement(tag);
|
|
|
|
|
writer.WriteElementString("hostid", HostID.ToString());
|
|
|
|
|
writer.WriteElementString("nicid", NicID.ToString());
|
|
|
|
|
writer.WriteElementString("hostname", HostName);
|
|
|
|
|
writer.WriteElementString("nicname", NicName);
|
|
|
|
|
writer.WriteEndElement();
|
|
|
|
|
}
|
|
|
|
|
public string HostNicIDString
|
|
|
|
|
{
|
|
|
|
|
get { return HostID.ToString()+"-"+NicID.ToString(); }
|
|
|
|
|
}
|
|
|
|
|
public bool Equals(HostNicID toCheck)
|
|
|
|
|
{
|
|
|
|
|
if (HostID != toCheck.HostID) return false;
|
|
|
|
|
if (NicID != toCheck.NicID) return false;
|
|
|
|
|
if (HostName != toCheck.HostName) return false;
|
|
|
|
|
if (NicName != toCheck.NicName) return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
public struct IPConnectionEntry
|
|
|
|
|
{
|
|
|
|
|
public IPAddress destIP; //where we are sending the packet to. We expect a response to come from here
|
|
|
|
|
public PacketType What; //ping, dhcp, etc
|
|
|
|
|
public ResponseToPacket Response; //accept, masq
|
|
|
|
|
public IPAddress internalIP; //Used if we are masquerading
|
|
|
|
|
public IPConnectionEntry(IPAddress dest, PacketType what, ResponseToPacket response)
|
|
|
|
|
{
|
|
|
|
|
destIP = dest;
|
|
|
|
|
What = what;
|
|
|
|
|
Response = response;
|
|
|
|
|
internalIP = null;
|
|
|
|
|
}
|
|
|
|
|
public IPConnectionEntry(IPAddress dest, PacketType what, ResponseToPacket response, IPAddress internal_ip)
|
|
|
|
|
{
|
|
|
|
|
destIP = dest;
|
|
|
|
|
What = what;
|
|
|
|
|
Response = response;
|
|
|
|
|
internalIP = internal_ip;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-26 23:41:29 +01:00
|
|
|
|
public class PingTestStatus
|
|
|
|
|
{
|
|
|
|
|
public string Source;
|
|
|
|
|
public string Dest;
|
|
|
|
|
public bool Succeeded = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
[Serializable]
|
|
|
|
|
public struct ArpEntry
|
|
|
|
|
{
|
|
|
|
|
public string MACAddress;
|
|
|
|
|
public string IPAddr;
|
|
|
|
|
public HostNicID NicOnWhichItIsFound;
|
|
|
|
|
public ArpEntry(string mac, string ip, HostNicID thenic)
|
|
|
|
|
{
|
|
|
|
|
MACAddress = mac;
|
|
|
|
|
IPAddr = ip;
|
|
|
|
|
NicOnWhichItIsFound = thenic;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class PuzzleInfo
|
|
|
|
|
{
|
|
|
|
|
public string PuzzleName;
|
|
|
|
|
public string PuzzleTitle;
|
|
|
|
|
public string PuzzleDescription;
|
|
|
|
|
public List<string> PuzzleTags = new List<string>();
|
|
|
|
|
public int Level=0;
|
|
|
|
|
public double SortOrder=0;
|
|
|
|
|
public void Load(XmlNode TheNode, string Name)
|
|
|
|
|
{
|
|
|
|
|
PuzzleName = Name;
|
|
|
|
|
foreach (XmlNode Individual in TheNode.ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
XmlNodeType myNodetype = Individual.NodeType;
|
|
|
|
|
if (myNodetype == XmlNodeType.Element)
|
|
|
|
|
{
|
|
|
|
|
switch (Individual.Name.ToLower())
|
|
|
|
|
{
|
|
|
|
|
case "edunetworkbuilder":
|
|
|
|
|
case "network":
|
|
|
|
|
Load(Individual, PuzzleName);
|
|
|
|
|
break;
|
|
|
|
|
case "message":
|
|
|
|
|
PuzzleDescription = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "title":
|
|
|
|
|
PuzzleTitle = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "tag":
|
|
|
|
|
PuzzleTags.Add(Individual.InnerText);
|
|
|
|
|
break;
|
|
|
|
|
case "level":
|
|
|
|
|
PuzzleTags.Add("Level_" + Individual.InnerText);
|
|
|
|
|
int.TryParse(Individual.InnerText, out Level);
|
|
|
|
|
break;
|
|
|
|
|
case "sortorder":
|
|
|
|
|
double.TryParse(Individual.InnerText, out SortOrder);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-07 17:50:56 +01:00
|
|
|
|
[Serializable]
|
|
|
|
|
public class FirewallRule
|
|
|
|
|
{
|
|
|
|
|
public string Source;
|
|
|
|
|
public string Destination;
|
|
|
|
|
public FirewallRuleType Action;
|
|
|
|
|
|
|
|
|
|
public FirewallRule(string source, string dest, FirewallRuleType action)
|
|
|
|
|
{
|
|
|
|
|
Source = source;
|
|
|
|
|
Destination = dest;
|
|
|
|
|
Action = action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FirewallRule(XmlNode theNode)
|
|
|
|
|
{
|
|
|
|
|
foreach (XmlNode Individual in theNode.ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
XmlNodeType myNodetype = Individual.NodeType;
|
|
|
|
|
if (myNodetype == XmlNodeType.Element)
|
|
|
|
|
{
|
|
|
|
|
switch (Individual.Name.ToLower())
|
|
|
|
|
{
|
|
|
|
|
case "source":
|
|
|
|
|
Source = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "destination":
|
|
|
|
|
Destination = Individual.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "action":
|
|
|
|
|
Action = NB.ParseEnum<FirewallRuleType>(Individual.InnerText);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Save(XmlWriter writer, string tag)
|
|
|
|
|
{
|
|
|
|
|
writer.WriteStartElement(tag);
|
|
|
|
|
writer.WriteElementString("source", Source);
|
|
|
|
|
writer.WriteElementString("destination", Destination);
|
|
|
|
|
writer.WriteElementString("action", Action.ToString());
|
|
|
|
|
writer.WriteEndElement();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-07-31 18:27:25 +02:00
|
|
|
|
static class NB
|
2015-08-01 19:58:53 +02:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public static string BroadcastMACString = "FF:FF:FF:FF:FF:FF"; //The broadcast MAC address
|
|
|
|
|
public static string BroadcastIPString = "255.255.255.255"; //the generic broadcast IP address
|
|
|
|
|
public static string ZeroIPString = "0.0.0.0";
|
|
|
|
|
public static string LoopbackIPString = "127.0.0.1";
|
|
|
|
|
public static int LinkStep = 8;//The percentage of the link we move at each "tick"
|
2016-10-28 17:17:13 +02:00
|
|
|
|
public static int PacketPixelSize = 16; //The size of the packet pixel
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static int PacketVersionNum = 2; //2 uses the new stuff. Anything else uses the old stuff
|
|
|
|
|
public const int GridSize = 10;
|
2015-11-16 23:14:17 +01:00
|
|
|
|
public static string[,] LanguageChoices = { { NB.Translate("NB_NBEn"), "en" }, { NB.Translate("NB_NBFr"), "fr" } };
|
2015-08-22 21:25:15 +02:00
|
|
|
|
public static int WirelessMaxUnsuccessfulLink = 120; //The link will connect, but the packet will drop
|
|
|
|
|
public static int WirelessMaxSuccessfulLink = 100; //Packets will drop after this distance
|
|
|
|
|
public static int WirelessReconnectDistance = 70; //Try to find a closer AP if we are this far out.
|
2016-10-11 02:31:57 +02:00
|
|
|
|
public static int UntaggedVLAN = -1; //If the packet is not tagged.
|
2016-12-11 01:47:14 +01:00
|
|
|
|
public static int MaxPacketsBeforeOptimizing = 50;
|
2017-08-02 00:20:27 +02:00
|
|
|
|
public static int DefaultPasswordLen = 6;
|
2017-08-03 18:37:45 +02:00
|
|
|
|
public static int DefaultMachinePasswordLen = 20;
|
2017-08-02 00:20:27 +02:00
|
|
|
|
public static int DefaultSaltLen = 50;
|
2017-08-05 20:11:26 +02:00
|
|
|
|
public static int NormalRotation = 5;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
|
2017-08-01 21:30:07 +02:00
|
|
|
|
public static string AllowedPasswordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!~@#$%^&*()_+{}[]/?<>,.";
|
|
|
|
|
public static string AllowedUsernameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._";
|
2015-08-01 19:58:53 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Find the global random number generator.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>A valid random number generator</returns>
|
|
|
|
|
public static Random GetRandom()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return new Random();
|
|
|
|
|
if (myWin.GameRandomGen == null) return new Random();
|
|
|
|
|
return myWin.GameRandomGen;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Find the global random number generator.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>A valid random number generator</returns>
|
2017-06-16 20:03:38 +02:00
|
|
|
|
public static CultureInfo GetCulture(NBSettings theSettings = null)
|
2015-08-01 19:58:53 +02:00
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
CultureInfo CI=null;
|
2017-06-16 20:03:38 +02:00
|
|
|
|
NBSettings oursettings;
|
|
|
|
|
|
|
|
|
|
if (theSettings == null) oursettings = NB.GetSettings();
|
|
|
|
|
else oursettings = theSettings;
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
if (myWin != null)
|
|
|
|
|
{
|
|
|
|
|
CI = myWin.GetCulture();
|
|
|
|
|
}
|
|
|
|
|
if(CI == null || myWin == null)
|
|
|
|
|
{
|
2017-06-16 18:27:53 +02:00
|
|
|
|
string CL = oursettings.ChosenLanguage;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
CI = CultureInfo.CreateSpecificCulture(CL);
|
|
|
|
|
}
|
|
|
|
|
return CI;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Find the global random number generator.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>A valid random number generator</returns>
|
|
|
|
|
public static ResourceManager GetResource()
|
|
|
|
|
{
|
|
|
|
|
ResourceManager myresource = null;
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin != null)
|
|
|
|
|
{
|
|
|
|
|
myresource = myWin.GetResource();
|
|
|
|
|
}
|
|
|
|
|
if(myresource == null || myWin == null)
|
|
|
|
|
{
|
|
|
|
|
System.Reflection.Assembly MyAssembly;
|
|
|
|
|
MyAssembly = Assembly.GetCallingAssembly();
|
|
|
|
|
myresource = new ResourceManager("EduNetworkBuilder.Resources.languages.edustrings", MyAssembly);
|
|
|
|
|
}
|
|
|
|
|
return myresource;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 18:27:53 +02:00
|
|
|
|
public static NBSettings GetSettings()
|
|
|
|
|
{
|
2017-07-30 21:55:37 +02:00
|
|
|
|
//Try getting the user settings
|
|
|
|
|
PersonClass User = GetUser();
|
|
|
|
|
if (User != null) return User.UserSettings;
|
|
|
|
|
|
|
|
|
|
//If no user, get the settings for the program.
|
2017-06-16 18:27:53 +02:00
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin != null)
|
|
|
|
|
{
|
|
|
|
|
return myWin.OurSettings;
|
|
|
|
|
}
|
|
|
|
|
return new NBSettings(); //This is only in case we are blowing up. Try to avoid that.
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-14 18:34:39 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Determine if we are using Mono or .Net. Some things get killed using Mono.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>True if we are using Mono</returns>
|
|
|
|
|
public static bool IsRunningOnMono()
|
|
|
|
|
{
|
|
|
|
|
return Type.GetType("Mono.Runtime") != null;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static Point GetSnapped(Point Location)
|
|
|
|
|
{
|
|
|
|
|
int x = (Location.X / NB.GridSize) * NB.GridSize;
|
|
|
|
|
int y = (Location.Y / NB.GridSize) * NB.GridSize;
|
|
|
|
|
Point newlocation = new Point(x, y);
|
|
|
|
|
return newlocation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Network GetNetwork()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
if (myWin.GameRandomGen == null) return null;
|
|
|
|
|
return myWin.myNetwork;
|
|
|
|
|
}
|
2016-02-03 20:04:18 +01:00
|
|
|
|
public static void MarkToUpdate()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return;
|
|
|
|
|
myWin.NeedsUpdate = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-23 00:01:56 +01:00
|
|
|
|
public static int nextPacketID()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return 1; //return something.
|
|
|
|
|
return myWin.nextPacketID();
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-08 19:09:22 +02:00
|
|
|
|
public static BuilderWindow GetBuilderWin()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
return myWin;
|
|
|
|
|
}
|
2015-08-01 19:58:53 +02:00
|
|
|
|
|
2017-08-09 16:32:32 +02:00
|
|
|
|
public static PersonProfileForm GetProfileWin()
|
|
|
|
|
{
|
|
|
|
|
PersonProfileForm myWin = (PersonProfileForm)Application.OpenForms["PersonProfileForm"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
return myWin;
|
|
|
|
|
}
|
2017-07-30 01:34:51 +02:00
|
|
|
|
public static PersonClass GetUser()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow BW = GetBuilderWin();
|
|
|
|
|
if (BW == null) return null;
|
|
|
|
|
return BW.CurrentUser;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Return a translated string in the current chosen language
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="key">The key for the item we are translating</param>
|
|
|
|
|
/// <returns>A string of the translated information</returns>
|
2017-06-16 20:03:38 +02:00
|
|
|
|
public static string Translate(string key, NBSettings theSettings=null)
|
2015-08-01 19:58:53 +02:00
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null)
|
|
|
|
|
{
|
|
|
|
|
ResourceManager RM = GetResource();
|
2017-06-16 20:03:38 +02:00
|
|
|
|
CultureInfo CI = GetCulture(theSettings);
|
|
|
|
|
|
2015-08-08 19:09:22 +02:00
|
|
|
|
string answer="";
|
2015-08-01 19:58:53 +02:00
|
|
|
|
answer = RM.GetString(key, CI);
|
2015-08-08 19:09:22 +02:00
|
|
|
|
if (answer == null) return "";
|
2015-08-01 19:58:53 +02:00
|
|
|
|
return answer;
|
|
|
|
|
}
|
|
|
|
|
return myWin.Translate(key);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-08 19:09:22 +02:00
|
|
|
|
public static string GetHelpTopicKey(HelpTopics What)
|
|
|
|
|
{
|
|
|
|
|
return "H_" + What.ToString() + "_Key";
|
|
|
|
|
}
|
|
|
|
|
public static string GetHelpTopicTitle(HelpTopics What)
|
|
|
|
|
{
|
|
|
|
|
return "H_" + What.ToString() + "_Title";
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static DebugPausePoint GetDebugPauseSetting()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return DebugPausePoint.none;
|
|
|
|
|
if (myWin.GameRandomGen == null) return DebugPausePoint.none;
|
|
|
|
|
return myWin.DebugSetting;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static PuzzleInfo GetPuzzleInfoFromName(string PuzzleName)
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
return myWin.PuzzleInfoFromName(PuzzleName);
|
|
|
|
|
}
|
2015-11-21 23:55:03 +01:00
|
|
|
|
|
|
|
|
|
public static string LeftPad(string what, int amount=-1)
|
|
|
|
|
{
|
|
|
|
|
int UseAmount = 10;
|
|
|
|
|
if (amount != -1) UseAmount = amount;
|
|
|
|
|
string format = "{0," + (0 - UseAmount).ToString() + "}";
|
|
|
|
|
string mystring = string.Format(format, what);
|
|
|
|
|
return mystring;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 20:03:38 +02:00
|
|
|
|
public static void ChangeLanguage(NBSettings theSettings=null)
|
2015-08-01 19:58:53 +02:00
|
|
|
|
{
|
|
|
|
|
//Find the window. If it exists, use /set the language setting there. If not, use / set the default.
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
2017-06-16 20:03:38 +02:00
|
|
|
|
NBSettings oursettings;
|
|
|
|
|
|
|
|
|
|
if (theSettings == null) oursettings = NB.GetSettings();
|
|
|
|
|
else oursettings = theSettings;
|
|
|
|
|
|
2017-06-16 18:27:53 +02:00
|
|
|
|
string lang = oursettings.ChosenLanguage;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
if (lang == "") lang = "en";
|
|
|
|
|
|
|
|
|
|
string StartingItem = "";
|
|
|
|
|
for (int i = 0; i < LanguageChoices.GetLength(0); i++)
|
|
|
|
|
{
|
|
|
|
|
if (lang == LanguageChoices[i, 1])
|
|
|
|
|
{
|
|
|
|
|
StartingItem = LanguageChoices[i, 0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//we need to choose a language:
|
|
|
|
|
Form LanguageForm = new Form();
|
2015-11-16 23:14:17 +01:00
|
|
|
|
LanguageForm.Text = NB.Translate("NB_ChangeLang1");
|
2015-08-01 19:58:53 +02:00
|
|
|
|
Label lblText = new Label();
|
|
|
|
|
lblText.Location = new Point(5, 5);
|
|
|
|
|
lblText.AutoSize = true;
|
2015-11-16 23:14:17 +01:00
|
|
|
|
lblText.Text = NB.Translate("NB_ChangeLang2");
|
2015-08-01 19:58:53 +02:00
|
|
|
|
LanguageForm.Icon = Properties.Resources.NBIco;
|
|
|
|
|
|
|
|
|
|
ComboBox cbQuestions = new ComboBox();
|
|
|
|
|
cbQuestions.Location = new Point(lblText.Location.X + lblText.Width + 10, lblText.Location.Y);
|
|
|
|
|
cbQuestions.Width = 60;
|
|
|
|
|
for (int i = 0; i < LanguageChoices.GetLength(0); i++ )
|
|
|
|
|
{
|
|
|
|
|
cbQuestions.Items.Add(LanguageChoices[i,0]);
|
|
|
|
|
}
|
|
|
|
|
if(cbQuestions.Items.Contains(StartingItem))
|
|
|
|
|
{
|
|
|
|
|
cbQuestions.SelectedItem = StartingItem;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cbQuestions.SelectedIndex = 0;
|
|
|
|
|
|
|
|
|
|
LanguageForm.Width = cbQuestions.Location.X + cbQuestions.Width + 70;
|
|
|
|
|
LanguageForm.Height = 90;
|
|
|
|
|
LanguageForm.AutoSize = true;
|
|
|
|
|
|
|
|
|
|
Button btnAccept = new Button();
|
|
|
|
|
btnAccept.Location = new Point(cbQuestions.Location.X, cbQuestions.Location.Y + cbQuestions.Height + 10);
|
2015-11-19 21:49:14 +01:00
|
|
|
|
btnAccept.Text = NB.Translate("_OK");
|
2015-08-01 19:58:53 +02:00
|
|
|
|
btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); };
|
|
|
|
|
|
|
|
|
|
LanguageForm.Controls.Add(lblText);
|
|
|
|
|
LanguageForm.Controls.Add(cbQuestions);
|
|
|
|
|
LanguageForm.Controls.Add(btnAccept);
|
|
|
|
|
|
|
|
|
|
LanguageForm.ShowDialog();
|
|
|
|
|
if (cbQuestions.SelectedIndex >= 0)
|
|
|
|
|
{
|
2017-06-16 18:27:53 +02:00
|
|
|
|
oursettings.LanguageHasBeenChosen = true;
|
2015-08-01 19:58:53 +02:00
|
|
|
|
string mychoice = LanguageChoices[cbQuestions.SelectedIndex, 1];
|
|
|
|
|
if (myWin == null)
|
|
|
|
|
{
|
2017-06-16 18:27:53 +02:00
|
|
|
|
oursettings.ChosenLanguage = mychoice;
|
|
|
|
|
//oursettings.Save(); //We do this when we exit. No need to save it right this instant.
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
myWin.ChosenLanguage = mychoice;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void PlaySound(NBSoundType What)
|
|
|
|
|
{
|
|
|
|
|
SoundPlayer sndClick;
|
|
|
|
|
switch (What)
|
|
|
|
|
{
|
|
|
|
|
case NBSoundType.none:
|
|
|
|
|
break;
|
|
|
|
|
case NBSoundType.success:
|
|
|
|
|
sndClick = new SoundPlayer(Properties.Resources.wavBellDing);
|
|
|
|
|
sndClick.Play();
|
|
|
|
|
break;
|
2015-11-01 14:25:20 +01:00
|
|
|
|
case NBSoundType.saved_failed:
|
|
|
|
|
sndClick = new SoundPlayer(Properties.Resources.noBeep);
|
|
|
|
|
sndClick.Play();
|
|
|
|
|
break;
|
|
|
|
|
case NBSoundType.saved_ok:
|
|
|
|
|
sndClick = new SoundPlayer(Properties.Resources.click);
|
|
|
|
|
sndClick.Play();
|
|
|
|
|
break;
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-30 21:55:37 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Serialize any serializable class to an XML string.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of object</typeparam>
|
|
|
|
|
/// <param name="toSerialize">The object to serialize</param>
|
|
|
|
|
/// <returns>A string containing the serialized object in XML</returns>
|
|
|
|
|
public static string SerializeObject<T>(T toSerialize)
|
|
|
|
|
{
|
|
|
|
|
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
|
|
|
|
|
|
|
|
|
|
using (StringWriter textWriter = new StringWriter())
|
|
|
|
|
{
|
|
|
|
|
xmlSerializer.Serialize(textWriter, toSerialize);
|
|
|
|
|
return textWriter.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Deserialize (oposite of SerializeObject) an object from an xml string.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of object to deserialize</typeparam>
|
|
|
|
|
/// <param name="toDeserialize">the xml string containing the object</param>
|
|
|
|
|
/// <returns>An object of the specified type</returns>
|
|
|
|
|
public static T Deserialize<T>(string toDeserialize)
|
|
|
|
|
{
|
|
|
|
|
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
|
|
|
|
|
StringReader textReader = new StringReader(toDeserialize);
|
|
|
|
|
return (T)xmlSerializer.Deserialize(textReader);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static List<string> GetPuzzleTags()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
return myWin.GetPuzzleTags();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-22 15:01:59 +01:00
|
|
|
|
public static bool PuzzleLevelHasUnsolved(string LevelName)
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return false;
|
|
|
|
|
return myWin.PuzzleLevelHasUnsolved(LevelName);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static List<string> GetPuzzleNames()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return null;
|
|
|
|
|
return myWin.GetPuzzleNames();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void LoadNetworkFromResource(string resource)
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return;
|
|
|
|
|
myWin.LoadNetworkFromResource(resource);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void SetProgress(double HowFar, double total)
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return;
|
|
|
|
|
myWin.SetProgress(HowFar, total);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-03 20:04:18 +01:00
|
|
|
|
public static void UpdateMessages()
|
|
|
|
|
{
|
|
|
|
|
BuilderWindow myWin = (BuilderWindow)Application.OpenForms["BuilderWindow"];
|
|
|
|
|
if (myWin == null) return;
|
|
|
|
|
myWin.UpdateMessages();
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static int GetUniqueIdentifier()
|
|
|
|
|
{
|
|
|
|
|
Network myNet = GetNetwork();
|
|
|
|
|
if(myNet == null)
|
|
|
|
|
{
|
|
|
|
|
//We should never get here. If so, we are in a bad sort of way.
|
|
|
|
|
Random rnd = GetRandom();
|
|
|
|
|
return rnd.Next(1,100);
|
|
|
|
|
}
|
|
|
|
|
return myNet.GetUniqueIdentifier();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Delay(int amount)
|
|
|
|
|
{
|
|
|
|
|
System.Threading.Thread.Sleep(amount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T ParseEnum<T>(string value)
|
|
|
|
|
{
|
2015-08-08 15:12:34 +02:00
|
|
|
|
// Do not initialize this variable here.
|
|
|
|
|
return (T)Enum.Parse(typeof(T), value, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T TryParseEnum<T>(string value, T Default )
|
|
|
|
|
{
|
|
|
|
|
if (!Enum.IsDefined(typeof(T), value))
|
|
|
|
|
return Default;
|
|
|
|
|
|
|
|
|
|
return (T)Enum.Parse(typeof(T), value);
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static GeneralComponentType GetComponentType(NetworkComponent What)
|
|
|
|
|
{
|
|
|
|
|
GeneralComponentType theType = GeneralComponentType.none;
|
|
|
|
|
if(What.GetType().ToString() == "EduNetworkBuilder.NetworkDevice")
|
|
|
|
|
theType = GeneralComponentType.device;
|
|
|
|
|
if (What.GetType().ToString() == "EduNetworkBuilder.NetworkLink")
|
|
|
|
|
theType = GeneralComponentType.link;
|
|
|
|
|
return theType;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-08 15:12:34 +02:00
|
|
|
|
public static void ReadContextHelp(HelpTopics What)
|
|
|
|
|
{
|
2015-08-08 19:09:22 +02:00
|
|
|
|
RTFWindow tForm = null;
|
2015-08-08 15:12:34 +02:00
|
|
|
|
//make a new window if needed
|
2015-08-08 19:09:22 +02:00
|
|
|
|
foreach(Form myfrm in Application.OpenForms)
|
|
|
|
|
{
|
2015-11-16 23:14:17 +01:00
|
|
|
|
if(myfrm.Name == NB.Translate("NB_RdCtxtHelp"))
|
2015-08-08 19:09:22 +02:00
|
|
|
|
{
|
|
|
|
|
//We have a context window
|
|
|
|
|
tForm = (RTFWindow)myfrm;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(tForm == null)
|
|
|
|
|
{
|
|
|
|
|
//We do not have one yet. Make a new one
|
|
|
|
|
tForm = new RTFWindow(RTFWindowContents.help);
|
2015-11-16 23:14:17 +01:00
|
|
|
|
tForm.Name = NB.Translate("NB_RdCtxtHelp");
|
2015-08-08 19:09:22 +02:00
|
|
|
|
}
|
2015-08-08 15:12:34 +02:00
|
|
|
|
//load help
|
2015-08-08 19:09:22 +02:00
|
|
|
|
tForm.Show();
|
2015-08-08 15:12:34 +02:00
|
|
|
|
//Jump to the correct location
|
2015-08-08 19:09:22 +02:00
|
|
|
|
if(tForm != null)
|
|
|
|
|
{
|
|
|
|
|
tForm.JumpToSelection(What);
|
|
|
|
|
}
|
2015-08-08 15:12:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static string GenerateMACAddress()
|
|
|
|
|
{
|
|
|
|
|
var sBuilder = new StringBuilder();
|
|
|
|
|
var random = GetRandom();
|
|
|
|
|
int number;
|
|
|
|
|
byte b;
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
number = random.Next(0, 255);
|
|
|
|
|
b = Convert.ToByte(number);
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
b = setBit(b, 6); //--> set locally administered
|
|
|
|
|
b = unsetBit(b, 7); // --> set unicast
|
|
|
|
|
}
|
|
|
|
|
sBuilder.Append(number.ToString("X2"));
|
|
|
|
|
}
|
|
|
|
|
string mac= sBuilder.ToString().ToUpper();
|
|
|
|
|
if (MAC_Exists(mac))
|
|
|
|
|
return GenerateMACAddress(); //If it already exists, generate another
|
|
|
|
|
return mac;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-27 22:20:32 +02:00
|
|
|
|
public static string TextPromptBox(string Prompt, Icon theIcon=null, bool isPassword = false)
|
|
|
|
|
{
|
|
|
|
|
return TextPromptBox(Prompt, "", "", theIcon, isPassword);
|
|
|
|
|
}
|
|
|
|
|
public static string TextPromptBox(string Prompt, string Title, Icon theIcon = null, bool isPassword=false)
|
|
|
|
|
{
|
|
|
|
|
return TextPromptBox(Prompt, Title, "", theIcon, isPassword);
|
|
|
|
|
}
|
|
|
|
|
public static string TextPromptBox(string Prompt, string Title, string oldtext, Icon theIcon, bool isPassword)
|
|
|
|
|
{
|
|
|
|
|
//we need to choose a language:
|
|
|
|
|
int yspace = 10;
|
|
|
|
|
Form TextInputForm = new Form();
|
2017-08-02 15:30:42 +02:00
|
|
|
|
TextInputForm.Text = Title;
|
2017-07-27 22:20:32 +02:00
|
|
|
|
Label lblText = new Label();
|
|
|
|
|
lblText.Location = new Point(5, 5);
|
|
|
|
|
lblText.AutoSize = true;
|
|
|
|
|
lblText.Text = Prompt;
|
|
|
|
|
if(theIcon != null)
|
|
|
|
|
TextInputForm.Icon = theIcon;
|
|
|
|
|
if (oldtext == null) oldtext = "";
|
|
|
|
|
|
|
|
|
|
TextBox tbEvent = new TextBox();
|
|
|
|
|
tbEvent.Location = new Point(lblText.Location.X, lblText.Location.Y + lblText.Height + yspace);
|
|
|
|
|
tbEvent.Width = 120;
|
|
|
|
|
tbEvent.Text = oldtext;//Populate it with the old data if we can
|
|
|
|
|
if (isPassword)
|
|
|
|
|
tbEvent.PasswordChar = '*';
|
|
|
|
|
|
|
|
|
|
TextInputForm.Width = tbEvent.Location.X + tbEvent.Width + 30;
|
|
|
|
|
TextInputForm.Height = 90;
|
|
|
|
|
TextInputForm.AutoSize = true;
|
|
|
|
|
|
|
|
|
|
Button btnAccept = new Button();
|
|
|
|
|
btnAccept.Location = new Point(tbEvent.Location.X, tbEvent.Location.Y + tbEvent.Height + yspace);
|
|
|
|
|
btnAccept.Text = "OK";
|
|
|
|
|
btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); };
|
|
|
|
|
|
|
|
|
|
Button btnCancel = new Button();
|
|
|
|
|
btnCancel.Location = new Point(btnAccept.Location.X + btnAccept.Width + 10, tbEvent.Location.Y + tbEvent.Height + 10);
|
|
|
|
|
btnCancel.Text = "Cancel";
|
|
|
|
|
btnCancel.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; tbEvent.Text = ""; f.Close(); };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TextInputForm.Controls.Add(lblText);
|
|
|
|
|
TextInputForm.Controls.Add(tbEvent);
|
|
|
|
|
TextInputForm.Controls.Add(btnAccept);
|
|
|
|
|
TextInputForm.Controls.Add(btnCancel);
|
|
|
|
|
|
|
|
|
|
TextInputForm.AcceptButton = btnAccept;
|
|
|
|
|
TextInputForm.CancelButton = btnCancel;
|
|
|
|
|
|
|
|
|
|
TextInputForm.ShowDialog();
|
|
|
|
|
return tbEvent.Text;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-02 15:30:42 +02:00
|
|
|
|
|
|
|
|
|
public static Dictionary<string, bool> CheckPromptBox(Dictionary<string, bool> Checks)
|
|
|
|
|
{
|
|
|
|
|
return CheckPromptBox(Checks, "", null);
|
|
|
|
|
}
|
|
|
|
|
public static Dictionary<string, bool> CheckPromptBox(Dictionary<string, bool> Checks, string Title)
|
|
|
|
|
{
|
|
|
|
|
return CheckPromptBox(Checks, Title, null);
|
|
|
|
|
}
|
|
|
|
|
public static Dictionary<string, bool> CheckPromptBox(Dictionary<string,bool> Checks, string Title, Icon theIcon)
|
|
|
|
|
{
|
|
|
|
|
//we need to choose a language:
|
|
|
|
|
Dictionary<string, bool> responses = new Dictionary<string, bool>();
|
|
|
|
|
|
|
|
|
|
int yspace = 10;
|
|
|
|
|
Form CheckInputForm = new Form();
|
|
|
|
|
CheckInputForm.Text = Title;
|
|
|
|
|
if (theIcon != null)
|
|
|
|
|
CheckInputForm.Icon = theIcon;
|
|
|
|
|
|
2017-08-02 16:01:14 +02:00
|
|
|
|
int startx = 20;
|
2017-08-02 15:30:42 +02:00
|
|
|
|
|
|
|
|
|
int y = 0;
|
|
|
|
|
int lastY = 0;
|
|
|
|
|
int lastHeight = 0;
|
|
|
|
|
foreach(KeyValuePair<string, bool> entry in Checks)
|
|
|
|
|
{
|
|
|
|
|
//Make a checkbox
|
|
|
|
|
CheckBox cb = new CheckBox();
|
|
|
|
|
cb.Name = entry.Key; //Name it so we can know what it is.
|
|
|
|
|
cb.Text = entry.Key; //Have it display the right value for a label
|
|
|
|
|
cb.Checked = entry.Value; //Have it checked, or not, depending on the value we passed in
|
|
|
|
|
|
|
|
|
|
//Put it in the appropriate location
|
|
|
|
|
cb.Location = new Point(startx, (y * (cb.Height + yspace)) + yspace);
|
2017-08-02 16:01:14 +02:00
|
|
|
|
cb.AutoSize = true;
|
2017-08-02 15:30:42 +02:00
|
|
|
|
lastY = cb.Location.Y;
|
|
|
|
|
lastHeight = cb.Height;
|
|
|
|
|
CheckInputForm.Controls.Add(cb);
|
2017-08-02 16:01:14 +02:00
|
|
|
|
y++;
|
2017-08-02 15:30:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CheckInputForm.AutoSize = true;
|
|
|
|
|
|
|
|
|
|
Button btnAccept = new Button();
|
|
|
|
|
btnAccept.Location = new Point(startx, lastY + lastHeight + yspace);
|
|
|
|
|
btnAccept.Text = "OK";
|
|
|
|
|
btnAccept.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; f.Close(); };
|
|
|
|
|
|
|
|
|
|
Button btnCancel = new Button();
|
|
|
|
|
btnCancel.Location = new Point(btnAccept.Location.X + btnAccept.Width + 10,btnAccept.Location.Y);
|
|
|
|
|
btnCancel.Text = "Cancel";
|
|
|
|
|
btnCancel.Click += (s, g) => { Button b = (Button)s; Form f = (Form)b.Parent; responses = null; f.Close(); };
|
|
|
|
|
|
|
|
|
|
CheckInputForm.Controls.Add(btnAccept);
|
|
|
|
|
CheckInputForm.Controls.Add(btnCancel);
|
|
|
|
|
|
|
|
|
|
CheckInputForm.AcceptButton = btnAccept;
|
|
|
|
|
CheckInputForm.CancelButton = btnCancel;
|
2017-08-02 16:01:14 +02:00
|
|
|
|
CheckInputForm.Height = btnCancel.Location.Y + btnCancel.Height + 10;
|
2017-08-02 15:30:42 +02:00
|
|
|
|
|
|
|
|
|
CheckInputForm.ShowDialog();
|
|
|
|
|
foreach (KeyValuePair<string, bool> entry in Checks)
|
|
|
|
|
{
|
2017-08-02 16:01:14 +02:00
|
|
|
|
if(responses != null && CheckInputForm.Controls[entry.Key] != null && CheckInputForm.Controls[entry.Key] is CheckBox)
|
2017-08-02 15:30:42 +02:00
|
|
|
|
{
|
|
|
|
|
CheckBox One = (CheckBox)CheckInputForm.Controls[entry.Key];
|
|
|
|
|
responses.Add(One.Name, One.Checked);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return responses;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
public static bool MAC_Exists(string MAC)
|
|
|
|
|
{
|
|
|
|
|
Network myNet = GetNetwork();
|
|
|
|
|
if(myNet == null) return false;
|
|
|
|
|
return myNet.MAC_Exists(MAC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<string> arp(UInt32 IP)
|
|
|
|
|
{
|
|
|
|
|
List<string> arps = new List<string>();
|
|
|
|
|
Network myNet = GetNetwork();
|
|
|
|
|
if (myNet == null) return arps;
|
|
|
|
|
return myNet.arp(IP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static byte setBit(byte b, int BitNumber)
|
|
|
|
|
{
|
|
|
|
|
if (BitNumber < 8 && BitNumber > -1)
|
|
|
|
|
{
|
|
|
|
|
return (byte)(b | (byte)(0x01 << BitNumber));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException(
|
2015-11-19 13:50:28 +01:00
|
|
|
|
string.Format(NB.Translate("NB_BitError"), BitNumber.ToString()));
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static byte unsetBit(byte b, int BitNumber)
|
|
|
|
|
{
|
|
|
|
|
if (BitNumber < 8 && BitNumber > -1)
|
|
|
|
|
{
|
|
|
|
|
return (byte)(b | (byte)(0x00 << BitNumber));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException(
|
2015-11-19 13:50:28 +01:00
|
|
|
|
string.Format(NB.Translate("NB_BitError"), BitNumber.ToString()));
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Randomize a list
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of list to return</typeparam>
|
|
|
|
|
/// <param name="list">The list to randomize</param>
|
|
|
|
|
/// <returns>a new list that is randomized</returns>
|
|
|
|
|
public static List<T> Randomize<T>(List<T> list)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
List<T> randomizedList = new List<T>(list);
|
|
|
|
|
Random rnd = GetRandom();
|
|
|
|
|
int n = randomizedList.Count;
|
|
|
|
|
int counter = 0;
|
|
|
|
|
T value;
|
|
|
|
|
while (n > 1)
|
|
|
|
|
{
|
|
|
|
|
n--;
|
|
|
|
|
int k = rnd.Next(n + 1);
|
|
|
|
|
value = randomizedList[k];
|
|
|
|
|
randomizedList[k] = randomizedList[n];
|
|
|
|
|
randomizedList[n] = value;
|
|
|
|
|
counter++;
|
|
|
|
|
if (counter > 10)
|
|
|
|
|
{
|
|
|
|
|
counter = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return randomizedList;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-31 18:27:25 +02:00
|
|
|
|
public static List<TreeNode> GetAllNodes(this TreeView _self)
|
|
|
|
|
{
|
|
|
|
|
List<TreeNode> result = new List<TreeNode>();
|
|
|
|
|
foreach (TreeNode child in _self.Nodes)
|
|
|
|
|
{
|
|
|
|
|
result.AddRange(child.GetAllNodes());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
public static List<TreeNode> GetAllNodes(this TreeNode _self)
|
|
|
|
|
{
|
|
|
|
|
List<TreeNode> result = new List<TreeNode>();
|
|
|
|
|
result.Add(_self);
|
|
|
|
|
foreach (TreeNode child in _self.Nodes)
|
|
|
|
|
{
|
|
|
|
|
result.AddRange(child.GetAllNodes());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2017-08-01 21:30:07 +02:00
|
|
|
|
public static bool ValidateString(string tovalidate, string AllowedCharacters)
|
|
|
|
|
{
|
|
|
|
|
if (tovalidate == null || tovalidate == "") return false;
|
|
|
|
|
if (AllowedCharacters == null || AllowedCharacters == "") return false;
|
|
|
|
|
foreach (char one in tovalidate)
|
|
|
|
|
if (!AllowedCharacters.Contains(one)) return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
public static bool ValidatePassword(string password)
|
|
|
|
|
{
|
|
|
|
|
return ValidateString(password, AllowedPasswordCharacters);
|
|
|
|
|
}
|
|
|
|
|
public static bool ValidateUsername(string password)
|
|
|
|
|
{
|
|
|
|
|
return ValidateString(password, AllowedUsernameCharacters);
|
|
|
|
|
}
|
2017-08-01 21:43:55 +02:00
|
|
|
|
public static bool ValidateFullName(string password)
|
|
|
|
|
{
|
|
|
|
|
return ValidateString(password, AllowedUsernameCharacters + " ");
|
|
|
|
|
}
|
2017-07-31 18:27:25 +02:00
|
|
|
|
|
2017-08-02 18:25:26 +02:00
|
|
|
|
public static OpenFileDialog SelectDirectoryDialog(string Title, string InitialDirectory="")
|
|
|
|
|
{
|
|
|
|
|
OpenFileDialog OFD = new OpenFileDialog();
|
|
|
|
|
OFD.Title = Title;
|
|
|
|
|
if (InitialDirectory != "")
|
|
|
|
|
OFD.InitialDirectory = InitialDirectory;
|
|
|
|
|
OFD.ValidateNames = false;
|
|
|
|
|
OFD.CheckFileExists = false;
|
|
|
|
|
OFD.CheckPathExists = true;
|
|
|
|
|
OFD.FileName = NB.Translate("PPF_SelectThisFolder");
|
|
|
|
|
DialogResult answer = OFD.ShowDialog();
|
|
|
|
|
if (answer == DialogResult.Cancel) OFD.FileName = ""; //This is how we cancel out
|
|
|
|
|
return OFD;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-05 19:41:42 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Move a file out of the way, making a rotating backup at the same time.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="SourceFileWithDir">A source filename with a directory</param>
|
|
|
|
|
/// <param name="DestDir">The directory where to put the file</param>
|
|
|
|
|
/// <param name="rotation">The number of rotation backups to make</param>
|
|
|
|
|
public static void MoveFileWithRotation(string SourceFileWithDir, string DestDir, int rotation)
|
|
|
|
|
{
|
|
|
|
|
if (!File.Exists(SourceFileWithDir)) return; //we do not rotate if the source does not exist
|
|
|
|
|
if (!Directory.Exists(DestDir))
|
|
|
|
|
Directory.CreateDirectory(DestDir);
|
|
|
|
|
//Rotate the old file first, then move the new one over.
|
|
|
|
|
string dest_file = Path.Combine(DestDir, Path.GetFileName(SourceFileWithDir));
|
|
|
|
|
RotateFile(dest_file, rotation);
|
|
|
|
|
File.Move(SourceFileWithDir, dest_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Move a file out of the way, making a rotating backup at the same time. backup to appdata
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="SourceFileWithDir">A source filename with a directory</param>
|
|
|
|
|
/// <param name="rotation">The number of rotation backups to make</param>
|
|
|
|
|
public static void MoveFileWithRotation(string SourceFileWithDir, int rotation)
|
|
|
|
|
{
|
|
|
|
|
string StandardDest = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EduNetworkBuilder");
|
|
|
|
|
MoveFileWithRotation(SourceFileWithDir, StandardDest, rotation);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-05 20:11:26 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Move a file out of the way, making a rotating backup at the same time. backup to appdata
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="SourceFileWithDir">A source filename with a directory</param>
|
|
|
|
|
public static void MoveFileWithRotation(string SourceFileWithDir)
|
|
|
|
|
{
|
|
|
|
|
string StandardDest = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EduNetworkBuilder");
|
|
|
|
|
MoveFileWithRotation(SourceFileWithDir, StandardDest, NB.NormalRotation);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-05 19:41:42 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Given a file, rotate it with the specified number of versions.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="filename"></param>
|
|
|
|
|
/// <param name="count"></param>
|
|
|
|
|
public static void RotateFile(string filename, int count)
|
|
|
|
|
{
|
|
|
|
|
if (count < 1) return;
|
|
|
|
|
string currentfile = GenFilenameWithInt(filename, count);
|
|
|
|
|
string rotatefile;
|
|
|
|
|
if (File.Exists(currentfile)) File.Delete(currentfile); //The last rotation gets deleted
|
|
|
|
|
for(int i=count -1; i >= 1; i--)
|
|
|
|
|
{
|
|
|
|
|
currentfile = GenFilenameWithInt(filename, i);
|
|
|
|
|
rotatefile = GenFilenameWithInt(filename, i + 1);
|
|
|
|
|
if (File.Exists(currentfile))
|
|
|
|
|
File.Move(currentfile, rotatefile);
|
|
|
|
|
}
|
|
|
|
|
//The final case is when there is no version number on the file.
|
|
|
|
|
currentfile = filename;
|
|
|
|
|
rotatefile = GenFilenameWithInt(filename, 1);
|
|
|
|
|
if (File.Exists(currentfile))
|
|
|
|
|
File.Move(currentfile, rotatefile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string GenFilenameWithInt(string filename, int version)
|
|
|
|
|
{
|
|
|
|
|
string FileOnly = Path.GetFileNameWithoutExtension(filename);
|
|
|
|
|
string FileWithInt = FileOnly + "-" + version.ToString("00") + Path.GetExtension(filename);
|
|
|
|
|
string Combined = Path.Combine(Path.GetDirectoryName(filename), FileWithInt);
|
|
|
|
|
return Combined;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-09 16:32:32 +02:00
|
|
|
|
public static Font GetFont()
|
|
|
|
|
{
|
|
|
|
|
PersonProfileForm PPF = GetProfileWin();
|
|
|
|
|
if (PPF != null) return PPF.GetFont();
|
|
|
|
|
return new Font(FontFamily.GenericSansSerif, 10.0F, FontStyle.Bold);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-02 23:57:04 +02:00
|
|
|
|
public static void NotImplimentedMessage()
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(Translate("NB_NotImplimented"));
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-10 23:07:33 +02:00
|
|
|
|
public static string CSVSafeString(string source)
|
|
|
|
|
{
|
|
|
|
|
string dest = source;
|
|
|
|
|
char[] chars = { '\t', '\r', '\n', '\"', ',' };
|
|
|
|
|
|
|
|
|
|
if (dest.IndexOfAny(chars) >= 0)
|
|
|
|
|
{
|
|
|
|
|
dest = '\"' + dest.Replace("\"", "\"\"") + '\"'; //quotes around outside, replace " with ""
|
|
|
|
|
}
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 19:58:53 +02:00
|
|
|
|
}
|
|
|
|
|
}
|