diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a4fe3c6977171123955ae583411384d21a0bdf93 Binary files /dev/null and b/.DS_Store differ diff --git a/assignments/.DS_Store b/assignments/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a308dd9de4b911c6cf89af7d62423a9a192ba664 Binary files /dev/null and b/assignments/.DS_Store differ diff --git a/assignments/README.md b/assignments/README.md index c7693bf0505f7c9abde909e479de1669cd39e6db..ea7416bf6a0d8a1c10a1fee1f9ffa1f68262b488 100644 --- a/assignments/README.md +++ b/assignments/README.md @@ -36,14 +36,20 @@ All MV3500 cohorts have source code collected under a common Netbeans project. 4. Name all of your files starting with your last name, e.g. **LastnameProgram.java** **LastnameScreenshot.png** etc. 5. Be sure that names match for **LastnameProgram.java** and the class name, i.e. **public class LastnameJava** 6. Be sure to start each .java source file with correct package name, for example: - 1. package MV3500Cohort2021JulySeptember.homework1; -7. The Run and Debug context menus should be available for you to test your .java source. -8. Be sure to Commit (with description) and Push Upstream, as discussed above. + * package MV3500Cohort2022MayJune.homework1; + * package MV3500Cohort2022MayJune.homework2; etc. +7. Add a copy of **package-info.java** file to your directory. If you use NetBeans to copy, then it helpfully performs a rename refactoring and the file's package name is correct. +8. Check the javadoc by going to [build.xml](build.xml) and running target **javadoc.custom** +9. Be sure to Commit (with description) and Push Upstream, as discussed above. After committing and pushing, you can now verify that your files are been shared by checking the website: * https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2023MarchJune +**Clarity is key.** Good practices +* Note your changes in a **README.md** file. +* For nontrivial projects, you will also need to add a UML flow diagram and a UML timing sequence diagram. +* Visio has templates for UML diagrams, drawings with another tool or hand sketches are fine. ## References diff --git a/assignments/pduLog/README.md b/assignments/pduLog/README.md index 1e83f1026e5ecd9e83514af7eafd8f5f3d91b6e1..fa036d159c7bdd833bdf5e92522c0adafab6162d 100644 --- a/assignments/pduLog/README.md +++ b/assignments/pduLog/README.md @@ -2,6 +2,8 @@ This directory holds temporary PDU log files which may be deleted at any time! +To clean out old log files, simply run this directory's **[build.xml](build.xml)** target `clean.all.pduLogs` + Each time you run a DIS simulation and a PduRecorder is listening, another log file is created. File names are numbered sequentially and uniquely, so that important PDU log captures can later be copied and saved to where they are needed. @@ -14,4 +16,4 @@ the corresponding homework or project directory (and likely renaming as well). Note that the PDU log files are very tolerant of inline comments starting with a # character, so you can document success/failure and TODO issues there as well. -To clean out old log files, simply run [build.xml](build.xml) target `clean.all.log.files` +<!-- https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/assignments/pduLog/README.md --> diff --git a/assignments/pduLog/build.xml b/assignments/pduLog/build.xml index 636c956f7acba0d3aa3a7c654c113174b7343550..7825c920830c67daba126d11b2c2748efaf8af71 100644 --- a/assignments/pduLog/build.xml +++ b/assignments/pduLog/build.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 1995-2021 held by the author(s). All rights reserved. + Copyright (c) 1995-2023 held by the author(s). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/assignments/src/.DS_Store b/assignments/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8f370ce20024e01626b607bebd4111933ec46cae Binary files /dev/null and b/assignments/src/.DS_Store differ diff --git a/assignments/src/MV3500Cohort2023MarchJune/.DS_Store b/assignments/src/MV3500Cohort2023MarchJune/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a506183143edd57a28f7eb7f1281d354078197fe Binary files /dev/null and b/assignments/src/MV3500Cohort2023MarchJune/.DS_Store differ diff --git a/assignments/src/MV3500Cohort2023MarchJune/README.md b/assignments/src/MV3500Cohort2023MarchJune/README.md index 31af1645711306afd3112444167369655af6a578..93a113d5abc2ef99f1b06662f7de400cd30814d1 100644 --- a/assignments/src/MV3500Cohort2023MarchJune/README.md +++ b/assignments/src/MV3500Cohort2023MarchJune/README.md @@ -1,5 +1,7 @@ ## Student assignments: homework submission directories +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/assignments/src/MV3500Cohort2023MarchJune/README.md --> + * [Homework 1 README](homework1/README.md) Netbeans, Wireshark, Telnet, TCP Sockets * [Homework 2 README](homework2/README.md) UDP Multicast Client/Server Networking * [Homework 3 README](homework3/README.md) Example Simulation Recording OpenDIS Network Streams diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Chojnacki/package-info.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Chojnacki/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..55c5c5ecedd73578c39142d1a9eb3ad3cece9c2e --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Chojnacki/package-info.java @@ -0,0 +1,10 @@ +/** + * Assignment 3 - Example Simulation Program for MV3500. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a> + * @see java.lang.Package + * @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful">StackOverflow: why-is-package-info-java-useful</a> + * @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java">StackOverflow: how-do-i-document-packages-in-java</a> + */ + +package MV3500Cohort2023MarchJune.homework3.Chojnacki; diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..2707e4a293289fe1c51eb7a3e608d605727c5a1f --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java @@ -0,0 +1,10 @@ +/** + * Final project assignments supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a> + * @see java.lang.Package + * @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful">StackOverflow: why-is-package-info-java-useful</a> + * @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java">StackOverflow: how-do-i-document-packages-in-java</a> + */ + +package MV3500Cohort2023MarchJune.homework3.Fredrickson; diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/ExampleSimulationProgram.java index 27391682d6c8167269da63f27c7fb804661e40d6..f21d15eae2ac5f2f47ab04288de6efbbee9ebb3b 100644 --- a/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/ExampleSimulationProgram.java +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/ExampleSimulationProgram.java @@ -176,6 +176,14 @@ public class ExampleSimulationProgram // more is needed here by scenario authors... munitionDescriptor1.setQuantity(1); firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); + + entityStatePdu_2.getEntityLocation().setX(0.0); // Initial location of Entity 2 + entityStatePdu_2.getEntityLocation().setZ(0.0); // Initial location of Entity 2 + entityStatePdu_2.getEntityLocation().setY(0.0); // Initial location of Entity 2 + + entityStatePdu_1.getEntityLocation().setX(1050.0); // Initial location of Entity 2 + entityStatePdu_1.getEntityLocation().setZ(0.0); // Initial location of Entity 2 + entityStatePdu_1.getEntityLocation().setY(500.0); // Initial location of Entity 2 } /** @@ -223,12 +231,37 @@ public class ExampleSimulationProgram // compute a track, update an ESPDU, whatever it is that your model is doing... // Where is my entity? Insert changes in position; this sample only changes X position. - // Adjusted to change all X, Y, and Z positions - swislas - entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + 1.0); // 1m per timestep - entityStatePdu_1.getEntityLocation().setY(entityStatePdu_1.getEntityLocation().getY() + 1.0); // 1m per timestep - entityStatePdu_1.getEntityLocation().setZ(entityStatePdu_1.getEntityLocation().getZ() + 1.0); // 1m per timestep + + // Velocity calculations for Entity 1 moving towards Entity 2 + Double dMinusP_X = entityStatePdu_2.getEntityLocation().getX() - entityStatePdu_1.getEntityLocation().getX(); + Double dMinusP_Z = entityStatePdu_2.getEntityLocation().getZ() - entityStatePdu_1.getEntityLocation().getZ(); + Double magnitudeDMinusP = Math.sqrt(dMinusP_X * dMinusP_X + dMinusP_Z * dMinusP_Z); + Double speed = 77.2; // Average speed of CH53 - meters per second + + // Final velocity values + Double velocityX = dMinusP_X * speed / magnitudeDMinusP; + Double velocityZ = dMinusP_Z * speed / magnitudeDMinusP; + + // Moves Entity 1 towards Entity 2 + entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + velocityX); + entityStatePdu_1.getEntityLocation().setZ(entityStatePdu_1.getEntityLocation().getZ() + velocityZ); - // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at! + // Calculates the total distance between the two Entities + double magnitudeX = entityStatePdu_2.getEntityLocation().getX() - entityStatePdu_1.getEntityLocation().getX(); + double magnitudeY = entityStatePdu_2.getEntityLocation().getY() - entityStatePdu_1.getEntityLocation().getY(); + double magnitudeZ = entityStatePdu_2.getEntityLocation().getZ() - entityStatePdu_1.getEntityLocation().getZ(); + double magnitude = Math.sqrt(magnitudeX * magnitudeX + magnitudeY * magnitudeY + magnitudeZ * magnitudeZ); + + // Shows an easy to identify log of Entity movement and a firing action + System.out.println(""); + System.out.println(entityStatePdu_1.getEntityLocation()); + if (magnitude < firePdu_1a.getRange()) { + firePdu_1a.setFiringEntityID(entityID_1); + firePdu_1a.setTargetEntityID(entityID_2); + firePdu_1a.setDescriptor(munitionDescriptor1); + System.out.println("Fire at target"); + } + System.out.println(""); // etc. etc. your code goes here for your simulation of interest diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/package-info.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..3ae2e78cb32bc2556a55f36cbb9a9b0bfb84d5ef --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Islas/package-info.java @@ -0,0 +1,18 @@ +/** + * Assignment3 for the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a> + * @see java.lang.Package + * @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful">StackOverflow: why-is-package-info-java-useful</a> + * @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java">StackOverflow: how-do-i-document-packages-in-java</a> + * + * Sets coordinates for Entity 1 and Entity 2. When simulations starts, Entity 1 advances towards Entity 2 and + * fires munitions when in range. Prints Entity 1 location and firing info (on occurance) to console after each step of the simulation. + * + * Adjusted time between loops to three seconds to allow for ease of reading. + * + * Adjusted total number of loops to 4 to shorten simulation time. + * + */ + +package MV3500Cohort2023MarchJune.homework3.Islas; diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgram.java index 48ede73ae0f26cc9c27500a6d3e0e5f6ffa5dce1..aec56e3dea2ca7e4db26950968c97b73e45313d0 100644 --- a/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgram.java +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgram.java @@ -1,515 +1,527 @@ -/** - * Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. - * This work is provided under a BSD open-source license, see project license.html and license.txt - * - * This Program is a modified version of ExampleSimulationProgram in order to see the - * verbose plain text pdu log. This simulates a firewall identifying a malicious packet - * and tracing its source before destroying it - updated September 12, 2021 to ensure - * correct file pushed to Gitlab. - * - * @author William Oblak (Changes made from copy given in class) - */ -package MV3500Cohort2023MarchJune.homework3.Oblak; - -import edu.nps.moves.dis7.enumerations.*; // match any -import edu.nps.moves.dis7.pdus.*; // match any of the PDU classes, easier than listing individually -import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; -import edu.nps.moves.dis7.utilities.PduFactory; -import edu.nps.moves.dis7.utilities.stream.PduRecorder; -import java.util.ArrayList; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** The purpose of this program is to provide an easily modifiable example simulation program - * that includes DIS-capable entities doing tasks and reporting them to the network. - * Default settings include PDU recording turned on by default. - */ -public class ExampleSimulationProgram -{ - private boolean verboseComments = true; - static final String NETWORK_ADDRESS_DEFAULT = "239.1.2.3"; - static final int NETWORK_PORT_DEFAULT = 3000; - static String networkAddress = NETWORK_ADDRESS_DEFAULT; - static int networkPort = NETWORK_PORT_DEFAULT; - String DEFAULT_OUTPUT_DIRECTORY = "./pduLog"; - - private EntityID createFriendFireWall() { - EntityID FNFireWallID = new EntityID(); // 1.1.225.1.1.1 Platform,Cyber,USA,FireWall - FNFireWallID.setSiteID(13); - FNFireWallID.setApplicationID(43); - FNFireWallID.setEntityID(103); - return FNFireWallID; - } - - private EntityType createFriendFireWallType() { - EntityType FNFireWallType = new EntityType(); - FNFireWallType.setEntityKind(EntityKind.PLATFORM); - FNFireWallType.setDomain(Domain.inst(PlatformDomain.OTHER)); - FNFireWallType.setCountry(Country.AUSTRALIA_AUS); - FNFireWallType.setCategory(3); - FNFireWallType.setSubCategory(1); - FNFireWallType.setSpecific(1); - return FNFireWallType; - } - - private EntityID createMalPacket() { - EntityID MalPacketID = new EntityID(); // 1.1.45.1.7.1 Platform,Cyber,China,MaliciousPacket - MalPacketID.setSiteID(66); - MalPacketID.setApplicationID(666); - MalPacketID.setEntityID(6666); - return MalPacketID; - } - - private EntityType createMalPacketType() { - EntityType MalPacketType = new EntityType(); - MalPacketType.setEntityKind(EntityKind.PLATFORM); - MalPacketType.setDomain(Domain.inst(PlatformDomain.OTHER)); - MalPacketType.setCountry(Country.CHINA_PEOPLES_REPUBLIC_OF_CHN); - MalPacketType.setCategory(3); - MalPacketType.setSubCategory(1); - MalPacketType.setSpecific(1); - return MalPacketType; - } - - private MunitionDescriptor createTraceroute() { - - EntityType TracerouteType = new EntityType(); //2.2.225.2.13.1 - TracerouteType.setEntityKind(EntityKind.MUNITION); - TracerouteType.setDomain(Domain.inst(PlatformDomain.OTHER)); - TracerouteType.setCountry(Country.AUSTRALIA_AUS); - TracerouteType.setCategory(2); - TracerouteType.setSubCategory(8); - TracerouteType.setSpecific(1); - MunitionDescriptor Traceroute = new MunitionDescriptor(); - Traceroute.setMunitionType(TracerouteType); - Traceroute.setQuantity(1000); - Traceroute.setFuse(MunitionDescriptorFuse.CONTACT); - Traceroute.setRate(200); - return Traceroute; - } - - /** - * This runSimulationLoops() method is for you, a - * programmer-modifiable method for defining and running a new simulation of interest. - * Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that - * you can focus on your model entities and activities. - * Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for - * modification and sending in a simulation loop. - * Continuous improvement efforts seek to make this program as easy and straightforward - * as possible for DIS simulationists to use and adapt. - * All of the other methods are setup, teardown and configuration that you may find - * interesting, even helpful, but don't really have to worry about. - */ - @SuppressWarnings("SleepWhileInLoop") // yes we do that - public void runSimulationLoops () - { - try - { - /** seconds for real-time execution (not simulation time, which may or may not be the same) */ - final double SIMULATION_LOOP_DURATION_SECONDS = 1.0; - final int SIMULATION_MAX_LOOP_COUNT = 10; // be deliberate out out there! also avoid infinite loops. - int simulationLoopCount = 0; // variable, initialized at 0 - boolean simulationComplete = false; // sentinel variable as termination condition,, are we done yet? - boolean fireBool = false; - boolean destBool = false; - - // TODO reset clock to zero each time for consistent outputs - - // Your model setup: define participants. who's who in this zoo? - // Assuming you keep track of entity objects... here is some support for for Entity 1. - - // create PDU object for US Firewall and set its values. - //EntityID entityID_1 = new EntityID(); - //entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; - - EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu(); - entityStatePdu_1.setEntityID(createFriendFireWall()); - entityStatePdu_1.setEntityType(createFriendFireWallType()); - entityStatePdu_1.getEntityLocation().setX(0); - entityStatePdu_1.setForceId(ForceID.FRIENDLY); - - // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? - // create PDU object for Malware Packet and set its values. - //EntityID entityID_2 = new EntityID(); - //entityID_2.setSiteID(4).setApplicationID(5).setEntityID(6); - - EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu(); - entityStatePdu_2.setEntityID(createMalPacket()); - entityStatePdu_2.setEntityType(createMalPacketType()); - entityStatePdu_2.getEntityLocation().setX(7); - entityStatePdu_2.setForceId(ForceID.OPPOSING); - - int MalPacketPingsReceived = 0; - - FirePdu firePdu = pduFactory.makeFirePdu(); // for entity 1 first weapon (possible traceroute) - // should we customize this munition? what is it for your simulation? - EntityID fireID = new EntityID(); - fireID.setSiteID(13); - fireID.setApplicationID(43); - fireID.setEntityID(103); - EntityID targetID = new EntityID(); - targetID.setSiteID(66); - targetID.setApplicationID(666); - targetID.setEntityID(6666); - - firePdu.setFiringEntityID(fireID); - firePdu.setTargetEntityID(targetID); - - firePdu.setDescriptor(createTraceroute()); // calling create Traceroute Method - - EntityID TracerouteID = new EntityID(); - TracerouteID.setEntityID(1); - firePdu.setMunitionExpendibleID(TracerouteID); - - CommentReliablePdu MalPacketDestroyedComment = pduFactory.makeCommentReliablePdu("Malware Packet DESTROYED BY Firewall"); - CommentReliablePdu MalPacketDetectedComment = pduFactory.makeCommentReliablePdu("Firewall Detects Malware engage Traceroute"); - - // TODO simulation management PDUs for startup, planning to design special class support - - //DetonationPdu detonationPdu = pduFactory.makeDetonationPdu(); - //detonationPdu.setDescriptor(pDescriptor); - - - // loop the simulation while allowed, programmer can set additional conditions to break out and finish - while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet? - { - simulationLoopCount++; // good practice: increment loop counter as first action in that loop - - // ============================================================================================= - // * your own simulation code starts here! * - // ============================================================================================= - - // are there any other variables to modify at the beginning of your loop? - - // compute a track, update an ESPDU, whatever it is that your model is doing... - - // Where is my entity? Insert changes in position; this sample only changes X position. - entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX()); // stationary defensive posture - entityStatePdu_2.getEntityLocation().setX(entityStatePdu_2.getEntityLocation().getX() - 1.0); // 1m per timestep - - // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at! - Double range = entityStatePdu_2.getEntityLocation().getX(); - System.out.println("range: " + range + " hops from our Network DMZ!"); - - if (range < 5) { // Range 5 - if (!fireBool) { - sendSinglePdu(MalPacketDetectedComment); - } - fireBool = true; - System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "." + firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "." + firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "." + " at Entity#" + firePdu.getTargetEntityID().getEntityID()); - - if (firePdu.getTargetEntityID().getEntityID() == 6666) { - MalPacketPingsReceived += 1; - if (MalPacketPingsReceived > 1) { - // The Firewall destroys the MalPacket - - System.out.println("Malware Packet DESTROYED BY Firewall after " + MalPacketPingsReceived + "pings from the traceroute."); - narrativeMessage4 = "Destroyed MalPacket"; - destBool = true; - simulationComplete = true; - - } - } - } - // etc. etc. your code goes here for your simulation of interest - - // something happens between my simulation entities, la de da de da... - System.out.println ("... My simulation just did something, no really..."); - - - // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) - narrativeMessage1 = "MV3500 ExampleSimulationProgramAllen_3"; - narrativeMessage2 = "runSimulation() loop " + simulationLoopCount; - narrativeMessage3 = "this is working!"; // intentionally blank for testing - - // your loop termination condition goes here - if (simulationLoopCount > 4) // for example - { - simulationComplete = true; - } - // ============================================================================================= - // * your own simulation code is finished here! * - // ============================================================================================= - - // staying synchronized with timestep: wait duration for elapsed time in this loop - // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes - Thread.sleep((long)(SIMULATION_LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds - System.out.println ("... [Pausing for " + SIMULATION_LOOP_DURATION_SECONDS + " seconds]"); - - // OK now send the status PDUs for this loop, and then continue - System.out.println ("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); - sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); - sendSinglePdu(entityStatePdu_2); // me too i.e. 2! - System.out.println ("... [PDUs successfully sent for this loop]"); - - // =============================== - // loop now finished, check whether to terminate if simulation complete, otherwise continue - if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good - { - //sendSinglePdu(detonationPdu); - System.out.println ("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + - break; - } - } // end of simulation loop - - narrativeMessage2 = "runSimulation() completed successfully"; // all done - sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); - System.out.println ("... [final CommentPdu successfully sent for simulation]"); - // TODO simulation management PDUs - } - catch (InterruptedException iex) // handle any exception that your code might choose to provoke! - { - Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, iex); - } - } - /* **************************** infrastructure code, modification is seldom needed ************************* */ - - String narrativeMessage1 = new String(); - String narrativeMessage2 = new String(); - String narrativeMessage3 = new String(); - String narrativeMessage4 = new String(); - - /* VariableRecordType enumerations have potential use with CommentPdu logs */ - /* TODO contrast to EntityType */ - VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION; - VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT; - VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS; - VariableRecordType timeStepComment = VariableRecordType.APPLICATION_TIMESTEP; - VariableRecordType otherComment = VariableRecordType.OTHER; - - /** - * Output prefix to identify this class, helps with logging - */ - private final static String TRACE_PREFIX = "[" + ExampleSimulationProgram.class.getName() + "] "; - - // class variables - PduFactory pduFactory = new PduFactory(); - DisThreadedNetworkInterface disNetworkInterface; - DisThreadedNetworkInterface.PduListener pduListener; - Pdu receivedPdu; - PduRecorder pduRecorder; - - /** - * Constructor design goal: additional built-in initialization conveniences can go here - * to keep student efforts focused on the runSimulation() method. - */ - public ExampleSimulationProgram() - { - // Constructor is under consideration. Constructor is not currently needed. - } - - /** - * Utility Constructor that allows your example simulation program to override default network address and port - * @param address network address to use - * @param port corresponding network port to use - */ - public ExampleSimulationProgram(String address, int port) - { - setNetworkAddress(address); - - setNetworkPort(port); - } - - /** - * get networkAddress - * @return the networkAddress - */ - public String getNetworkAddress() - { - return networkAddress; - } - - /** - * set networkAddress - * @param newNetworkAddress the networkAddress to set - */ - public final void setNetworkAddress(String newNetworkAddress) - { - ExampleSimulationProgram.networkAddress = newNetworkAddress; - } - - /** - * get networkPort - * @return the networkPort - */ - public int getNetworkPort() - { - return networkPort; - } - - /** - * set networkPort - * @param newNetworkPort the networkPort to set - */ - public final void setNetworkPort(int newNetworkPort) - { - ExampleSimulationProgram.networkPort = newNetworkPort; - } - - /** - * Initialize network interface, choosing best available network interface - */ - public void setUpNetworkInterface() - { - disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); - disNetworkInterface.setDescriptor ("ExampleSimulationProgramAllen_3 pdu looping"); - - System.out.println("Network confirmation:" + - " address=" + disNetworkInterface.getAddress()+ // disNetworkInterface.getMulticastGroup() + - " port=" + disNetworkInterface.getPort()); // + disNetworkInterface.getDisPort()); - pduListener = new DisThreadedNetworkInterface.PduListener() - { - /** Callback handler for listener */ - @Override - public void incomingPdu(Pdu newPdu) - { - receivedPdu = newPdu; - } - }; - disNetworkInterface.addListener(pduListener); - - String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; - System.out.println("Beginning pdu save to directory " + outputDirectory); - pduRecorder = new PduRecorder(outputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save - pduRecorder.setDescriptor ("ExampleSimulationProgramAllen_3 pduRecorder"); - pduRecorder.start(); // begin running - } - - /** All done, release network resources */ - public void tearDownNetworkInterface() - { - pduRecorder.stop(); - - disNetworkInterface.removeListener(pduListener); - - disNetworkInterface.close(); -// disNetworkInterface.kill(); // renamed as close(), deprecated -// disNetworkInterface = null; // making sure no possibility of zombie process remaining... - } - - /** - * Send a single Protocol Data Unit (PDU) of any type - * @param pdu the pdu to send - */ - private void sendSinglePdu(Pdu pdu) - { - try - { - disNetworkInterface.send(pdu); - Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally - } - catch (InterruptedException ex) - { - System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); - System.exit(1); - } - } - - /** - * Send Comment PDU - * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments - * @param commentType enumeration value describing purpose of the narrative comment - * @param comments String array of narrative comments - */ - public void sendCommentPdu(VariableRecordType commentType, - // vararg... variable-length set of String comments can optionally follow - String... comments) - { - sendAllPdusForLoopTimestep (null, null, commentType, comments); - } - - /** - * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. - * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments - * @param entityStatePdu the ESPDU to send, if any - * @param firePdu the FirePDU to send, if any - * @param commentType enumeration value describing purpose of the narrative comment - * @param comments String array of narrative comments - */ - public void sendAllPdusForLoopTimestep(EntityStatePdu entityStatePdu, - FirePdu firePdu, - VariableRecordType commentType, - // vararg... variable-length set of String comments can optionally follow - String... comments) - { - if (entityStatePdu != null) - sendSinglePdu(entityStatePdu); - - if (firePdu != null) - sendSinglePdu(firePdu); // bang - - if ((comments != null) && (comments.length > 0)) - { - ArrayList<String> newCommentsList = new ArrayList<>(); - for (String comment : comments) - { - if (!comment.isEmpty()) - { - newCommentsList.add(comment); // OK found something to send - } - } - if (!newCommentsList.isEmpty()) - { - if (commentType == null) - commentType = otherComment; // fallback value otherComment - // now build the commentPdu from these string inputs, thus constructing a narrative entry - CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); - sendSinglePdu(commentPdu); - if (isVerboseComments()) - System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString()); - } - } - } - - /** - * Main method is first executed when a program instance is loaded. - * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> - * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation - */ - public static void main(String[] args) - { - System.out.println(TRACE_PREFIX + "started..."); - - ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance - - // initial execution: can handle args array of initialization arguments here - if (args.length == 2) - { - if ((args[0] != null) && !args[0].isEmpty()) - thisProgram.setNetworkAddress(args[0]); - - if ((args[1] != null) && !args[1].isEmpty()) - thisProgram.setNetworkPort(Integer.parseInt(args[1])); - } - else if (args.length != 0) - { - System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); - System.exit(-1); - } - // OK here we go... - - thisProgram.setUpNetworkInterface(); - - thisProgram.runSimulationLoops (); // ... your simulation execution code goes in there ... - - thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering - - System.out.println(TRACE_PREFIX + "complete."); // report successful completion - } - - /** - * get whether verbose comments are enabled - * @return whether verboseComments mode is enabled - */ - public boolean isVerboseComments() { - return verboseComments; - } - - /** - * set whether verbose comments are enabled - * @param newVerboseComments whether verboseComments mode is enabled - */ - public void setVerboseComments(boolean newVerboseComments) { - this.verboseComments = newVerboseComments; - } -} +/** + * Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + * + * This Program is a modified version of ExampleSimulationProgram in order to see the + * verbose plain text pdu log. This simulates a firewall identifying a malicious packet + * and tracing its source before destroying it - updated September 12, 2021 to ensure + * correct file pushed to Gitlab. + * + * @author William Oblak (Changes made from copy given in class) + */ +package MV3500Cohort2023MarchJune.homework3.Oblak; + +import edu.nps.moves.dis7.enumerations.*; // match any +import edu.nps.moves.dis7.pdus.*; // match any of the PDU classes, easier than listing individually +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; +import edu.nps.moves.dis7.utilities.PduFactory; +import edu.nps.moves.dis7.utilities.stream.PduRecorder; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** The purpose of this program is to provide an easily modifiable example simulation program + * that includes DIS-capable entities doing tasks and reporting them to the network. + * Default settings include PDU recording turned on by default. + */ +public class ExampleSimulationProgram +{ + private boolean verboseComments = true; + private boolean verboseDisInterface = false; + static final String NETWORK_ADDRESS_DEFAULT = "239.1.2.3"; + static final int NETWORK_PORT_DEFAULT = 3000; + static String networkAddress = NETWORK_ADDRESS_DEFAULT; + static int networkPort = NETWORK_PORT_DEFAULT; + String DEFAULT_OUTPUT_DIRECTORY = "./pduLog"; + + private EntityID createFriendFireWall() { + EntityID FNFireWallID = new EntityID(); // 1.1.225.1.1.1 Platform,Cyber,USA,FireWall + FNFireWallID.setSiteID(13); + FNFireWallID.setApplicationID(43); + FNFireWallID.setEntityID(103); + return FNFireWallID; + } + + private EntityType createFriendFireWallType() { + EntityType FNFireWallType = new EntityType(); + FNFireWallType.setEntityKind(EntityKind.PLATFORM); + FNFireWallType.setDomain(Domain.inst(PlatformDomain.OTHER)); + FNFireWallType.setCountry(Country.AUSTRALIA_AUS); + FNFireWallType.setCategory(3); + FNFireWallType.setSubCategory(1); + FNFireWallType.setSpecific(1); + return FNFireWallType; + } + + private EntityID createMalPacket() { + EntityID MalPacketID = new EntityID(); // 1.1.45.1.7.1 Platform,Cyber,China,MaliciousPacket + MalPacketID.setSiteID(66); + MalPacketID.setApplicationID(666); + MalPacketID.setEntityID(6666); + return MalPacketID; + } + + private EntityType createMalPacketType() { + EntityType MalPacketType = new EntityType(); + MalPacketType.setEntityKind(EntityKind.PLATFORM); + MalPacketType.setDomain(Domain.inst(PlatformDomain.OTHER)); + MalPacketType.setCountry(Country.CHINA_PEOPLES_REPUBLIC_OF_CHN); + MalPacketType.setCategory(3); + MalPacketType.setSubCategory(1); + MalPacketType.setSpecific(1); + return MalPacketType; + } + + private MunitionDescriptor createTraceroute() { + + EntityType TracerouteType = new EntityType(); //2.2.225.2.13.1 + TracerouteType.setEntityKind(EntityKind.MUNITION); + TracerouteType.setDomain(Domain.inst(PlatformDomain.OTHER)); + TracerouteType.setCountry(Country.AUSTRALIA_AUS); + TracerouteType.setCategory(2); + TracerouteType.setSubCategory(8); + TracerouteType.setSpecific(1); + MunitionDescriptor Traceroute = new MunitionDescriptor(); + Traceroute.setMunitionType(TracerouteType); + Traceroute.setQuantity(1000); + Traceroute.setFuse(MunitionDescriptorFuse.CONTACT); + Traceroute.setRate(200); + return Traceroute; + } + + /** + * This runSimulationLoops() method is for you, a + * programmer-modifiable method for defining and running a new simulation of interest. + * Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that + * you can focus on your model entities and activities. + * Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + * Continuous improvement efforts seek to make this program as easy and straightforward + * as possible for DIS simulationists to use and adapt. + * All of the other methods are setup, teardown and configuration that you may find + * interesting, even helpful, but don't really have to worry about. + */ + @SuppressWarnings("SleepWhileInLoop") // yes we do that + public void runSimulationLoops () + { + try + { + /** seconds for real-time execution (not simulation time, which may or may not be the same) */ + final double SIMULATION_LOOP_DURATION_SECONDS = 1.0; + final int SIMULATION_MAX_LOOP_COUNT = 10; // be deliberate out out there! also avoid infinite loops. + int simulationLoopCount = 0; // variable, initialized at 0 + boolean simulationComplete = false; // sentinel variable as termination condition,, are we done yet? + boolean fireBool = false; + boolean destBool = false; + + // TODO reset clock to zero each time for consistent outputs + + // Your model setup: define participants. who's who in this zoo? + // Assuming you keep track of entity objects... here is some support for for Entity 1. + + // create PDU object for US Firewall and set its values. + //EntityID entityID_1 = new EntityID(); + //entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + + EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu(); + entityStatePdu_1.setEntityID(createFriendFireWall()); + entityStatePdu_1.setEntityType(createFriendFireWallType()); + entityStatePdu_1.getEntityLocation().setX(0); + entityStatePdu_1.setForceId(ForceID.FRIENDLY); + + // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? + // create PDU object for Malware Packet and set its values. + //EntityID entityID_2 = new EntityID(); + //entityID_2.setSiteID(4).setApplicationID(5).setEntityID(6); + + EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu(); + entityStatePdu_2.setEntityID(createMalPacket()); + entityStatePdu_2.setEntityType(createMalPacketType()); + entityStatePdu_2.getEntityLocation().setX(7); + entityStatePdu_2.setForceId(ForceID.OPPOSING); + + int MalPacketPingsReceived = 0; + + FirePdu firePdu = pduFactory.makeFirePdu(); // for entity 1 first weapon (possible traceroute) + // should we customize this munition? what is it for your simulation? + EntityID fireID = new EntityID(); + fireID.setSiteID(13); + fireID.setApplicationID(43); + fireID.setEntityID(103); + EntityID targetID = new EntityID(); + targetID.setSiteID(66); + targetID.setApplicationID(666); + targetID.setEntityID(6666); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + firePdu.setDescriptor(createTraceroute()); // calling create Traceroute Method + + EntityID TracerouteID = new EntityID(); + TracerouteID.setEntityID(1); + firePdu.setMunitionExpendibleID(TracerouteID); + + CommentReliablePdu MalPacketDestroyedComment = pduFactory.makeCommentReliablePdu("Malware Packet DESTROYED BY Firewall"); + CommentReliablePdu MalPacketDetectedComment = pduFactory.makeCommentReliablePdu("Firewall Detects Malware engage Traceroute"); + + // TODO simulation management PDUs for startup, planning to design special class support + + //DetonationPdu detonationPdu = pduFactory.makeDetonationPdu(); + //detonationPdu.setDescriptor(pDescriptor); + + + // loop the simulation while allowed, programmer can set additional conditions to break out and finish + while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet? + { + simulationLoopCount++; // good practice: increment loop counter as first action in that loop + + // ============================================================================================= + // * your own simulation code starts here! * + // ============================================================================================= + + // are there any other variables to modify at the beginning of your loop? + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? Insert changes in position; this sample only changes X position. + entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX()); // stationary defensive posture + entityStatePdu_2.getEntityLocation().setX(entityStatePdu_2.getEntityLocation().getX() - 1.0); // 1m per timestep + + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at! + Double range = entityStatePdu_2.getEntityLocation().getX(); + System.out.println("range: " + range + " hops from our Network DMZ!"); + + if (range < 5) { // Range 5 + if (!fireBool) { + sendSinglePdu(MalPacketDetectedComment); + } + fireBool = true; + System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "." + firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "." + firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "." + " at Entity#" + firePdu.getTargetEntityID().getEntityID()); + + if (firePdu.getTargetEntityID().getEntityID() == 6666) { + MalPacketPingsReceived += 1; + if (MalPacketPingsReceived > 1) { + // The Firewall destroys the MalPacket + + System.out.println("Malware Packet DESTROYED BY Firewall after " + MalPacketPingsReceived + " pings from the traceroute."); + narrativeMessage4 = "Destroyed MalPacket"; + destBool = true; + simulationComplete = true; + + } + } + } + // etc. etc. your code goes here for your simulation of interest + + // something happens between my simulation entities, la de da de da... + // System.out.println ("... My simulation just did something, no really..."); + + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 ExampleSimulationProgram Oblak"; + narrativeMessage2 = "runSimulation() loop " + simulationLoopCount; + narrativeMessage3 = "this is working!"; // intentionally blank for testing + + // your loop termination condition goes here + if (simulationLoopCount > 4) // for example + { + simulationComplete = true; + } + // ============================================================================================= + // * your own simulation code is finished here! * + // ============================================================================================= + + // staying synchronized with timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(SIMULATION_LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + // System.out.println ("... [Pausing for " + SIMULATION_LOOP_DURATION_SECONDS + " seconds]"); + + // OK now send the status PDUs for this loop, and then continue + // System.out.println ("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); + sendSinglePdu(entityStatePdu_2); // me too i.e. 2! + // System.out.println ("... [PDUs successfully sent for this loop]"); + + // =============================== + // loop now finished, check whether to terminate if simulation complete, otherwise continue + if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good + { + //sendSinglePdu(detonationPdu); + System.out.println ("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + + break; + } + } // end of simulation loop + + narrativeMessage2 = "runSimulation() completed successfully"; // all done + sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); + System.out.println ("... [final CommentPdu successfully sent for simulation]"); + // TODO simulation management PDUs + } + catch (InterruptedException iex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, iex); + } + } + /* **************************** infrastructure code, modification is seldom needed ************************* */ + + String narrativeMessage1 = new String(); + String narrativeMessage2 = new String(); + String narrativeMessage3 = new String(); + String narrativeMessage4 = new String(); + + /* VariableRecordType enumerations have potential use with CommentPdu logs */ + /* TODO contrast to EntityType */ + VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION; + VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT; + VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS; + VariableRecordType timeStepComment = VariableRecordType.APPLICATION_TIMESTEP; + VariableRecordType otherComment = VariableRecordType.OTHER; + + /** + * Output prefix to identify this class, helps with logging + */ + private final static String TRACE_PREFIX = "[" + ExampleSimulationProgram.class.getName() + "] "; + + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + PduRecorder pduRecorder; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public ExampleSimulationProgram() + { + // Constructor is under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor that allows your example simulation program to override default network address and port + * @param address network address to use + * @param port corresponding network port to use + */ + public ExampleSimulationProgram(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * get networkAddress + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * set networkAddress + * @param newNetworkAddress the networkAddress to set + */ + public final void setNetworkAddress(String newNetworkAddress) + { + ExampleSimulationProgram.networkAddress = newNetworkAddress; + } + + /** + * get networkPort + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * set networkPort + * @param newNetworkPort the networkPort to set + */ + public final void setNetworkPort(int newNetworkPort) + { + ExampleSimulationProgram.networkPort = newNetworkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + disNetworkInterface.setDescriptor ("ExampleSimulationProgram Oblak pdu looping"); + // trying to slience DIS logging so that the simulation progress is easier to follow + disNetworkInterface.setVerbose(verboseDisInterface); + disNetworkInterface.setVerboseIncludesTimestamp(verboseDisInterface); + disNetworkInterface.setVerboseReceipt(verboseDisInterface); + disNetworkInterface.setVerboseSending(verboseDisInterface); + + System.out.println("Network confirmation:" + + " address=" + disNetworkInterface.getAddress()+ // disNetworkInterface.getMulticastGroup() + + " port=" + disNetworkInterface.getPort()); // + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + + String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; + System.out.println("Beginning pdu save to directory " + outputDirectory); + pduRecorder = new PduRecorder(outputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save + pduRecorder.setDescriptor ("ExampleSimulationProgram Oblak pduRecorder"); + // trying to slience DIS logging so that the simulation progress is easier to follow + pduRecorder.setVerbose(verboseDisInterface); + pduRecorder.setVerboseIncludesTimestamp(verboseDisInterface); + pduRecorder.setVerboseReceipt(verboseDisInterface); + pduRecorder.setVerboseSending(verboseDisInterface); + + pduRecorder.start(); // begin running + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + pduRecorder.stop(); + + disNetworkInterface.removeListener(pduListener); + + disNetworkInterface.close(); +// disNetworkInterface.kill(); // renamed as close(), deprecated +// disNetworkInterface = null; // making sure no possibility of zombie process remaining... + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send Comment PDU + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param commentType enumeration value describing purpose of the narrative comment + * @param comments String array of narrative comments + */ + public void sendCommentPdu(VariableRecordType commentType, + // vararg... variable-length set of String comments can optionally follow + String... comments) + { + sendAllPdusForLoopTimestep (null, null, commentType, comments); + } + + /** + * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing purpose of the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdusForLoopTimestep(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable-length set of String comments can optionally follow + String... comments) + { + if (entityStatePdu != null) + sendSinglePdu(entityStatePdu); + + if (firePdu != null) + sendSinglePdu(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (String comment : comments) + { + if (!comment.isEmpty()) + { + newCommentsList.add(comment); // OK found something to send + } + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = otherComment; // fallback value otherComment + // now build the commentPdu from these string inputs, thus constructing a narrative entry + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendSinglePdu(commentPdu); + if (isVerboseComments()) + System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString()); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + System.out.println(TRACE_PREFIX + "started..."); + + ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulationLoops (); // ... your simulation execution code goes in there ... + + thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering + + System.out.println(TRACE_PREFIX + "complete."); // report successful completion + } + + /** + * get whether verbose comments are enabled + * @return whether verboseComments mode is enabled + */ + public boolean isVerboseComments() { + return verboseComments; + } + + /** + * set whether verbose comments are enabled + * @param newVerboseComments whether verboseComments mode is enabled + */ + public void setVerboseComments(boolean newVerboseComments) { + this.verboseComments = newVerboseComments; + } +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgramLog.txt b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgramLog.txt index 98a0e3d775fc5126379119fd4afbbff91136509b..f1e186fc0ead342faf5e6f47dd0f8c244787c7d9 100644 Binary files a/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgramLog.txt and b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgramLog.txt differ diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/PduCaptureLog.dislog b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/PduCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..c86d70df6a187f1e29def6f164d0e761f04e3638 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Oblak/PduCaptureLog.dislog @@ -0,0 +1,53 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\assignments -Dnb.internal.action.name=run.single -Djavac.includes=MV3500Cohort2023MarchJune/homework3/Oblak/ExampleSimulationProgram.java -Drun.class=MV3500Cohort2023MarchJune.homework3.Oblak.ExampleSimulationProgram run-single +init: +Deleting: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\built-jar.properties +deps-jar: +Updating property file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\built-jar.properties +Compiling 1 source file to C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\classes +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[MV3500Cohort2023MarchJune.homework3.Oblak.ExampleSimulationProgram] started... +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz +[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. +[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true +[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true +Network confirmation: address=239.1.2.3 port=3000 +Beginning pdu save to directory ./pduLog +[PduRecorder ExampleSimulationProgramAllen_3 pduRecorder] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\assignments\pduLog\PduCaptureLog11.dislog +[PduRecorder ExampleSimulationProgramAllen_3 pduRecorder] listening to IP address 239.1.2.3 on port 3000 +range: 6.0 hops from our Network DMZ! +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +sending PDUs for simulation step 1, monitor loopback to confirm sent +*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgramAllen_3, runSimulation() loop 1, this is working!] +... [PDUs successfully sent for this loop] +range: 5.0 hops from our Network DMZ! +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +sending PDUs for simulation step 2, monitor loopback to confirm sent +*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgramAllen_3, runSimulation() loop 2, this is working!] +... [PDUs successfully sent for this loop] +range: 4.0 hops from our Network DMZ! +Entity#103 is firing Other.Country 13 AUSTRALIA_AUS.2.8.1. at Entity#6666 +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +sending PDUs for simulation step 3, monitor loopback to confirm sent +*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgramAllen_3, runSimulation() loop 3, this is working!] +... [PDUs successfully sent for this loop] +range: 3.0 hops from our Network DMZ! +Entity#103 is firing Other.Country 13 AUSTRALIA_AUS.2.8.1. at Entity#6666 +Malware Packet DESTROYED BY Firewall after 2pings from the traceroute. +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +sending PDUs for simulation step 4, monitor loopback to confirm sent +*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgramAllen_3, runSimulation() loop 4, this is working!] +... [PDUs successfully sent for this loop] +... [Termination condition met, simulationComplete=true] +*** [Narrative comment sent: COMPLETE_EVENT_REPORT] [MV3500 ExampleSimulationProgramAllen_3, runSimulation() completed successfully, this is working!] +... [final CommentPdu successfully sent for simulation] + +PduRecorder.stop() closing recorder log file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\assignments\pduLog\PduCaptureLog11.dislog +[MV3500Cohort2023MarchJune.homework3.Oblak.ExampleSimulationProgram] complete. +BUILD SUCCESSFUL (total time: 14 seconds) diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/README.md b/assignments/src/MV3500Cohort2023MarchJune/homework3/README.md index 78951850a827c40841985693863e8d7fd7849b4a..195b95c32bf201f62588afda0533d35b0eb02f2b 100644 --- a/assignments/src/MV3500Cohort2023MarchJune/homework3/README.md +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/README.md @@ -1,14 +1,19 @@ -## Homework 3: Example Simulation Recording OpenDIS Network Streams +## Homework 3: Example Simulation Recording using OpenDIS Network Streams ### Assignment -* Adapt the functionality for [OpenDIS ExampleSimulationProgram](../../../../examples/src/OpenDis7Examples/ExampleSimulationProgram.java), modifying provided code -* Result streams are recorded/saved/replayed using [PduRecorder](https://savage.nps.edu/opendis7-java/javadoc/edu/nps/moves/dis7/utilities/stream/PduRecorder.html), [Wireshark](https://www.wireshark.org) or [X3D-Edit](https://savage.nps.edu/X3D-Edit). +1. Adapt the functionality for [OpenDIS ExampleSimulationProgram](../../../../examples/src/OpenDis7Examples/ExampleSimulationProgram.java), modifying provided code +2. Experiment with the enumeration values that set up each entity and PDU. What works for you? What makes sense for your future work? +3. Adapt or replace the UML diagrams to describe what you have going on. +4. Record, save and replay your result stream using [PduRecorder](https://savage.nps.edu/opendis7-java/javadoc/edu/nps/moves/dis7/utilities/stream/PduRecorder.html) or [Wireshark](https://www.wireshark.org) + * see local [assignments/src/pduLog](../../../pduLog) subdirectory for latest opendis log files + * Coming soon, we will also (again have) [X3D-Edit](https://savage.nps.edu/X3D-Edit) for DIS stream recording/replay +5. Observe good-practice conventions in the [assignments README](../../../README.md) and [current-course README](../README.md) instructions. This assignment presents a Problem Prototyping opportunity. While some minimal functionality is expected, the general outline of a networking problem and proposed solution holds great interest. -Think of it as a warmup preparation for your final project. +Think of it as warmup preparation for your future work. This is also a freeplay opportunity. You have the option to pick one or more of the provided course example programs @@ -17,8 +22,8 @@ and adapt the source to demonstrate a new client-server handshake protocol of in Be sure to provide a rationale that justifies why the networking choices you made (TCP/UDP, unicast/multicast, etc.) are the best for the problem you are addressing. -Refer to [homework2 README](../homework2/README.md) and [assignments README](../../../README.md) -for further details on what specific deliverables are expected in each homework assignment. +You may find that the prior [homework2 README](../homework2/README.md) still provides +helpful details on what specific deliverables are expected in each homework assignment. Team efforts are encouraged, though if you choose a team approach be sure to justify why. This is a good warmup prior to final projects. Have fun with Java networking! diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Sloan/package-info.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Sloan/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..b4a4c653405d45182b164b2f80cf37cfc277e9bb --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Sloan/package-info.java @@ -0,0 +1,10 @@ +/** + * Final project assignments supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a> + * @see java.lang.Package + * @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful">StackOverflow: why-is-package-info-java-useful</a> + * @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java">StackOverflow: how-do-i-document-packages-in-java</a> + */ + +package MV3500Cohort2023MarchJune.homework3.Sloan; diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/.DS_Store b/assignments/src/MV3500Cohort2023MarchJune/projects/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..80878e3412d0634604e7b9926bedb652267797ee Binary files /dev/null and b/assignments/src/MV3500Cohort2023MarchJune/projects/.DS_Store differ diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Customer.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Customer.java new file mode 100644 index 0000000000000000000000000000000000000000..ce0d4e839d272f746531854f46af047095098c47 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Customer.java @@ -0,0 +1,54 @@ +import java.io.*; +import java.net.*; + +public class Client_Customer { + public static void main(String[] args) { + + // TODO - Fill out the following questionairre: + + double averageBeefPurchase = 2; // How many pounds of beef do you typically purchase when you buy groceries? + double averageVariationInBeefPurchase = 0.5; // How much do you typically vary from the above amount (also in pounds)? + + double averagePorkPurchase = 4; // How many pounds of pork do you typically purchase when you buy groceries? + double averageVariationInPorkPurchase = 0.5; // How much do you typically vary from the above amount (also in pounds)? + + double averageChickenPurchase = 6; // How many pounds of chicken do you typically purchase when you buy groceries? + double averageVariationInChickenPurchase = 0.5; // How much do you typically vary from the above amount (also in pounds)? + + double averageEggsPurchase = 2; // How many eggs do you typically purchase when you buy groceries (amount in dozens)? + double averageVariationInEggsPurchase = 0.5; // How much do you typically vary from the above amount (also in dozens)? + + // End of TODO section + + Customer myCustomer = new Customer(averageBeefPurchase, averageVariationInBeefPurchase, averagePorkPurchase, averageVariationInPorkPurchase, averageChickenPurchase, averageVariationInChickenPurchase, averageEggsPurchase, averageVariationInEggsPurchase); + + try { + // Create client socket and connect to the server + Socket clientSocket = new Socket("localhost", 12345); + System.out.println("Connected to server."); + + // Send request to server + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + String request = "doTransaction," + myCustomer.getBeefPreference().generate() + "," + myCustomer.getPorkPreference().generate() + "," + myCustomer.getChickenPreference().generate() + "," + myCustomer.getEggsPreference().generate(); + out.println(request); + System.out.println("Sent request to server: " + request); + + // Receive response from server + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + StringBuilder responseBuilder = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + responseBuilder.append(line).append("\n"); + } + String response = responseBuilder.toString(); + System.out.print("Received response from server: " + response); + + // Close connections + in.close(); + out.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Farm.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Farm.java new file mode 100644 index 0000000000000000000000000000000000000000..f5385a7da7b12daec9698f1ac230642118f27855 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Client_Farm.java @@ -0,0 +1,50 @@ +import java.io.*; +import java.net.*; + +public class Client_Farm { + public static void main(String[] args) { + + // TODO - Fill out the following questionairre: + + int cattleCount = 50; // How many cows are on the farm? + + int pigCount = 50; // How many pigs are on the farm? + + int broilerChickenCount = 300; // How many broiler chickens (think supermarket chickens - they don't lay eggs) are on the farm? + + int layerChickenCount = 500; // How many egg laying chickens are on the farm? + + // End of TODO section + + LivestockRanch myFarm = new LivestockRanch(cattleCount, pigCount, broilerChickenCount, layerChickenCount); + + try { + // Create client socket and connect to the server + Socket clientSocket = new Socket("localhost", 12345); + System.out.println("Connected to server."); + + // Send request to server + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + String request = "doResupply," + myFarm.getCattleProcessRate() + "," + myFarm.getPigProcessRate() + "," + myFarm.getChickenProcessRate() + "," + myFarm.getEggLayingRate(); + out.println(request); + System.out.println("Sent request to server: " + request); + + // Receive response from server + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + StringBuilder responseBuilder = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + responseBuilder.append(line).append("\n"); + } + String response = responseBuilder.toString(); + System.out.print("Received response from server: " + response); + + // Close connections + in.close(); + out.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Customer.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Customer.java new file mode 100644 index 0000000000000000000000000000000000000000..1ae3e48540c630bef80513b18ac5e8b986479bc1 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Customer.java @@ -0,0 +1,56 @@ +import simkit.SimEntityBase; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; + +public class Customer extends SimEntityBase{ + private RandomVariate beefPreference; + private RandomVariate porkPreference; + private RandomVariate chickenPreference; + private RandomVariate eggsPreference; + + public Customer(double averagePurchaseOfBeef, double beefPlusMinus, double averagePurchaseOfPork, double porkPlusMinus, double averagePurchaseOfChicken, double chickenPlusMinus, double averagePurchaseOfEggs, double eggsPlusMinus) { + this.beefPreference = RandomVariateFactory.getInstance("Normal", averagePurchaseOfBeef, beefPlusMinus); + this.porkPreference = RandomVariateFactory.getInstance("Normal", averagePurchaseOfPork, porkPlusMinus); + this.chickenPreference = RandomVariateFactory.getInstance("Normal", averagePurchaseOfChicken, chickenPlusMinus); + this.eggsPreference = RandomVariateFactory.getInstance("Normal", averagePurchaseOfEggs, eggsPlusMinus); + } + + public void doRun() { + waitDelay("Transaction", 0.0); + } + + public void doTransaction() { + double beef = beefPreference.generate(); + beef = beef < 0 ? 0 : beef; + + double pork = porkPreference.generate(); + pork = pork < 0 ? 0 : pork; + + double chicken = chickenPreference.generate(); + chicken = chicken < 0 ? 0 : chicken; + + double eggs = eggsPreference.generate(); + eggs = eggs < 0 ? 0 : eggs; + + waitDelay("Transaction", 0.0, beef, pork, chicken, eggs); + waitDelay("Transaction", 7.0); + } + + public RandomVariate getBeefPreference() { + return beefPreference; + } + + public RandomVariate getPorkPreference() { + return porkPreference; + } + + public RandomVariate getChickenPreference() { + return chickenPreference; + } + + public RandomVariate getEggsPreference() { + return eggsPreference; + } + + +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/FarmStore.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/FarmStore.java new file mode 100644 index 0000000000000000000000000000000000000000..b099bc6bb78dad829f520fdb6c5969fc08b72131 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/FarmStore.java @@ -0,0 +1,69 @@ +import java.text.DecimalFormat; + +public class FarmStore { + private double bankAccount; + private double BEEFCOST = 10; // Cost per pound + private double PORKCOST = 5; // Cost per pound + private double CHICKENCOST = 2; // Cost per pound + private double EGGSCOST = 2; // Cost per dozen + + protected double beefQuantity; // Quantity in pounds + protected double porkQuantity; // Quantity in pounds + protected double chickenQuantity; // Quantity in pounds + protected double eggQuantity; // Quantity in dozens + + public FarmStore() { + this.bankAccount = 0; + this.beefQuantity = 0; + this.porkQuantity = 0; + this.chickenQuantity = 0; + this.eggQuantity = 0; + } + + public String doTransaction(double beef, double pork, double chicken, double eggs) { + DecimalFormat df = new DecimalFormat("#.##"); + + if (this.beefQuantity < beef) { + beef = Math.max(this.beefQuantity, 0); + System.out.println("We are out of beef"); + } + else {beef = Double.parseDouble(df.format(beef));} + if (this.porkQuantity < pork) { + pork = Math.max(this.porkQuantity, 0); + System.out.println("We are out of pork"); + } + else {pork = Double.parseDouble(df.format(pork));} + if (this.chickenQuantity < chicken) { + chicken = Math.max(this.chickenQuantity, 0); + System.out.println("We are out of chicken"); + } + else {chicken = Double.parseDouble(df.format(chicken));} + if (this.eggQuantity < eggs) { + eggs = Math.max(this.eggQuantity, 0); + System.out.println("We are out of eggs"); + } + else {eggs = Double.parseDouble(df.format(eggs));} + + this.beefQuantity -= beef; + this.porkQuantity -= pork; + this.chickenQuantity -= chicken; + this.eggQuantity -= eggs; + + double cost = beef * BEEFCOST + pork * PORKCOST + chicken * CHICKENCOST + eggs * EGGSCOST; + cost = Double.parseDouble(df.format(cost)); + this.bankAccount += cost; + + return "Product purchased:\nBeef: " + beef + " lbs\nPork: " + pork + " lbs\nChicken: " + chicken + " lbs\nEggs: " + eggs + " dozen\nTransaction total: $" + cost; + } + + public String doResupply(double beef, double pork, double chicken, double eggs) { + this.beefQuantity += beef; + this.porkQuantity += pork; + this.chickenQuantity += chicken; + this.eggQuantity += eggs; + + return "Product received:\nBeef: " + beef + " lbs\t\tCurrent Stock: " + beefQuantity + " lbs\nPork: " + pork + + " lbs\tCurrent Stock: " + porkQuantity + " lbs\nChicken: " + chicken + " lbs\tCurrent Stock: " + chickenQuantity + + " lbs\nEggs: " + eggs + " dozen\tCurrent Stock: " + eggQuantity + " dozen\nCurrent Profit: $" + bankAccount; + } +} \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/LivestockRanch.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/LivestockRanch.java new file mode 100644 index 0000000000000000000000000000000000000000..5db0ee64982065b596cd7d7c162cd2c8e8948925 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/LivestockRanch.java @@ -0,0 +1,57 @@ +public class LivestockRanch { + private int totalCattle; + private int totalPigs; + private int totalBroilerChickens; + private int totalLayerChickens; + + private double cattleProcessRate; + private double pigProcessRate; + private double chickenProcessRate; + private double eggLayingRate; + + public LivestockRanch (int totalCattle, int totalPigs, int totalBroilerChickens, int totalLayerChickens) { + this.totalCattle = totalCattle; + this.totalPigs = totalPigs; + this.totalBroilerChickens = totalBroilerChickens; + this.totalLayerChickens = totalLayerChickens; + + this.cattleProcessRate = totalCattle * 500 / (3 * 12); // Processing 1/3 of the total population per year, 1 per month, at 500 lbs of beef per cow + this.pigProcessRate = totalPigs * 150 / 6; // Processing 1/6 of the total population per month, at 150 lbs of pork per pig + this.chickenProcessRate = totalBroilerChickens * 6 / 3; // Processing 1/3 of the total population per month, at 6 lbs per chicken + this.eggLayingRate = totalLayerChickens * (25 / 12); // 25 eggs per layer chicken (divided by 12 to be sold in dozens) + } + + public int getTotalCattle() { + return totalCattle; + } + + public int getTotalPigs() { + return totalPigs; + } + + public int getTotalBroilerChickens() { + return totalBroilerChickens; + } + + public int getTotalLayerChickens() { + return totalLayerChickens; + } + + public double getCattleProcessRate() { + return cattleProcessRate; + } + + public double getPigProcessRate() { + return pigProcessRate; + } + + public double getChickenProcessRate() { + return chickenProcessRate; + } + + public double getEggLayingRate() { + return eggLayingRate; + } + + +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Server.java b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Server.java new file mode 100644 index 0000000000000000000000000000000000000000..ed276501a874c6af3d96562e835e503c12e6faa7 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/projects/Islas/Server.java @@ -0,0 +1,72 @@ +import java.io.*; +import java.net.*; + +public class Server { + public static void main(String[] args) { + + FarmStore market = new FarmStore(); + try { + // Create server socket + ServerSocket serverSocket = new ServerSocket(12345); + System.out.println("Server listening on port 12345..."); + + while (true) { + // Accept client connection + Socket clientSocket = serverSocket.accept(); + System.out.println("Client connected: " + clientSocket.getInetAddress().getHostAddress()); + + // Start a new thread to handle the client connection + ClientHandler clientHandler = new ClientHandler(clientSocket, market); + clientHandler.start(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + static class ClientHandler extends Thread { + private Socket clientSocket; + private FarmStore market; + + public ClientHandler(Socket socket, FarmStore market) { + this.clientSocket = socket; + this.market = market; + } + + public void run() { + try { + // Read data from client + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + String request = in.readLine(); + String[] parsedRequest = request.split(","); + System.out.println("Received request from client: " + request); + + // Process request + String response = processRequest(parsedRequest[0], Double.parseDouble(parsedRequest[1]), Double.parseDouble(parsedRequest[2]), Double.parseDouble(parsedRequest[3]), Double.parseDouble(parsedRequest[4])); + System.out.print("Sending response to client: " + response); + + // Send response to client + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + out.println(response); + + // Close connections + in.close(); + out.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String processRequest(String request, double beef, double pork, double chicken, double eggs) { + // Process the request and execute the corresponding method + if (request.equals("doTransaction")) { + return market.doTransaction(beef, pork, chicken, eggs); // Assuming appropriate arguments for the method + } else if (request.equals("doResupply")) { + return market.doResupply(beef, pork, chicken, eggs); + } else { + return "Invalid request!"; + } + } + } +} diff --git a/examples/nbproject/project.xml b/examples/nbproject/project.xml index 23c562da5d72e3170fcf3162eaf5ff03b9e283da..32d374e56719a41d54963505ba47f9a71722623f 100644 --- a/examples/nbproject/project.xml +++ b/examples/nbproject/project.xml @@ -70,6 +70,7 @@ <word>simulationists</word> <word>src</word> <word>subclassed</word> + <word>subpackage</word> <word>TcpExamples</word> <word>teardown</word> <word>thisHostName</word> diff --git a/examples/pduLog/ExamplePduCaptureLog.dislog b/examples/pduLog/ExamplePduCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..6efef559a8fd6e4eb14823e1d56311d70819036d --- /dev/null +++ b/examples/pduLog/ExamplePduCaptureLog.dislog @@ -0,0 +1,54 @@ +# Start, ENCODING_PLAINTEXT, [PduRecorder] 20230604_183013, DIS capture file, .\pduLog\PduCaptureLog.dislog +# Timestamp(8 bytes),ProtocolVersion,CompatibilityVersion,ExerciseID,PduType,PduStatus,HeaderLength,PduLength,then PDU-specific data +# ============================================= +# DisPduType 11 CREATE_ENTITY, Session time 18:30:13.5, session duration 00:00:00.0, Pdu timestamp -2131319063 22:55:37.0, simulation stream interval 0 00:00:00.0 +0,0,60,-107,-83,78,20,41,7,4,11,5,-128,-10,-90,-23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 11 CREATE_ENTITY, Session time 18:30:13.5, session duration 00:00:00.0, Pdu timestamp -2131319063 22:55:37.0, simulation stream interval 0 00:00:00.0 +0,0,0,0,1,-64,110,112,7,4,11,5,-128,-10,-90,-23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 22 COMMENT, Session time 18:30:13.5, session duration 00:00:00.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,1,-58,-69,-72,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-81,-46,0,0,1,64,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,115,116,101,112,32,100,117,114,97,116,105,111,110,32,49,46,48,32,115,101,99,111,110,100,115 +# DisPduType 22 COMMENT, Session time 18:30:13.6, session duration 00:00:00.1, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,6,-108,-17,92,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-53,32,0,0,2,16,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,32,48,46,48,32,97,116,32,76,111,99,97,108,68,97,116,101,84,105,109,101,32,50,48,50,51,45,48,54,45,48,52,84,49,56,58,51,48,58,49,51,46,54,54,50,50,56,53,54,48,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:14.7, session duration 00:00:01.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,73,86,-81,-20,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,4,17,12,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 18:30:14.8, session duration 00:00:01.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,79,-14,69,60,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 18:30:15.0, session duration 00:00:01.4, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,86,70,-14,-104,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:15.1, session duration 00:00:01.5, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,93,21,15,116,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:16.2, session duration 00:00:02.6, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-97,54,-55,56,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,4,17,12,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 18:30:16.3, session duration 00:00:02.7, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-91,-105,-87,-96,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 18:30:16.4, session duration 00:00:02.8, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-84,33,1,4,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:16.5, session duration 00:00:03.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-77,10,-64,24,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:17.6, session duration 00:00:04.1, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-11,40,-96,80,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,4,17,12,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 18:30:17.7, session duration 00:00:04.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,0,-5,100,-125,48,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 18:30:17.8, session duration 00:00:04.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,1,-72,-80,108,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:17.9, session duration 00:00:04.4, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,7,-66,-30,96,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:19.0, session duration 00:00:05.5, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,74,47,123,-16,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,4,17,12,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 18:30:19.1, session duration 00:00:05.6, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,80,75,63,-60,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 18:30:19.3, session duration 00:00:05.7, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,86,-74,-12,112,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:19.4, session duration 00:00:05.8, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,94,78,-15,96,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:20.5, session duration 00:00:06.9, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,-96,68,-75,-96,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,4,17,12,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 18:30:20.6, session duration 00:00:07.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,-90,-12,29,-116,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 18:30:20.7, session duration 00:00:07.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,-83,104,49,-108,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,53,0,0 +# DisPduType 01 ENTITY_STATE, Session time 18:30:20.8, session duration 00:00:07.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 2131319063 01:04:23.0 +0,0,0,1,-77,-11,-11,-56,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 22 COMMENT, Session time 18:30:20.9, session duration 00:00:07.4, Pdu timestamp -3558 23:00:42.0, simulation stream interval 2131315505 00:05:05.0 +0,0,0,1,-70,30,81,112,7,1,22,5,-1,-1,-14,26,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,9,90,-90,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,9,90,-90,0,0,1,48,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,99,111,109,112,108,101,116,101,100,32,115,117,99,99,101,115,115,102,117,108,108,121,0,0 +# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20230604_183023, DIS capture file, .\pduLog\PduCaptureLog.dislog diff --git a/examples/pduLog/README.md b/examples/pduLog/README.md index 1e83f1026e5ecd9e83514af7eafd8f5f3d91b6e1..5e90628af63f87d6b42c39bb8cd82b5abc5113fc 100644 --- a/examples/pduLog/README.md +++ b/examples/pduLog/README.md @@ -2,6 +2,8 @@ This directory holds temporary PDU log files which may be deleted at any time! +To clean out old log files, simply run [build.xml](build.xml) target `clean.all.log.files` + Each time you run a DIS simulation and a PduRecorder is listening, another log file is created. File names are numbered sequentially and uniquely, so that important PDU log captures can later be copied and saved to where they are needed. @@ -14,4 +16,4 @@ the corresponding homework or project directory (and likely renaming as well). Note that the PDU log files are very tolerant of inline comments starting with a # character, so you can document success/failure and TODO issues there as well. -To clean out old log files, simply run [build.xml](build.xml) target `clean.all.log.files` +<!-- https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/pduLog/README.md --> diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java index 7adfd418d738a5d82fb53ee624a1dfdc11ed2a3f..0c0c4bbb3db2ba51e1f6a487ac8cc9e06f3c41f6 100644 --- a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java @@ -93,8 +93,12 @@ public class ExampleSimulationProgram */ public ExampleSimulationProgram(String address, int port) { - disChannel.setNetworkAddress(address); - disChannel.setNetworkPort (port); + disChannel.setNetworkAddress (address); + disChannel.setNetworkPort (port); + disChannel.setVerboseComments (false); // TODO rename library method to disambiguate CommentPDU + // TODO still seems really chatty... add silent mode? + disChannel.setVerboseDisNetworkInterface(false); // Default false + disChannel.setVerbosePduRecorder (false); // default false initialize(); } diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png b/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..1917aa4ef9e4a994d8b4057c7c033f2ab73b78a6 Binary files /dev/null and b/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png differ diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx b/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx index dd9909acc73b3f6ec98f3a24550ddbe423a59867..439a854c826923f7f83f705be0a76139f141d2af 100644 Binary files a/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx and b/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx differ diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt b/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt index 680573439b4d8435d086c65ab69195b49a05e53b..7c1746e4eaffb64b74c1d2b6605b4c8e63e8775c 100644 --- a/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt @@ -1,28 +1,31 @@ -ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/ExampleSimulationProgram.java -Drun.class=OpenDis7Examples.ExampleSimulationProgram run-single +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run run init: -Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Deleting: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties deps-jar: -Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties -Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes -compile-single: -run-single: -[DisChannel] thisHostName=IT160907-UWALPP -[DisThreadedNetworkInterface] using network interface PANGP Virtual Ethernet Adapter +Updating property file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +Copying 1 file to C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile: +run: +[DisChannel] thisHostName=IT160907-INFLPP +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz [DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. [DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true [DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true [DisChannel ExampleSimulationProgram] Network confirmation: address=239.1.2.3 port=3000 [DisChannel ExampleSimulationProgram] Beginning pdu save to directory ./pduLog -[PduRecorder] Recorder log file open: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog1.dislog -[DisThreadedNetworkInterface] using network interface PANGP Virtual Ethernet Adapter +[PduRecorder] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog28.dislog +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz [DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. [DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true [DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true [PduRecorder PduRecorder] listening to IP address 239.1.2.3 on port 3000 [DisChannel ExampleSimulationProgram] just checking: disChannel.getNetworkAddress()=239.1.2.3, getNetworkPort()=3000 +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [sending 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [sending 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [sending 3] DisPduType 22 COMMENT, size 80 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 3] DisPduType 22 COMMENT, size 80 bytes) @@ -34,7 +37,7 @@ run-single: [DisThreadedNetworkInterface ExampleSimulationProgram] [sending 4] DisPduType 22 COMMENT, size 112 bytes) [DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 4] DisPduType 22 COMMENT, size 112 bytes) [DisThreadedNetworkInterface PduRecorder] [receipt 4] DisPduType 22 COMMENT, size 112 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu TIME] [Simulation time 0.0 at LocalDateTime 2022-06-25T21:11:35.986332500] +[DisChannel ExampleSimulationProgram] *** [CommentPdu TIME] [Simulation time 0.0 at LocalDateTime 2023-05-15T12:17:06.454742800] ... My simulation just did something, no really... ... [Pausing for 1.0 seconds] ... sending PDUs of interest for simulation step 1, monitor loopback to confirm sent @@ -126,19 +129,19 @@ run-single: [DisThreadedNetworkInterface PduRecorder] [receipt 25] DisPduType 22 COMMENT, size 120 bytes) [DisChannel ExampleSimulationProgram] *** [CommentPdu COMPLETE_EVENT_REPORT] [MV3500 ExampleSimulationProgram, runSimulation() completed successfully] ... [final=completion CommentPdu successfully sent for simulation] -*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=false receiveThread.isInterrupted()=true +*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true [DisThreadedNetworkInterface PduRecorder] close(): pdus2send.size()=0 baos.size()=0 dos.size()=0 [DisThreadedNetworkInterface PduRecorder] datagramSocket.leaveGroup address=239.1.2.3 port=3000 isClosed()=true close() complete. *** killThread() status: sendingThread.isAlive()=false sendingThread.isInterrupted()=true *** killThread() status: receiveThread.isAlive()=false receiveThread.isInterrupted()=true *** Thread close status: sendingThread.isAlive()=false receiveThread.isAlive()=false -PduRecorder.stop() closing recorder log file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog1.dislog -*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=false receiveThread.isInterrupted()=true +PduRecorder.stop() closing recorder log file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog28.dislog +*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true [DisThreadedNetworkInterface ExampleSimulationProgram] close(): pdus2send.size()=0 baos.size()=0 dos.size()=2808 [DisThreadedNetworkInterface ExampleSimulationProgram] datagramSocket.leaveGroup address=239.1.2.3 port=3000 isClosed()=true close() complete. *** killThread() status: sendingThread.isAlive()=false sendingThread.isInterrupted()=true *** killThread() status: receiveThread.isAlive()=false receiveThread.isInterrupted()=true *** Thread close status: sendingThread.isAlive()=false receiveThread.isAlive()=false [DisChannel ExampleSimulationProgram] complete. -BUILD SUCCESSFUL (total time: 13 seconds) +BUILD SUCCESSFUL (total time: 14 seconds) diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png b/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png index 5c31eb56c3af8febd139281b610bfdc0bdf3bf95..da2290863bec43303a3f377ce9442e747e116f29 100644 Binary files a/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png and b/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png differ diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx b/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx index 3292032c0c91b48be6858ce8aa60c8735cc21ccd..9c12e5d7c5cdcc9d670f0288bdc6002bf541a9b8 100644 Binary files a/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx and b/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx differ diff --git a/nbproject/project.xml b/nbproject/project.xml index 39294ac24a15458c01a96bc44f7ab5f89f853b49..7e9ae99737f9146c0b175e6431a5bcebb28391ca 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -36,19 +36,28 @@ auxiliary.show.customizer.message=<message> <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1"> <word>archivally</word> <word>autogenerated</word> + <word>brutzman</word> + <word>codebase</word> <word>codebases</word> <word>DIS</word> + <word>gitlab</word> + <word>html</word> <word>https</word> + <word>IITSEC</word> <word>integrators</word> <word>interoperability</word> <word>interoperable</word> + <word>Javadoc</word> <word>LVC</word> + <word>McGregor</word> <word>multicast</word> <word>NPS</word> + <word>opendis</word> <word>PDUs</word> <word>Redistributions</word> <word>TENA</word> <word>UML</word> + <word>wargaming</word> <word>WebRTC</word> <word>Wikipedia</word> </spellchecker-wordlist> diff --git a/presentations/07_NetworkScalability.pptx b/presentations/07_NetworkScalability.pptx index 2c23853c4598afaba4018b76f9448a351193c5a6..17ac41ca94694f8ce0c67ff31bead3bab2e7531c 100644 Binary files a/presentations/07_NetworkScalability.pptx and b/presentations/07_NetworkScalability.pptx differ diff --git a/presentations/09_HLA_HighLevelArchitecture.pptx b/presentations/09_HLA_HighLevelArchitecture.pptx index bc476c04917bfdeacf65a6923fadaf2d9ba9843c..3be2c8ede1c10c91c458e56babb516f7e0c80a21 100644 Binary files a/presentations/09_HLA_HighLevelArchitecture.pptx and b/presentations/09_HLA_HighLevelArchitecture.pptx differ diff --git a/presentations/10_TENA_References.md b/presentations/10_TENA_References.md index 31ae4f4b7fb1fda19b7146ab4314a692fb590bd1..c631616a04553a4d9dfc8b65fef88815573bc5d9 100644 --- a/presentations/10_TENA_References.md +++ b/presentations/10_TENA_References.md @@ -1,5 +1,7 @@  +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/presentations/10_TENA_References.md --> + # Test and Training Enabling Architecture (TENA) TENA is Government Off The Shelf (GOTS) software supporting a wide range of Live Virtual Constructive (LVC) capability.