/// <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 }