public void Stop() { //EventCommunicator.SendSimStopEvent(); //handshakeManagerThread.Abort(); if (coordinatorThread != null) { coordinatorThread.Abort(); } if (eCommReceiver != null) { eCommReceiver.Abort(); } //textChatServerThread.Abort(); HappeningList.Happenings.Clear(); TimerQueueClass.Clear(); IncomingList.Clear(); Genealogy.Clear(); StatesForUnits.Clear(); UnitFacts.CurrentUnitStates.Clear(); UnitFacts.ClearDMTables(); UnitFacts.Data.Clear(); ChatRooms.DropAllRooms(); VoiceChannels.DropAllChannels(); WhiteboardRooms.DropAllRooms(); TimerControl((int)TimerControls.Reset); // ScenarioToQueues.Reset(); WeaponTable.Clear(); NetworkTable.Clear(); SubplatformRecords.Clear(); Engrams.Clear(); Scores.Clear(); DebugLogger.StopLogging(); NameLists.Clear(); DecisionMakerType.ClearDMTable(); SpeciesType.ClearSpeciesTable(); Metronome.GetInstance().CleanupMetronome(); }
/// <summary> /// Creates the class (one instance only) that parses a scenario and puts events on queues /// </summary> /// <param name="scenarioFile"></param> public ScenarioToQueues(string scenarioFile, string schemaFile) { TimerQueueClass timerQueue = new TimerQueueClass(); // Extract fields from the XML file (and schema) // see http://weblogs.asp.net/dbrowning/articles/114561.aspx // paths to xml/xsd // const string path = @"C:\Documents and Settings\dgeller\My Documents\Visual Studio 2005\Projects\"; //const string scenarioFile = path + @"DDD\Scenario.xml"; // const string xsdPath = path + @"XMLTrial\XMLTrial\ScenarioSchema.xsd"; FileStream fs; Boolean returnVal; // ScenarioToQueues.schemaFile = schemaFile; // try // { returnVal = ValidateScenario(scenarioFile); // } /* catch (System.Exception e) * { * * string message = "Failed to validate schema. " + e.Message; * Coordinator.debugLogger.LogException("Scenario Reader", message); * throw new ApplicationException(message, e); * }*/ if (!returnVal) { return; } try { fs = File.Open(scenarioFile, FileMode.Open); } catch (System.Exception e) { string message = "Could not open scenario file on pass 2." + e.Message; Coordinator.debugLogger.LogException("Scenario Reader", message); throw new ApplicationException(message, e); } /// XmlReader readerTwo; try { XmlSchemaSet sc = new XmlSchemaSet(); sc.Add(null, ScenarioToQueues.namedSchemaFile);//+".xsd"); XmlReaderSettings readerSettings = new XmlReaderSettings(); // readerSettings.ValidationType = ValidationType.Schema; readerSettings.IgnoreWhitespace = true; // makes no difference ?! readerSettings.IgnoreWhitespace = true; // readerSettings.ValidationEventHandler += new ValidationEventHandler(SchemaValidationHandler); reader = XmlReader.Create(fs, readerSettings); parser.SetReader(reader); } catch (System.Exception e) { fs.Close(); string message = "Could not open schema file. " + e.Message; Coordinator.debugLogger.LogException("Scenario Reader", message); throw new ApplicationException(message, e); } //Build reverse dictionary of commnds->stage //This lets us enforce moving through the commands in a prescribed order Dictionary <string, int> stages = new Dictionary <string, int>(); string[][] stageMembers = parser.StageMembers(); for (int level = 0; level < stageMembers.Length; level++) { for (int member = 0; member < stageMembers[level].Length; member++) { stages[stageMembers[level][member]] = level; } } int currentStage = 0; string scenarioName = ""; string description = ""; reader.Read(); // opens, gets to xml declaration reader.Read(); try { if ("Scenario" == reader.Name) // only Scenario can be top level { reader.Read(); // pass by "Scenario" while (!reader.EOF && !((XmlNodeType.EndElement == reader.NodeType) && ("Scenario" == reader.Name))) { //Coordinator.debugLogger.Writeline("."); switch (reader.NodeType) { case XmlNodeType.Element: Coordinator.debugLogger.Writeline("ScenarioToQueues", "ELEMENT " + reader.Name, "test"); if (stages.ContainsKey(reader.Name)) { if (stages[reader.Name] < currentStage) { throw new ApplicationException("Command " + reader.Name + " out of sequence."); } currentStage = stages[reader.Name]; //NB, if command is not found in stages it will be trapped in the switch's default } switch (reader.Name) { case "ScenarioName": scenarioName = parser.pGetString(); break; case "Description": description = parser.pGetString(); break; case "ClientSideAssetTransfer": ClientSideAssetTransferType assetTransfers = new ClientSideAssetTransferType(parser.pGetBoolean()); TimerQueueClass.SendBeforeStartup(assetTransfers); Coordinator.debugLogger.Writeline("ScenarioToQueues", " ClientSideAssetTransferType ", "test"); break; case "ClientSideStartingLabelVisible": ClientSideStartingLabelVisibleType labelsVisible = new ClientSideStartingLabelVisibleType(parser.pGetBoolean()); TimerQueueClass.SendBeforeStartup(labelsVisible); Coordinator.debugLogger.Writeline("ScenarioToQueues", " ClientSideStartingLabelVisibleType ", "test"); break; case "ClientSideRangeRingVisibility": ClientSideRangeRingVisibilityType rangeRingVisibility = new ClientSideRangeRingVisibilityType(parser.pGetString()); TimerQueueClass.SendBeforeStartup(rangeRingVisibility); Coordinator.debugLogger.Writeline("ScenarioToQueues", "ClientSideRangeRingVisibilityType", "test"); break; case "Playfield": // except for the optional name/description // Playfield must be first scenario item sent // enforced by schema string errorText = string.Empty; string imgLibPath = string.Empty; string mapFilePath = string.Empty; string hostname = Aptima.Asim.DDD.CommonComponents.ServerOptionsTools.ServerOptions.HostName; pPlayfieldType pDefine = parser.pGetPlayfield(); PlayfieldEventType playfield = new PlayfieldEventType(pDefine); playfield.ScenarioName = scenarioName; playfield.Description = description; if (playfield.IconLibrary.EndsWith(".dll")) { imgLibPath = String.Format(@"\\{0}\{1}", ServerOptions.DDDClientPath, playfield.IconLibrary); //icon library does include dll extension } else { imgLibPath = String.Format(@"\\{0}\{1}.dll", ServerOptions.DDDClientPath, playfield.IconLibrary); //icon library doesnt include dll extension } mapFilePath = String.Format(@"\\{0}\MapLib\{1}", ServerOptions.DDDClientPath, playfield.MapFileName); //map file includes file extension //check image library path if (!File.Exists(imgLibPath)) { if (System.Windows.Forms.MessageBox.Show(String.Format("The server was not able to locate the image library in {0}. There is a chance that clients connecting to this machine will have a similar issue locating this file. If you'd still like to run the simulation, click Yes. If you'd like to stop the server, click No.", imgLibPath), "File not found", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes) { //User wants to continue } else { //user wants to stop server throw new Exception("User Cancelled server process. Server was unable to locate the image library at " + imgLibPath); return; } } //check map file path if (!File.Exists(mapFilePath)) { if (System.Windows.Forms.MessageBox.Show(String.Format("The server was not able to locate the map file in {0}. There is a chance that clients connecting to this machine will have a similar issue locating this file. If you'd still like to run the simulation, click Yes. If you'd like to stop the server, click No.", mapFilePath), "File not found", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes) { //User wants to continue } else { //user wants to stop server throw new Exception("User Cancelled server process. Server was unable to locate the map file at " + mapFilePath); return; } } TimerQueueClass.SendBeforeStartup(playfield); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Playfield", "test"); TimerQueueClass.SendBeforeStartup(new RandomSeedType()); break; case "LandRegion": pLandRegionType region = parser.pGetLandRegion(); RegionEventType regionEvent = new RegionEventType(region); TimerQueueClass.SendBeforeStartup(regionEvent); Coordinator.debugLogger.Writeline("ScenarioToQueues", " LandRegion " + regionEvent.UnitID, "test"); break; /* * case "ScoringRegion": * pScoringRegionType regionS = parser.pGetScoringRegion(); * RegionEventType regionEventS = new RegionEventType(regionS); * TimerQueueClass.SendBeforeStartup(regionEventS); * Coordinator.debugLogger.Writeline("ScenarioToQueues", " ScoringRegion " + regionEventS.UnitID, "test"); * break; */ case "ActiveRegion": pActiveRegionType regionA = parser.pGetActiveRegion(); RegionEventType regionEventA = new RegionEventType(regionA); if (!NameLists.activeRegionNames.New(regionA.ID, regionEventA)) { throw new ApplicationException("Duplicate active region name " + regionA.ID); } TimerQueueClass.SendBeforeStartup(regionEventA); Coordinator.debugLogger.Writeline("ScenarioToQueues", " ActiveRegion " + regionEventA.UnitID, "test"); break; case "Team": pTeamType team = parser.pGetTeam(); TeamType teamEvent = new TeamType(team); for (int i = 0; i < teamEvent.Count(); i++) { UnitFacts.AddEnemy(teamEvent.Name, teamEvent.GetEnemy(i)); } Coordinator.debugLogger.Writeline("ScenarioToQueues", " Team " + team.Name.ToString(), "test"); if (!NameLists.teamNames.New(team.Name, teamEvent)) { throw new ApplicationException("Duplicate team name " + team.Name); } TimerQueueClass.SendBeforeStartup(teamEvent); break; case "DecisionMaker": DecisionMakerType decisionMaker = new DecisionMakerType(parser.pGetDecisionMaker()); UnitFacts.AddDM(decisionMaker.Identifier, decisionMaker.Chroma, decisionMaker.Team); TimerQueueClass.SendBeforeStartup(decisionMaker); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Decision Maker ", "test"); break; case "Network": NetworkType network = new NetworkType(parser.pGetNetwork()); NetworkTable.AddNetwork(network); TimerQueueClass.SendBeforeStartup(network); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Network ", "test"); break; case "Sensor": //sensor follows Playfield pSensor sen = parser.pGetSensor(); // if Attribute is "all" there will be one cone; only extent is filled in from parser if (sen.Attribute == "All") { sen.Cones[0].Spread = 360; sen.Cones[0].Level = "Total"; } SensorTable.Add(sen.Name, new SensorType(sen.Attribute, sen.IsEngram, sen.TypeIfEngram, sen.Cones)); Coordinator.debugLogger.Writeline("ScenarioToQueues", " Sensor " + sen.Name.ToString(), "test"); break; /* case "TimeToRemove": * Defaults.DefaultTimeToRemove = parser.pGetInt(); * break; */ case "Classifications": ClassificationsType classifications = new ClassificationsType(parser.pGetClassifications()); TimerQueueClass.SendBeforeStartup(classifications); Coordinator.debugLogger.Writeline("ScenarioToQueues", " Classifications ", "test"); break; case "TimeToAttack": Defaults.DefaultTimeToAttack = parser.pGetInt() * 1000; break; case "Genus": pGenusType g = parser.pGetGenus(); if (!NameLists.speciesNames.New(g.Name, g)) { throw new ApplicationException("Duplicate use of genus name " + g.Name); } Genealogy.Add(g.Name); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Genus " + g.Name, "test"); // StartupForUnits.Add(genus); break; case "Species": // Genus and species come after playfield pSpeciesType s = parser.pGetSpecies(); SpeciesType species = new SpeciesType(s); if (!NameLists.speciesNames.New(species.Name, species)) { throw new ApplicationException("Duplicate use of species name " + species.Name); } Genealogy.Add(species.Name, species.BasedOn); if (species.IsWeapon) { WeaponTable.Add(species.Name); } WorkStates.Clear(); WorkStates.Add(species.States); StatesForUnits.AddStatesOf(species.Name, WorkStates.CollapseStates(species.Name, species.BasedOn)); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Species " + s.Name, "test"); // StartupForUnits.Add(species); break; case "Create_Event": //string newId; // Create_EventType platformCreate;//used for sub platforms pCreateType c = parser.pGetCreate(); Create_EventType createEvent = new Create_EventType(c); Genealogy.Add(createEvent.UnitID, createEvent.UnitBase); createEvent.Genus = Genealogy.GetGenus(createEvent.UnitID); UnitFacts.AddUnit(createEvent.UnitID, createEvent.Owner, createEvent.UnitBase); createEvent.Parameters = new ObjectDictionary(); SpeciesType speciesInfo = (SpeciesType)NameLists.speciesNames[createEvent.UnitBase]; foreach (KeyValuePair <string, StateBody> kvp in StatesForUnits.StateTable[createEvent.UnitBase]) { string stateName = kvp.Key; ExtendedStateBody extended = new ExtendedStateBody(kvp.Value); //end species dependent atts createEvent.Parameters.Add(stateName, (object)extended); // EngramDependants.Add(createEvent.UnitID, extended); } // TimerQueueClass.Add(1, createEvent); NameLists.unitNames.New(createEvent.UnitID, null); TimerQueueClass.SecondarySendBeforeStartup(createEvent); UnitFacts.CurrentUnitStates.Add(createEvent.UnitID, ""); Coordinator.debugLogger.Writeline("ScenarioToQueues", "createEvent for " + createEvent.UnitID, "test"); //for some reason this docs everyone at time 1. this seems to be the heart of the bug /* * for (int i = 0; i < createEvent.Subplatforms.Count;i++ ) * { * SubplatformDockType dockNotice = new SubplatformDockType(createEvent.Subplatforms[i], createEvent.UnitID); * dockNotice.Time = 1; * TimerQueueClass.SecondarySendBeforeStartup(dockNotice); * * } */ break; case "Reveal_Event": pRevealType r = parser.pGetReveal(); Reveal_EventType revealEvent = new Reveal_EventType(r); revealEvent.Genus = Genealogy.GetGenus(revealEvent.UnitID); if (r.Time > 1) { TimerQueueClass.Add(r.Time, revealEvent); } else { TimerQueueClass.SecondarySendBeforeStartup(revealEvent); } Coordinator.debugLogger.Writeline("ScenarioToQueues", "revealEvent for " + revealEvent.UnitID + " at time" + r.Time.ToString(), "test"); RevealDocked(r.UnitID, r.Time); break; case "Move_Event": pMoveType m = parser.pGetMove(); if (!UnitFacts.IsAUnit(m.UnitID)) { throw new ApplicationException("Cannot move non-exsitant unit " + m.UnitID); } Move_EventType moveEvent = new Move_EventType(m); TimerQueueClass.Add(moveEvent.Time, moveEvent); Coordinator.debugLogger.Writeline("ScenarioToQueues", " moveEvent for " + moveEvent.UnitID, "test"); break; case "Completion_Event": HappeningCompletionType completionType = new HappeningCompletionType(parser.pGetHappeningCompletion()); HappeningList.Add(completionType); break; case "Species_Completion_Event": pSpeciesCompletionType sct = parser.pGetSpeciesCompletion(); SpeciesCompletionType speciesCompletion = new SpeciesCompletionType(sct); SpeciesHappeningList.Add(speciesCompletion); break; case "Reiterate": ReiterateType reiterate = new ReiterateType(parser.pGetReiterate()); Move_EventType mQueued = (Move_EventType)(reiterate.ReiterateList[0]); Move_EventType mQCopy = (Move_EventType)(reiterate.ReiterateList[0]); mQueued.Range = reiterate.Range; mQueued.Time = reiterate.Time; TimerQueueClass.Add(mQueued.Time, mQueued); Coordinator.debugLogger.Writeline("ScenarioToQueues", " moveEvent from reiterate for " + mQueued.UnitID, "test"); reiterate.ReiterateList.RemoveAt(0); reiterate.ReiterateList.Add(mQCopy); HappeningCompletionType envelope = new HappeningCompletionType(reiterate); HappeningList.Add(envelope); break; case "StateChange_Event": StateChangeEvent change = new StateChangeEvent(parser.pGetStateChange()); if (!UnitFacts.IsAUnit(change.UnitID)) { throw new ApplicationException("State change event references unknown unit " + change.UnitID); } if (!StatesForUnits.UnitHasState(change.UnitID, change.NewState)) { throw new ApplicationException("State chage for " + change.UnitID + " refers to unknwon state " + change.NewState); } for (int i = 0; i < change.Except.Count; i++) { // if (!StatesForUnits.UnitHasState(Genealogy.GetBase(change.UnitID), change.Except[i])) throw new ApplicationException("State change for " + change.UnitID + " refers to unknown state " + change.Except); if (!StatesForUnits.UnitHasState(change.UnitID, change.Except[i])) { throw new ApplicationException("State change for " + change.UnitID + " refers to unknown state " + change.Except); } } for (int i = 0; i < change.From.Count; i++) { // if (!StatesForUnits.UnitHasState(Genealogy.GetBase(change.UnitID), change.From[i])) throw new ApplicationException("State change for " + change.UnitID + " refers to unknown state " + change.From); if (!StatesForUnits.UnitHasState(change.UnitID, change.From[i])) { throw new ApplicationException("State change for " + change.UnitID + " refers to unknown state " + change.From); } } TimerQueueClass.Add(change.Time, change); break; case "Transfer_Event": TransferEvent t = new TransferEvent(parser.pGetTransfer()); if (!UnitFacts.IsDM(t.From)) { throw new ApplicationException("Transfer event references unknown DM (from) " + t.From); } if (!UnitFacts.IsDM(t.To)) { throw new ApplicationException("Transfer event references unknown DM (to) " + t.To); } if (!UnitFacts.IsAUnit(t.UnitID)) { throw new ApplicationException("Transfer event references unknown unit " + t.UnitID); } TimerQueueClass.Add(t.Time, t); break; case "Launch_Event": LaunchEventType launch = new LaunchEventType(parser.pGetLaunch()); if (!UnitFacts.IsAUnit(launch.UnitID)) { throw new ApplicationException("Cannot launch from non-existent unit " + launch.UnitID); } TimerQueueClass.Add(launch.Time, launch); break; case "WeaponLaunch_Event": WeaponLaunchEventType weaponLaunch = new WeaponLaunchEventType(parser.pGetWeaponLaunch()); if (!UnitFacts.IsAUnit(weaponLaunch.UnitID)) { throw new ApplicationException("Cannot launch from non-existent unit " + weaponLaunch.UnitID); } TimerQueueClass.Add(weaponLaunch.Time, weaponLaunch); break; case "DefineEngram": pDefineEngramType defineEngram = parser.pGetDefineEngram(); Engrams.Create(defineEngram.Name, defineEngram.EngramValue, defineEngram.Type); TimerQueueClass.SendBeforeStartup(new EngramSettingType(defineEngram.Name, "", defineEngram.EngramValue, defineEngram.Type)); break; case "ChangeEngram": ChangeEngramType changeEngram = new ChangeEngramType(parser.pGetChangeEngram()); if (!Engrams.ValidUpdate(changeEngram.Name, changeEngram.EngramValue)) { throw new ApplicationException("Illegal value " + changeEngram.EngramValue + " for engram " + changeEngram.Name); } TimerQueueClass.Add(changeEngram.Time, changeEngram); // Engrams.SendUpdate(changeEngram.Name); break; case "RemoveEngram": RemoveEngramEvent removeEngram = new RemoveEngramEvent(parser.pGetRemoveEngram()); TimerQueueClass.Add(removeEngram.Time, removeEngram); break; //These chat commands are those from the scenario only; // thos from client are handled immediately case "OpenChatRoom": OpenChatRoomType openChatRoom = new OpenChatRoomType(parser.pGetOpenChatRoom()); TimerQueueClass.Add(openChatRoom.Time, openChatRoom); break; case "CloseChatRoom": CloseChatRoomType closeChatRoom = new CloseChatRoomType(parser.pGetCloseChatRoom()); TimerQueueClass.Add(closeChatRoom.Time, closeChatRoom); break; /* Not implemented yet * case "DropChatters": * DropChattersType dropChatters = new DropChattersType(parser.pGetDropChatters()); * TimerQueueClass.Add(dropChatters.Time, dropChatters); * break; * case "AddChatters": * AddChattersType addChatters = new AddChattersType(parser.pGetAddChatters()); * TimerQueueClass.Add(addChatters.Time, addChatters); * break; * */ case "OpenWhiteboardRoom": OpenWhiteboardRoomType openWhiteboardRoom = new OpenWhiteboardRoomType(parser.pGetOpenWhiteboardRoom()); TimerQueueClass.Add(openWhiteboardRoom.Time, openWhiteboardRoom); break; case "OpenVoiceChannel": OpenVoiceChannelType openVoiceChannel = new OpenVoiceChannelType(parser.pGetOpenVoiceChannel()); TimerQueueClass.Add(openVoiceChannel.Time, openVoiceChannel); break; case "CloseVoiceChannel": CloseVoiceChannelType closeVoiceChannel = new CloseVoiceChannelType(parser.pGetCloseVoiceChannel()); TimerQueueClass.Add(closeVoiceChannel.Time, closeVoiceChannel); break; /* * //Removed before 4.1 * case "GrantVoiceChannelAccess": * GrantVoiceAccessType grantVoiceChannelAccess = new GrantVoiceAccessType(parser.pGetGrantVoiceChannelAccess()); * TimerQueueClass.Add(grantVoiceChannelAccess.Time, grantVoiceChannelAccess); * break; * case "RemoveVoiceChannelAccess": * RemoveVoiceAccessType removeVoiceChannelAccess = new RemoveVoiceAccessType(parser.pGetRemoveVoiceChannelAccess()); * TimerQueueClass.Add(removeVoiceChannelAccess.Time, removeVoiceChannelAccess); * break; */ case "Rule": pScoringRuleType srt = parser.pGetScoringRule(); ScoringRuleType scoreRule = new ScoringRuleType(srt); if (!NameLists.ruleNames.New(srt.Name, scoreRule)) { throw new ApplicationException("Duplicate scoring rule name " + srt.Name); } ScoringRules.Add(scoreRule); break; case "Score": pScoreType pst = parser.pGetScore(); ScoreType st = new ScoreType(pst); if (!NameLists.scoreNames.New(pst.Name, st)) { throw new ApplicationException("Duplicate score name " + pst.Name); } Scores.Register(st); break; case "FlushEvents": FlushEvents flush = new FlushEvents(parser.pGetFlushEventsType()); TimerQueueClass.Add(flush.Time, flush); break; case "SendChatMessage": SendChatMessageType sendChat = new SendChatMessageType(parser.pGetSendChatMessage()); if (!UnitFacts.IsDM(sendChat.Sender) && !("EXP" == sendChat.Sender)) { throw new ApplicationException("In SendChatMessage, '" + sendChat.Sender + "' is not a valid DM name."); } // Note: Can't validate chat room name at parse time; it might not have been created yet TimerQueueClass.Add(sendChat.Time, sendChat); break; case "Apply": ApplyType apply = new ApplyType(parser.pGetApply()); //what does this do? TimerQueueClass.Add(apply.Time, apply); break; case "SendVoiceMessage": SendVoiceMessageType playVoiceMessage = new SendVoiceMessageType(parser.pGetSendVoiceMessage()); //what does this do? TimerQueueClass.Add(playVoiceMessage.Time, playVoiceMessage); break; case "SendVoiceMessageToUser": SendVoiceMessageToUserType playVoiceMessageToUser = new SendVoiceMessageToUserType(parser.pGetSendVoiceMessageToUser()); //what does this do? TimerQueueClass.Add(playVoiceMessageToUser.Time, playVoiceMessageToUser); break; default: throw new ApplicationException("ScenarioToQueues: Unknown Scenario Element is *" + reader.Name); } //switch break; default: Coordinator.debugLogger.Writeline("ScenarioToQueues", "Unhandled or out-of-sequence XML tag " + reader.Value, "test"); reader.Read(); break; } //switch } //while // All of scenario processed. Now do last things //verify that the Chat, Whiteboard, and Voice lists contain only DMs and make them symmetric. List <string> allDMs = UnitFacts.GetAllDms(); for (int i = 0; i < allDMs.Count; i++) { DecisionMakerType thisDM = DecisionMakerType.GetDM(allDMs[i]); for (int j = 0; j < thisDM.ChatPartners.Count; j++) { if (!allDMs.Contains(thisDM.ChatPartners[j])) { throw new ApplicationException("Unknown decision maker name '" + thisDM.ChatPartners[j] + "' found as chat partner of '" + allDMs[i] + "'"); } DecisionMakerType partnerDM = DecisionMakerType.GetDM(thisDM.ChatPartners[j]); if (!partnerDM.ChatPartners.Contains(allDMs[i])) { partnerDM.MayChatWith(allDMs[i]); } } for (int j = 0; j < thisDM.WhiteboardPartners.Count; j++) { if (!allDMs.Contains(thisDM.WhiteboardPartners[j])) { throw new ApplicationException("Unknown decision maker name '" + thisDM.WhiteboardPartners[j] + "' found as whiteboard partner of '" + allDMs[i] + "'"); } DecisionMakerType partnerDM = DecisionMakerType.GetDM(thisDM.WhiteboardPartners[j]); if (!partnerDM.WhiteboardPartners.Contains(allDMs[i])) { partnerDM.MayWhiteboardWith(allDMs[i]); } } for (int j = 0; j < thisDM.VoicePartners.Count; j++) { if (!allDMs.Contains(thisDM.ChatPartners[j])) { throw new ApplicationException("Unknown decision maker name '" + thisDM.VoicePartners[j] + "' found as voice partner of '" + allDMs[i] + "'"); } DecisionMakerType partnerDM = DecisionMakerType.GetDM(thisDM.VoicePartners[j]); if (!partnerDM.VoicePartners.Contains(allDMs[i])) { partnerDM.MaySpeakWith(allDMs[i]); } } } // Add networks for DMs that have none List <string> dmList = UnitFacts.GetAllDms(); for (int nextDM = 0; nextDM < dmList.Count; nextDM++) { if (!NetworkTable.IsNetworkMember(dmList[nextDM])) { string netName = "Network-For-" + dmList[nextDM]; NetworkTable.AddMember(netName, dmList[nextDM]); NetworkType newNet = new NetworkType(netName); newNet.Add(dmList[nextDM]); TimerQueueClass.SendBeforeStartup(newNet); Coordinator.debugLogger.Writeline("ScenarioToQueues", "Network ", "test"); } } //AD: Don't create default chat room, user should have control of this // Create the detault Broadcast chatroom //OpenChatRoomType broadcastChatRoom = new OpenChatRoomType(1, "", "Broadcast", dmList); //TimerQueueClass.SendBeforeStartup(broadcastChatRoom); }//if } catch (System.Exception e) { if (e.Message.StartsWith("User Cancelled")) {//This means a missing map or icon library, and the user wanted to stop the server. Do not write to error log, just stop the server. throw e; } string message = "Failure in Parsing Control for next tag=" + reader.Name + " : " + e.Message; Coordinator.debugLogger.LogException("ScenarioReader", message); throw new ApplicationException(message, e); } finally { reader.Close(); fs.Close(); // Coordinator.debugLogger.Writeline("ScenarioToQueues", "Done", "general"); } }//
public static Boolean AttackApproved(ScenarioEventType s) { Boolean returnValue = false; /* * Approval algorithm; * If there are no matches on list, return check default condition * If there are any matches then any one that gives permission is enough * */ Boolean denied = false; if ("Aptima.Asim.DDD.ScenarioController.AttackObjectRequestType" != s.GetType().ToString()) { return(returnValue); } AttackObjectRequestType alias = (AttackObjectRequestType)s; for (int i = 0; i < approvals.Count; i++) { ScenarioEventType candidate = approvals[i]; if ("Aptima.Asim.DDD.ScenarioController.AttackRequestApprovalType" != candidate.GetType().ToString()) { continue; } AttackRequestApprovalType rule = (AttackRequestApprovalType)candidate; if (rule.Capability != alias.CapabilityName) { continue; } if (rule.Actor != "") { if ((!rule.ActorIsSpecies) && (rule.Actor != alias.UnitID)) { continue; } if (rule.ActorIsSpecies && !Genealogy.UnderSpecies(alias.UnitID, rule.Actor)) { continue; } } if (rule.Target != "") { if ((!rule.TargetIsSpecies) && (rule.Target != alias.TargetObjectID)) { continue; } if (rule.TargetIsSpecies && !Genealogy.UnderSpecies(alias.TargetObjectID, rule.Target)) { continue; } } if (rule.TargetStates.Count != 0) { if (!rule.TargetStates.Contains(UnitFacts.CurrentUnitStates[alias.TargetObjectID])) { continue; } } // At this point we can say that the rule legitimaly refers to alias.UnitID if (!rule.EngramValid(alias.UnitID, alias.TargetObjectID)) { denied = true; continue; } if ((rule.UseDefault) && (alias.DecisionMaker != UnitFacts.GetDM(alias.UnitID))) { denied = true; continue; } //Wow. This rule was passed returnValue = true; break; } if (!returnValue && !denied) {// Now use the default rule DecisionMakerType unitDM = DecisionMakerType.GetDM(UnitFacts.GetDM(alias.UnitID)); if ( (alias.DecisionMaker == unitDM.Identifier) // && //(UnitFacts.HostileTo(unitDM.Team, DecisionMakerType.GetDM(UnitFacts.GetDM(alias.TargetObjectID)).Team)) //AD: Changed to allow for non-hostiles to be engaged, as they are requested by live players. ) { returnValue = true; } } return(returnValue); }
/// <summary> /// Coordinates all the processing for each time slice /// </summary> /// <param name="updateIncrement"></param> public static void NextTimeSlice() { /* * Initially the only items that would be named in events would be actual units. * Now that other things (ActiveRegions,for example) can also appear in events * it is necessary to allow UnitFActs to know those names too, to keep various checks on * object name legality from failing */ /* 1. Process the incoming list of events from below */ // Which units are currently on the incoming list? List <string> unitList = IncomingList.AffectedUnits(); for (int i = 0; i < unitList.Count; i++) { List <IncomingItemType> eventList = IncomingList.Retrieve(unitList[i]); /* do things with these events */ for (int j = 0; j < eventList.Count; j++) { ScenarioEventType thisItem = eventList[j].TheEvent; Coordinator.debugLogger.Writeline("Timer", "Time: " + timer + " Unit " + unitList[i] + " has incoming " + thisItem.GetType().ToString(), "test"); if (UnitFacts.AnyDead(thisItem.AllUnits)) { continue; } Boolean launchedByOwner; switch (thisItem.GetType().ToString()) { case name_Space + "MoveComplete_Event": { Coordinator.debugLogger.Writeline("Timer", "Unit " + thisItem.UnitID + " MoveComplete discovered at t=" + timer.ToString(), "test"); // scan happenings list for matches VerifyMatch = ActionMatch; SeekHappening(thisItem.UnitID, "MoveComplete_Event"); SeekSpeciesHappening(thisItem, "MoveComplete_Event"); } break; case name_Space + "StateChangeNotice": string newState = ((StateChangeNotice)thisItem).NewState; Coordinator.debugLogger.Writeline("Timer", "Unit " + thisItem.UnitID + " StateChange to " + newState + " discovered at t=" + timer.ToString(), "test"); VerifyMatch = StateMatch; List <string> affectedUnitList = new List <string>(); if ("Dead" != newState) { affectedUnitList.Add(thisItem.UnitID); UnitFacts.CurrentUnitStates[thisItem.UnitID] = newState; // newState; } else // Purge queues if the new state is "Dead" { affectedUnitList = SubplatformRecords.DeepDockedList(thisItem.UnitID); } for (int someUnit = 0; someUnit < affectedUnitList.Count; someUnit++) { if ("Dead" == newState) { UnitFacts.CurrentUnitStates[affectedUnitList[someUnit]] = "Dead"; // newState; //first drop all timer events involving this unit TimerQueueClass.FlushOneUnit(affectedUnitList[someUnit]); } SeekHappening(affectedUnitList[someUnit], newState); //Then if dead, remove all happening events involving this unit if ("Dead" == newState) { HappeningList.FlushOneUnit(affectedUnitList[someUnit]); Coordinator.debugLogger.Writeline("Timer", " stateChangeEvent for " + affectedUnitList[someUnit], "test"); } SeekSpeciesHappening(thisItem, newState); } break; case name_Space + "AttackSuccessfulNotice": AttackSuccessfulNotice asn = (AttackSuccessfulNotice)thisItem; for (int asi = 0; asi < AttackSuccessfulList.Happenings.Count; asi++) { AttackSuccessfulCompletionType tryThisEvent = AttackSuccessfulList.Happenings[asi]; if (tryThisEvent.Matches(asn)) { if (tryThisEvent.DoThisList.Count > 0) { AttackSuccessfulCompletionType.EnqueueEvents(asn.UnitID, asn.Target, tryThisEvent.DoThisList); } break; } } break; case name_Space + "AttackObjectRequestType": Coordinator.debugLogger.Writeline("Timer", "Attack request for " + thisItem.UnitID + "attack Request discovered at t=" + timer.ToString(), "test"); AttackObjectRequestType recastAOR = (AttackObjectRequestType)thisItem; if (ApprovalsList.AttackApproved(recastAOR)) { string attacker = recastAOR.UnitID; string target = recastAOR.TargetObjectID; AttackObjectEvent attack = new AttackObjectEvent(attacker, target, recastAOR.CapabilityName); attack.AddOtherUnit(target); TimerQueueClass.Add(1 + (int)(TimerTicker.Timer / 1000 /*Coordinator.UpdateIncrement*/), attack); } else { TimerQueueClass.Add(1 + (int)(TimerTicker.Timer / 1000), new SystemMessage(1, recastAOR.UnitID, "Attack against " + recastAOR.TargetObjectID + " failed.")); } break; case name_Space + "WeaponLaunchRequestType": WeaponLaunchRequestType recastWL = (WeaponLaunchRequestType)thisItem; string unitID = recastWL.UnitID; string weaponID = recastWL.WeaponID; string targetID = recastWL.TargetObjectID; Coordinator.debugLogger.Writeline("Timer", "Weapon Launch request for " + unitID + " using " + weaponID + " Attack Request discovered at t=" + timer.ToString(), "test"); string platformOwner = UnitFacts.Data[unitID].Owner; string weaponOwner = UnitFacts.Data[weaponID].Owner; launchedByOwner = SpeciesType.GetSpecies(UnitFacts.Data[weaponID].Species).LaunchedByOwner; // ) if ( SubplatformRecords.IsLaunchableWeapon(unitID, weaponID) && ( (platformOwner == recastWL.DecisionMaker) || (weaponOwner == recastWL.DecisionMaker) && launchedByOwner ) ) { // validate attack DecisionMakerType targetDM = DecisionMakerType.GetDM(UnitFacts.GetDM(targetID)); if ( (launchedByOwner && UnitFacts.HostileTo(DecisionMakerType.GetDM(platformOwner).Team, targetDM.Team)) || (UnitFacts.HostileTo(DecisionMakerType.GetDM(weaponOwner).Team, targetDM.Team)) //Removed !launchedByOwner from second statement ) { //NB. THe code that builds and sends the event was missing from here. It was last seen in rev 232. // its removeal was probably an accident? // build event to send down WeaponLaunch_EventType wEvent = new WeaponLaunch_EventType(unitID, targetID, weaponID); TimerQueueClass.Add(1 + (int)(timer / 1000), wEvent); // replace by new platform handling } } else { //need to throw an event back to ViewPro to re-allocate weapon String reason = ""; if (!UnitFacts.Data.ContainsKey(unitID)) { reason = "Platform object is unknown by the system."; } else if (UnitFacts.Data[unitID].Owner != recastWL.DecisionMaker) { reason = "Requesting DM does not own the Platform object."; } WeaponLaunchFailure_EventType failEvent = new WeaponLaunchFailure_EventType(weaponID, unitID, reason); failEvent.Time = (int)(timer / 1000 /*Coordinator.UpdateIncrement*/); TimerQueueClass.Add(1 + (int)(timer / 1000 /*Coordinator.UpdateIncrement*/), failEvent); } break; case name_Space + "SubplatformLaunchRequestType": SubplatformLaunchRequestType recastSL = (SubplatformLaunchRequestType)thisItem; string childID = recastSL.UnitID; string requestor = recastSL.Requestor; string parentID = recastSL.ParentUnit; LocationType destination = recastSL.Destination; Coordinator.debugLogger.Writeline("Timer", "Subplatform Launch request for " + childID + " from " + parentID + " discovered at t=" + timer.ToString(), "test"); launchedByOwner = SpeciesType.GetSpecies(UnitFacts.Data[childID].Species).LaunchedByOwner; if ( (UnitFacts.Data[parentID].Owner == requestor) || (UnitFacts.Data[childID].Owner == requestor) && launchedByOwner ) { // build event to send down SubplatformLaunchType slEvent = new SubplatformLaunchType(childID, parentID, destination); TimerQueueClass.Add(1 + (int)(timer / 1000), slEvent); } /**/ break; case name_Space + "SubplatformDockRequestType": SubplatformDockRequestType recastSD = (SubplatformDockRequestType)thisItem; string orphanID = recastSD.UnitID; string dockRequestor = recastSD.Requestor; string adopterID = recastSD.ParentUnit; Coordinator.debugLogger.Writeline("Timer", "Subplatform Dock request for " + orphanID + " from " + adopterID + " discovered at t=" + timer.ToString(), "test"); if ("" != adopterID) { if (UnitFacts.Data.ContainsKey(orphanID) && UnitFacts.Data.ContainsKey(adopterID) && ((UnitFacts.Data[orphanID].Owner == dockRequestor) // && (UnitFacts.Data[adopterID].Owner == dockRequestor) ) && SpeciesType.GetSpecies(UnitFacts.GetSpecies(adopterID)).CanHaveSubplatform(UnitFacts.GetSpecies(orphanID)) ) { /* for dock to any object*/ SubplatformDockType sdEvent = new SubplatformDockType(orphanID, adopterID); TimerQueueClass.Add(1 + (int)(timer / 1000), sdEvent); } } // if the parent is "" just ignore the request
public static void SendTimeTick(object timeObj) { /* 2. Send the tick */ // timer += updateIncrement; int time = (int)timeObj; int timer = time / 1000; int secs = timer % 60; int mins = (timer / 60) % 60; int hours = timer / 3600; const string name_Space = TimerTicker.name_Space; DateTime currTime = new DateTime(1, 1, 1, hours, mins, secs); string simulationTime = String.Format("{0:HH:mm:ss}", currTime); EventCommunicator.SendEvent(new TickEventType(time, simulationTime)); // current = DateTime.Now; // TimeSpan ts = current - last; // Console.WriteLine("timeslice: {0:+hh.mm.ss.ffffzz}", ts.ToString()); //last = current; /* 3. Pull the events for this tick off the queue and handle them */ List <ScenarioEventType> events = TimerQueueClass.RetrieveEvents(timer); if (events != null) { for (int v = 0; v < events.Count; v++) { Coordinator.debugLogger.Writeline("Timer", "Time: " + time.ToString() + " ID: " + events[v].UnitID.ToString() + " Event: " + events[v].GetType().ToString(), "test"); // track current state if (UnitFacts.AnyDead(events[v].AllUnits)) {// skip an event that refers to a dead unit continue; } string thisUnit = events[v].UnitID; string thisTarget = ""; // Only a few outgoing events require two substitutions switch (events[v].GetType().ToString()) { case name_Space + "AttackObjectEvent": thisTarget = ((AttackObjectEvent)events[v]).TargetObjectID; break; case name_Space + "LaunchEventType": thisTarget = ((LaunchEventType)events[v]).Child; break; case name_Space + "WeaponLaunchEventType": thisTarget = ((WeaponLaunchEventType)events[v]).Child; break; case name_Space + "SubplatformLaunchType": thisTarget = ((SubplatformLaunchType)events[v]).ParentUnit; break; case name_Space + "SubplatformDockType": thisTarget = ((SubplatformDockType)events[v]).ParentUnit; break; default: break; } if (!events[v].EngramValid(thisUnit, thisTarget)) { Coordinator.debugLogger.Writeline("Timer", "Time: Command" + events[v].GetType().ToString() + " ignored due to value of " + events[v].Range.Name, "test"); } else { switch (events[v].GetType().ToString()) { /* SInce the active region update requires both activity and visibility, * must find current values of non-updated field just before sending event */ case name_Space + "ActiveRegionActivityUpdateType": ActiveRegionStateType currentStateForVisibility = (ActiveRegionStateType)(NameLists.activeRegionNames.ContainedData[((ActiveRegionActivityUpdateType)(events[v])).UnitID]); currentStateForVisibility.IsActive = ((ActiveRegionActivityUpdateType)(events[v])).IsActive; NameLists.activeRegionNames.ContainedData[((ActiveRegionActivityUpdateType)(events[v])).UnitID] = currentStateForVisibility; ActiveRegionUpdateType activityUpdate = new ActiveRegionUpdateType(((ActiveRegionActivityUpdateType)(events[v])).UnitID, ((ActiveRegionActivityUpdateType)(events[v])).Time, currentStateForVisibility); EventCommunicator.SendEvent(activityUpdate); break; case name_Space + "ActiveRegionVisibilityUpdateType": ActiveRegionStateType currentStateForActivity = (ActiveRegionStateType)(NameLists.activeRegionNames.ContainedData[((ActiveRegionVisibilityUpdateType)(events[v])).UnitID]); currentStateForActivity.IsVisible = ((ActiveRegionVisibilityUpdateType)(events[v])).IsVisible; NameLists.activeRegionNames.ContainedData[((ActiveRegionVisibilityUpdateType)(events[v])).UnitID] = currentStateForActivity; ActiveRegionUpdateType visibilityUpdate = new ActiveRegionUpdateType(((ActiveRegionVisibilityUpdateType)(events[v])).UnitID, ((ActiveRegionVisibilityUpdateType)(events[v])).Time, currentStateForActivity); EventCommunicator.SendEvent(visibilityUpdate); break; case name_Space + "CloseChatRoomType": if (ChatRooms.DropChatRoom(((CloseChatRoomType)(events[v])).Room)) { EventCommunicator.SendEvent(events[v]); } break; case name_Space + "CloseVoiceChannelType": if (VoiceChannels.DropVoiceChannel(((CloseVoiceChannelType)(events[v])).Channel)) { EventCommunicator.SendEvent(events[v]); } break; case name_Space + "Reveal_EventType": UnitFacts.CurrentUnitStates[events[v].UnitID] = ((Reveal_EventType)events[v]).InitialState; EventCommunicator.SendEvent(events[v]); break; case name_Space + "StateChangeEvent": string currentState = UnitFacts.CurrentUnitStates[events[v].UnitID]; if (("Dead" != currentState) && (!((StateChangeEvent)events[v]).IsException(currentState))) { if ((((StateChangeEvent)events[v]).HasPrecursors()) && (((StateChangeEvent)events[v]).IsPrecursor(currentState))) { EventCommunicator.SendEvent(events[v]); } else if (!((StateChangeEvent)events[v]).HasPrecursors()) { EventCommunicator.SendEvent(events[v]); } } break; case name_Space + "TransferEvent": if (UnitFacts.ChangeDM(events[v].UnitID, /* ((TransferEvent)events[v]).From, */ ((TransferEvent)events[v]).To)) { EventCommunicator.SendEvent(events[v]); } // and if not? Throw exception?? else { Coordinator.debugLogger.LogError("Timed Queue Manager", "Transfer of Unit " + events[v].UnitID + " from " + ((TransferEvent)events[v]).From + " failed."); } break; case name_Space + "SubplatformLaunchType": SubplatformLaunchType alias = ((SubplatformLaunchType)events[v]); List <string> nowDocked = SubplatformRecords.GetDocked(alias.ParentUnit); if (nowDocked.Contains(alias.UnitID)) { SubplatformRecords.UnDock(alias.ParentUnit, alias.UnitID); EventCommunicator.SendEvent(events[v]); } break; case name_Space + "SubplatformDockType": SubplatformDockType dock = ((SubplatformDockType)events[v]); string adopterID = dock.ParentUnit; if (SubplatformRecords.CountDockedOfSpecies(adopterID, UnitFacts.GetSpecies(dock.UnitID)) <= SpeciesType.GetSpecies(UnitFacts.GetSpecies(adopterID)).GetSubplatformCapacity(UnitFacts.GetSpecies(dock.UnitID))) { if (SubplatformRecords.RecordDocking(thisTarget, dock.UnitID) == true) { EventCommunicator.SendEvent(events[v]); } else { string someError = "This failed because the subplatform wasn't able to be docked to this platform"; } } break; //SubplatformLaunchType is a response to a launch request, //LaunchEventType was intended to be from the scenario. This needs to be rethought. case name_Space + "LaunchEventType": // Note -- it isn't an error if the thing isn't docked any more LaunchEventType launch = (LaunchEventType)events[v]; // This comes from scenario so we only check if there is something to launch if ("" != launch.Child) { List <string> dockedNow = SubplatformRecords.GetDocked(launch.UnitID); if (dockedNow.Contains(launch.Child)) { SubplatformRecords.UnDock(launch.UnitID, launch.Child); ///??? Subplatforms.GetDocked(launch.UnitID); // not in sim model launch.Genus = Genealogy.GetGenus(launch.Child); SubplatformRecords.UnDock(launch.UnitID, launch.Child); EventCommunicator.SendEvent(launch); } } break; case name_Space + "WeaponLaunchEventType": // Note -- it isn't an error if the thing isn't docked any more WeaponLaunchEventType launchWeapon = (WeaponLaunchEventType)events[v]; // This comes from scenario so we only check if there is something to launch if ("" != launchWeapon.Child) { List <string> dockedNow = SubplatformRecords.GetDocked(launchWeapon.UnitID); if (dockedNow.Contains(launchWeapon.Child)) { SubplatformRecords.UnDock(launchWeapon.UnitID, launchWeapon.Child); SubplatformRecords.UnDock(launchWeapon.UnitID, launchWeapon.Child); EventCommunicator.SendEvent(launchWeapon); } } break; case name_Space + "EngramSettingType": //This is the inital value so it was set in the table at parset time EventCommunicator.SendEvent(events[v]); break; case name_Space + "ChangeEngramType": ChangeEngramType newValue = ((ChangeEngramType)events[v]); Engrams.Set(newValue.Name, newValue.UnitID, newValue.EngramValue); EventCommunicator.SendEvent(new EngramSettingType(newValue.Name, newValue.UnitID, newValue.EngramValue, Engrams.GetType(newValue.Name))); break; case name_Space + "RemoveEngramEvent": Engrams.Remove(((RemoveEngramEvent)events[v]).Name); break; case name_Space + "OpenChatRoomType": //Requests from below are handled by EventCommunicator //This processing is for commands in script -- ?? string chatFailureMessage = ""; OpenChatRoomType ocr = ((OpenChatRoomType)events[v]); if (("EXP" != ocr.Owner) && !UnitFacts.IsDM(ocr.Owner)) { chatFailureMessage = "The name '" + ocr.Owner + "' is not a valid decision maker."; } else { for (int i = 0; i < ocr.Members.Count; i++) { DecisionMakerType DMi = DecisionMakerType.GetDM(ocr.Members[i]); for (int mbr = 1 + i; mbr < ocr.Members.Count; mbr++) { if (!DMi.CanChatWith(ocr.Members[mbr])) { chatFailureMessage = "Decison Makers '" + DMi.Identifier + "' cannot be in a chat room with '" + ocr.Members[mbr] + "'"; break; } if ("" != chatFailureMessage) { break; } } } } if ("" == chatFailureMessage) { chatFailureMessage = ChatRooms.AddRoom(ocr); EventCommunicator.SendEvent(ocr); } if ("" != chatFailureMessage) { // DON'T throw new ApplicationException("Could not create chatroom '"+ocr.Range+"': "+chatFailureMessage); // send a system message instead } break; case name_Space + "SendChatMessageType": // Script induced. Only need to check if there is such a room if (ChatRooms.IsRoom(((SendChatMessageType)(events[v])).RoomName)) { EventCommunicator.SendEvent(events[v]); } break; case name_Space + "OpenWhiteboardRoomType": //Requests from below are handled by EventCommunicator //This processing is for commands in script -- ?? string whiteboardFailureMessage = ""; OpenWhiteboardRoomType owr = ((OpenWhiteboardRoomType)events[v]); if (("EXP" != owr.Owner) && !UnitFacts.IsDM(owr.Owner)) { whiteboardFailureMessage = "The name '" + owr.Owner + "' is not a valid decision maker."; } else { for (int i = 0; i < owr.Members.Count; i++) { DecisionMakerType DMi = DecisionMakerType.GetDM(owr.Members[i]); for (int mbr = 1 + i; mbr < owr.Members.Count; mbr++) { if (!DMi.CanWhiteboardWith(owr.Members[mbr])) { whiteboardFailureMessage = "Decison Makers '" + DMi.Identifier + "' cannot be in a whiteboard room with '" + owr.Members[mbr] + "'"; break; } if ("" != whiteboardFailureMessage) { break; } } } } if ("" == whiteboardFailureMessage) { whiteboardFailureMessage = WhiteboardRooms.AddRoom(owr); } if ("" != whiteboardFailureMessage) { // DON'T throw new ApplicationException("Could not create whiteboardroom '"+owr.Range+"': "+whiteboardFailureMessage); // send a system message instead } break; case name_Space + "OpenVoiceChannelType": //Requests from below would be/are handled by EventCommunicator //This processing is for commands in script -- ?? string voiceFailureMessage = ""; OpenVoiceChannelType ovct = ((OpenVoiceChannelType)events[v]); //if (("EXP" != ovct.Owner) && !UnitFacts.IsDM(ovct.Owner)) //{ // voiceFailureMessage = "Open Voice Channel: The name '" + ovct.Owner + "' is not a valid decision maker."; // ErrorLog.Write(voiceFailureMessage); //} //else //{ voiceFailureMessage = VoiceChannels.AddChannel(ovct); if ("" != voiceFailureMessage) { ErrorLog.Write(voiceFailureMessage); } else { //ovct.InitialMembers = DecisionMakerType.GetVoiceChannelMembers(ovct.Channel); //TODO: AD: Is this even NECESSARY? EventCommunicator.SendEvent(ovct); } //} break; case name_Space + "FlushEvents": //first drop all timer events involving this unit TimerQueueClass.FlushOneUnit(((FlushEvents)events[v]).UnitID); // Then all events on happenin queue about this unit for (int h = 0; h < HappeningList.Happenings.Count; h++) { // Find first happening event that keys off this state change HappeningCompletionType incident = HappeningList.Happenings[h]; if (incident.UnitID == ((FlushEvents)events[v]).UnitID) { HappeningList.Happenings.RemoveAt(h); } else // examine all the DoThisLists { List <int> removals = new List <int>(); for (int d = 0; d < incident.DoThisList.Count; d++) { if (incident.DoThisList[d].Involves(((FlushEvents)events[v]).UnitID)) { removals.Add(d); } //then remove from back to front to preserve indices for (int r = removals.Count - 1; r >= 0; r--) { incident.DoThisList.RemoveAt(r); } } } } break; case name_Space + "ForkReplayEventType": EventCommunicator.SendEvent(events[v]); break; default: EventCommunicator.SendEvent(events[v]); break; } } } TimerQueueClass.DropNode(time); } }