/// <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"); } }//
/// <summary> /// This method takes in a Create_EventType (ScenCon defined object), and retrieves /// the data from the object, packages up the data into a SimulationEvent (SimCore defined /// object), and then sends the event to the network server. This method was pulled out of /// the main block of code to simplify sending the event and code readability. /// </summary> /// <param name="incoming">The Create_EventType object whose data is packaged /// into an outgoing SimulationEvent.</param> private static void SendCreateEvent(Create_EventType incoming) { SimulationEvent e = SimulationEventFactory.BuildEvent(ref simModelInfo, "NewObject"); Dictionary<string, DataValue> myAtt = new Dictionary<string, DataValue>(); Dictionary<string, object> DictionaryOfStates; DataValue dv; ObjectInfo myObject; string objectType = incoming.Genus.ToString(); myObject = simModelInfo.objectModel.objects[objectType]; dv = new StateTableValue(); try { e["Time"] = DataValueFactory.BuildInteger(incoming.Time);//ConvertInteger(incoming.Timer); e["ObjectType"] = DataValueFactory.BuildString(objectType); //ConvertString(objectType); e["ID"] = DataValueFactory.BuildString(incoming.UnitID);//ConvertString(incoming.UnitID); /*********** Define the State Table ***********************/ DictionaryOfStates = incoming.Parameters.GetDictionary(); } catch { throw new Exception("Missing Required Data for Create Event"); } Dictionary<string, DataValue> SimCoreStateTable = new Dictionary<string, DataValue>(); foreach (KeyValuePair<string, object> kvp in DictionaryOfStates) { DataValue capabilities, vulnerabilities, currentSimCoreState; capabilities = new CapabilityValue(); vulnerabilities = new VulnerabilityValue(); currentSimCoreState = new AttributeCollectionValue(); ExtendedStateBody currentScenConState = new ExtendedStateBody(); currentScenConState = (ExtendedStateBody)incoming.Parameters[kvp.Key]; capabilities = DefineCapabilityValue(currentScenConState.Capabilities); ((AttributeCollectionValue)currentSimCoreState).attributes.Add("Capability", capabilities); vulnerabilities = DefineVulnerabilityValue(currentScenConState.Vulnerabilities, currentScenConState.Combinations); ((AttributeCollectionValue)currentSimCoreState).attributes.Add("Vulnerability", vulnerabilities); DataValue sensorArray = DataValueFactory.BuildValue("SensorArrayType"); DataValue sensor; Dictionary<string, SensorType> sensors = new Dictionary<string, SensorType>(); Dictionary<string, List<ConeValue>> ranges; sensors = currentScenConState.Sensors; foreach (string sensorKind in sensors.Keys) { ranges = new Dictionary<string, List<ConeValue>>(); sensor = DataValueFactory.BuildValue("SensorType"); SensorType typeOfSensor = sensors[sensorKind]; string attributeSensed = typeOfSensor.Attribute; List<Cone> cones = typeOfSensor.Cones; double maxRange = 0.0; ((SensorValue)sensor).attIsEngram[attributeSensed] = sensors[sensorKind].IsEngram; List<ConeValue> simCoreCones = new List<ConeValue>(); foreach (Cone aCone in sensors[sensorKind].Cones) { LocationValue direction = new LocationValue(); direction.X = aCone.Direction.X; direction.Y = aCone.Direction.Y; direction.Z = aCone.Direction.Z; direction.exists = true; ConeValue cv = new ConeValue(); cv.direction = direction; cv.extent = aCone.Extent; if (aCone.Extent > maxRange) maxRange = aCone.Extent; cv.level = aCone.Level; cv.spread = aCone.Spread; simCoreCones.Add(cv); } ranges.Add(attributeSensed, simCoreCones); ((SensorValue)sensor).ranges = ranges; ((SensorValue)sensor).sensorName = sensorKind; if (((SensorValue)sensor).maxRange < maxRange) { ((SensorValue)sensor).maxRange = maxRange; } ((SensorArrayValue)sensorArray).sensors.Add((SensorValue)sensor); } ((AttributeCollectionValue)currentSimCoreState).attributes.Add("Sensors", sensorArray); //Emitters DataValue emitter = DataValueFactory.BuildValue("EmitterType"); Dictionary<string, EmitterType> scenConEmitters = currentScenConState.Emitters; EmitterType emission; foreach (string s in scenConEmitters.Keys) { emission = scenConEmitters[s].DeepCopy(); string attributeName = s; ((EmitterValue)emitter).attIsEngram[s] = emission.IsEngram; // string level; // double variance; Dictionary<string, double> levels = new Dictionary<string, double>(); foreach (string level in emission.Levels.Keys) { // levels.Add(level, (double)(emission[level])); double dublet = Double.Parse((emission.Levels[level].ToString())); levels.Add(level, dublet); } ((EmitterValue)emitter).emitters.Add(attributeName, levels); } ((AttributeCollectionValue)currentSimCoreState).attributes.Add("Emitters", emitter); foreach (AttributeInfo attr in myObject.attributes.Values) { string attrType = attr.dataType; string simCoreName = attr.name; string scenConKey = convertSimCoreToScenCon(simCoreName); if (currentScenConState.Parameters.ContainsKey(scenConKey)) { switch (attrType) { case "StringType": ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildString(Convert.ToString(currentScenConState.Parameters[scenConKey]))); break;/*ConvertString(Convert.ToString(currentScenConState.Parameters[scenConKey])*/ case "IntegerType": ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildInteger(Convert.ToInt32(currentScenConState.Parameters[scenConKey]))); break;/*ConvertInteger(Convert.ToInt32(currentScenConState.Parameters[scenConKey])*/ case "DoubleType": ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildDouble(Convert.ToDouble(currentScenConState.Parameters[scenConKey]))); break;/*ConvertDouble(Convert.ToDouble(currentScenConState.Parameters[scenConKey])*/ case "LocationType": LocationType lt = currentScenConState.Parameters[scenConKey] as LocationType; ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildLocation(lt.X, lt.Y, lt.Z, false)); break;/*ConvertLocation((LocationType)currentScenConState.Parameters[scenConKey])*/ case "VelocityType": VelocityType vt = currentScenConState.Parameters[scenConKey] as VelocityType; ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildVelocity(vt.VX, vt.VY, vt.VZ)); break;/*ConvertVelocity((VelocityType)currentScenConState.Parameters[scenConKey])*/ case "BooleanType": if (currentScenConState.Parameters.ContainsKey(attr.name)) { string booleanVal = currentScenConState.Parameters[attr.name].ToString(); bool value = false; if (booleanVal == "true" || booleanVal == "True" || booleanVal == "TRUE") { value = true; } ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildBoolean(value)); }/*ConvertBoolean(value)*/ break; case "StringListType": ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, DataValueFactory.BuildStringList((List<String>)currentScenConState.Parameters[scenConKey])); break; case "ClassificationDisplayRulesType": ((AttributeCollectionValue)currentSimCoreState).attributes.Add(simCoreName, (DataValue)currentScenConState.Parameters[scenConKey]); break; default: break; } } } SimCoreStateTable.Add(kvp.Key, currentSimCoreState); } dv = new StateTableValue(); ((StateTableValue)dv).states = SimCoreStateTable; e["StateTable"] = dv; ((AttributeCollectionValue)e["Attributes"]).attributes.Add("OwnerID", DataValueFactory.BuildString(incoming.Owner));/*ConvertString( .Owner)*/ ((AttributeCollectionValue)e["Attributes"]).attributes.Add("ClassName", DataValueFactory.BuildString(incoming.UnitBase));/*ConvertString(incoming.UnitBase)*/ server.PutEvent(e); }
/// <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"); } }//
/// <summary> /// This method loops while the program runs, and every 100 /// milliseconds (1/10 of a sec) calls the server's "GetEvents" /// method. This retrieves events that the EvComm has /// subscribed to. At which point, the list is parsed, and the /// events are converted back to ScenCon styled events. /// </summary> public void WaitForEvents() { //Receives an incoming message from the simcore string objID = null; string parentID = null; string targetObjID = null; string dm = null; string capability = null; List<String> capabilities; string newState = null; LocationType vect = null; string weaponID = null; double throttle; string eventType = null; string roomName=null; string channelName = null; string requestingDM=null; string textString=null; List<string> membershipList; List<SimulationEvent> incomingEvents = new List<SimulationEvent>(); bool allowAssetTransferRequests = true; try { while (true) { incomingEvents = server.GetEvents(); if (incomingEvents.Count == 0) {//do nothing } else { foreach (SimulationEvent e in incomingEvents) { eventType = e.eventType; switch (eventType) { case "SimCoreReady": Coordinator.debugLogger.Writeline("EventCommunicator", "Ready To Start Scenario", "test"); Coordinator.ReadyToStart(); break; case "SelfDefenseAttackStarted": objID = ((StringValue)e["AttackerObjectID"]).value; targetObjID = ((StringValue)e["TargetObjectID"]).value; SelfDefenseAttackNotice selfDefenseNotice = new SelfDefenseAttackNotice(objID, targetObjID); selfDefenseNotice.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(selfDefenseNotice); Coordinator.debugLogger.Writeline("EventCommunicator", "Self defense attack started", "test"); break; case "SubplatformDockRequest": objID = ((StringValue)e["ObjectID"]).value; parentID = ((StringValue)e["ParentObjectID"]).value; dm = ((StringValue)e["UserID"]).value; SubplatformDockRequestType dockRequest = new SubplatformDockRequestType(dm, objID, parentID); dockRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(dockRequest); Coordinator.debugLogger.Writeline("EventCommunicator", "Subplatform dock request received", "test"); break; case "SubplatformLaunchRequest": objID = ((StringValue)e["ObjectID"]).value; parentID = ((StringValue)e["ParentObjectID"]).value; dm = ((StringValue)e["UserID"]).value; vect = new LocationType(((LocationValue)e["LaunchDestinationLocation"]).X, ((LocationValue)e["LaunchDestinationLocation"]).Y, ((LocationValue)e["LaunchDestinationLocation"]).Z); SubplatformLaunchRequestType subPlaunchRequest = new SubplatformLaunchRequestType(dm, objID, parentID, vect); subPlaunchRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(subPlaunchRequest); Coordinator.debugLogger.Writeline("EventCommunicator", "Subplatform launch request received", "test"); break; case "WeaponLaunchRequest": objID = ((StringValue)e["ParentObjectID"]).value; //the launching object weaponID = ((StringValue)e["ObjectID"]).value;// the weapon id being launched //parentID = ((StringValue)e["ParentObjectID"]).value; targetObjID = ((StringValue)e["TargetObjectID"]).value; //The target object dm = ((StringValue)e["UserID"]).value; //the dm launching the weapon WeaponLaunchRequestType launchRequest = new WeaponLaunchRequestType(objID, dm, targetObjID, weaponID); launchRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(launchRequest); Coordinator.debugLogger.Writeline("EventCommunicator", "Weapon launch request received", "test"); break; case "MoveDone": objID = ((StringValue)e["ObjectID"]).value; //see line 222 of MotionSim.cs for reference MoveComplete_Event moveDone = new MoveComplete_Event(objID.ToString()); moveDone.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(moveDone); break; case "MoveObjectRequest": dm = String.Empty; dm = ((StringValue)e["UserID"]).value; objID = String.Empty; objID = ((StringValue)e["ObjectID"]).value; vect = new LocationType(); //X is location in UTM Easting ((LocationType)vect).X = ((LocationValue)e["DestinationLocation"]).X; //Y is location in UTM Northing ((LocationType)vect).Y = ((LocationValue)e["DestinationLocation"]).Y; //Z is altitude in meters ((LocationType)vect).Z = ((LocationValue)e["DestinationLocation"]).Z; throttle = new double(); throttle = ((DoubleValue)e["Throttle"]).value; MoveObjectRequestType moveObjectRequest = new MoveObjectRequestType(objID, dm, vect, throttle); moveObjectRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(moveObjectRequest); break; case "AttackObjectRequest": dm = String.Empty; dm = ((StringValue)e["UserID"]).value; objID = String.Empty; objID = ((StringValue)e["ObjectID"]).value; targetObjID = String.Empty; targetObjID = ((StringValue)e["TargetObjectID"]).value; capability = ((StringValue)e["CapabilityName"]).value; AttackObjectRequestType attackObjectRequest = new AttackObjectRequestType(objID, dm, targetObjID, capability); attackObjectRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(attackObjectRequest); break; case "TransferObjectRequest": if (allowAssetTransferRequests) { string recipientDM = String.Empty; recipientDM = ((StringValue)e["RecipientID"]).value; objID = String.Empty; objID = ((StringValue)e["ObjectID"]).value; string requesterID = String.Empty; requesterID = ((StringValue)e["UserID"]).value; string currentState = ((StringValue)e["State"]).value; TransferObjectRequest transferObjectRequest = new TransferObjectRequest(requesterID, recipientDM, objID, currentState); transferObjectRequest.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(transferObjectRequest); } else { //client side asset transfers were not allowed Coordinator.debugLogger.Writeline("EventCommunicator", "TransferObjectRequest denied due to scenario constraints", "test"); } break; case "StateChange": objID = ((StringValue)e["ObjectID"]).value; newState = ((StringValue)e["NewState"]).value; StateChangeNotice changeNotice = new StateChangeNotice(objID, newState); changeNotice.Time = ((IntegerValue)e["Time"]).value; IncomingList.Add(changeNotice); break; /* case "JoinChatRoom" : string roomToJoin=((StringValue)e["RoomName"]).value; string targetPlayerID=((StringValue)e["TargetPlayerID"]).value; if(!UnitFacts.IsDM(targetPlayerID)) throw new ApplicationException("'" + targetPlayerID + "' is not a valid decision maker name. Cannot add to chatroom '" + roomToJoin + "'"); List<string> members = ChatRooms.GetChatMembers(roomToJoin); Boolean canJoin = true; DecisionMakerType candidateDM=DecisionMakerType.GetDM(targetPlayerID); for(int i=0;i<members.Count;i++) if (!candidateDM.CanChatWith(members[i])) { canJoin = false; break; } if (canJoin) { ChatRooms.AddChatMember(roomToJoin, targetPlayerID); //notify chat server SimulationEvent f = SimulationEventFactory.BuildEvent(ref simModelInfo, "AddToChatRoom"); f["RoomName"] = DataValueFactory.BuildString("roomToJoin"); f["TargetPlayerID"] = DataValueFactory.BuildString("targetPlayerID"); server.PutEvent(f); } break ;*/ case "RequestCloseChatRoom": roomName = ((StringValue)e["RoomName"]).value; Boolean closedChatOK=ChatRooms.DropChatRoom(roomName); if (closedChatOK) { SimulationEvent reportClosedChat = SimulationEventFactory.BuildEvent(ref simModelInfo, "CloseChatRoom"); reportClosedChat["RoomName"] = DataValueFactory.BuildString(roomName); server.PutEvent(reportClosedChat); } break; case "RequestCloseVoiceChannel": channelName = ((StringValue)e["ChannelName"]).value; Boolean closedVoiceOK=VoiceChannels.DropVoiceChannel(channelName); if (closedVoiceOK) { SimulationEvent reportClosedVoice = SimulationEventFactory.BuildEvent(ref simModelInfo, "CloseVoiceChannel"); reportClosedVoice["ChannelName"] = DataValueFactory.BuildString(channelName); server.PutEvent(reportClosedVoice); } break; case "RequestChatRoomCreate": { // HAndled at once -- so no delay is seen even if server is not active roomName = ((StringValue)e["RoomName"]).value; requestingDM = ((StringValue)e["SenderDM_ID"]).value; membershipList = new List<string>(); List<string> allMembers = ((StringListValue)e["MembershipList"]).strings; string chatFailureReason = ""; OpenChatRoomType openEvent = null; // needed bacause it appears to compiler that this is not defined on every path if (!UnitFacts.IsDM(requestingDM)) chatFailureReason = "Illegal DM '" + requestingDM + "' in create chat room request"; else { for (int i = 0; i < allMembers.Count; i++) membershipList.Add(allMembers[i]); for (int i = 0; i < membershipList.Count; i++) { DecisionMakerType DMi = DecisionMakerType.GetDM(membershipList[i]); for (int m = 1 + i; m < membershipList.Count; m++) { if (!DMi.CanChatWith(membershipList[m])) { chatFailureReason = "Decison Makers '" + DMi.Identifier + "' cannot be in a chat room with '" + membershipList[m] + "'"; break; } if ("" != chatFailureReason) break; } } if ("" == chatFailureReason) { // Now validate and queue response openEvent = new OpenChatRoomType(1 + (int)(TimerTicker.Timer / 1000/*Coordinator.UpdateIncrement*/), requestingDM, roomName, membershipList); chatFailureReason = ChatRooms.AddRoom(openEvent); } if ("" != chatFailureReason) { EventCommunicator.SendEvent(new SystemMessage( 1 + (int)(TimerTicker.Timer / 1000), requestingDM, chatFailureReason)); } else { EventCommunicator.SendEvent(openEvent); } } } break; case "RequestWhiteboardRoomCreate": { // HAndled at once -- so no delay is seen even if server is not active roomName = ((StringValue)e["RoomName"]).value; requestingDM = ((StringValue)e["SenderDM_ID"]).value; membershipList = new List<string>(); List<string> allMembers = ((StringListValue)e["MembershipList"]).strings; string whiteboardFailureReason = ""; OpenWhiteboardRoomType openEvent = null; // needed bacause it appears to compiler that this is not defined on every path if (!UnitFacts.IsDM(requestingDM)) whiteboardFailureReason = "Illegal DM '" + requestingDM + "' in create whiteboard room request"; else { for (int i = 0; i < allMembers.Count; i++) membershipList.Add(allMembers[i]); for (int i = 0; i < membershipList.Count; i++) { DecisionMakerType DMi = DecisionMakerType.GetDM(membershipList[i]); for (int m = 1 + i; m < membershipList.Count; m++) { if (!DMi.CanWhiteboardWith(membershipList[m])) { whiteboardFailureReason = "Decison Makers '" + DMi.Identifier + "' cannot be in a whiteboard room with '" + membershipList[m] + "'"; break; } if ("" != whiteboardFailureReason) break; } } if ("" == whiteboardFailureReason) { // Now validate and queue response openEvent = new OpenWhiteboardRoomType(1 + (int)(TimerTicker.Timer / 1000/*Coordinator.UpdateIncrement*/), requestingDM, roomName, membershipList); whiteboardFailureReason = WhiteboardRooms.AddRoom(openEvent); } if ("" != whiteboardFailureReason) { EventCommunicator.SendEvent(new SystemMessage( 1 + (int)(TimerTicker.Timer / 1000), requestingDM, whiteboardFailureReason)); } else { EventCommunicator.SendEvent(openEvent); } } } break; case "AttackSucceeded": objID = ((StringValue)e["ObjectID"]).value; targetObjID = ((StringValue)e["TargetID"]).value; capabilities = ((StringListValue)e["Capabilities"]).strings; newState = ((StringValue)e["NewState"]).value; IncomingList.Add(new AttackSuccessfulNotice(objID, targetObjID, capabilities, newState)); break; case "ChangeTagRequest": objID = ((StringValue)e["UnitID"]).value; requestingDM = ((StringValue)e["DecisionMakerID"]).value; textString = ((StringValue)e["Tag"]).value; // This event is handled in place for more rapid turnaround membershipList = new List<string>(); string thisTeam = UnitFacts.DMTeams[requestingDM]; for (int mbrs = 0; mbrs < UnitFacts.TeamDMs[thisTeam].Count; mbrs++) { membershipList.Add(UnitFacts.TeamDMs[thisTeam][mbrs]); } EventCommunicator.SendEvent(new UpdateTagType(objID, textString, membershipList)); break; case "ClientSideAssetTransferAllowed": allowAssetTransferRequests = ((BooleanValue)e["EnableAssetTransfer"]).value; break; case "DynamicCreate": objID = ((StringValue)e["ObjectID"]).value; dm = ((StringValue)e["Owner"]).value; String kind = ((StringValue)e["Kind"]).value; Aptima.Asim.DDD.ScenarioParser.pCreateType c; c = new Aptima.Asim.DDD.ScenarioParser.pCreateType(objID, kind, dm); 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); } NameLists.unitNames.New(createEvent.UnitID, null); //TimerQueueClass.SecondarySendBeforeStartup(createEvent); TimerQueueClass.Add(1, createEvent); UnitFacts.CurrentUnitStates.Add(createEvent.UnitID, ""); break; case "DynamicReveal": objID = ((StringValue)e["ObjectID"]).value; LocationValue loc = (LocationValue)e["InitialLocation"]; String initialState = ((StringValue)e["InitialState"]).value; Aptima.Asim.DDD.ScenarioParser.pLocationType pLoc = new Aptima.Asim.DDD.ScenarioParser.pLocationType(); pLoc.X = loc.X; pLoc.Y = loc.Y; pLoc.Z = loc.Z; int revealTime = ((IntegerValue)e["RevealTime"]).value; Aptima.Asim.DDD.ScenarioParser.pRevealType r; r = new Aptima.Asim.DDD.ScenarioParser.pRevealType(objID, null, revealTime, pLoc,initialState, new Dictionary<string, object>()); Reveal_EventType revealEvent = new Reveal_EventType(r); revealEvent.Genus = Genealogy.GetGenus(revealEvent.UnitID); TimerQueueClass.Add(r.Time, revealEvent); //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"); ScenarioToQueues.RevealDocked(r.UnitID, r.Time); break; default: throw new ApplicationException("Received unknown event in EventCommunicator:" + eventType); } } incomingEvents.Clear(); } Thread.Sleep(100); } } /* catch (ThreadAbortException e) { //throw new ApplicationException("In WaitForEvents", e); } */ finally { }//removes a warning caused bu the null catch. If catch is needed, this won't be }