Merge branch 'main' into 407-create-a-simple-plugin-to-manage-units-database

This commit is contained in:
Pax1601
2023-09-24 10:22:45 +02:00
23 changed files with 2058 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
import { getApp } from "..";
import { GAME_MASTER } from "../constants/constants";
import { AirbaseChartRunwayData, AirbaseChartRunwayHeadingData } from "../interfaces";
import { Airbase } from "../mission/airbase";
import { dataPointMap } from "../other/utils";
import { Unit } from "../unit/unit";

View File

@@ -10,6 +10,7 @@ import { aircraftDatabase } from "../unit/databases/aircraftdatabase";
import { helicopterDatabase } from "../unit/databases/helicopterdatabase";
import { groundUnitDatabase } from "../unit/databases/groundunitdatabase";
import { navyUnitDatabase } from "../unit/databases/navyunitdatabase";
import { UnitSpawnOptions, UnitSpawnTable } from "../interfaces";
export class UnitSpawnMenu {
#container: HTMLElement;

36
client/src/dom.d.ts vendored Normal file
View File

@@ -0,0 +1,36 @@
interface CustomEventMap {
"unitSelection": CustomEvent<Unit>,
"unitDeselection": CustomEvent<Unit>,
"unitsSelection": CustomEvent<Unit[]>,
"unitsDeselection": CustomEvent<Unit[]>,
"clearSelection": CustomEvent<>,
"unitCreation": CustomEvent<Unit>,
"unitDeletion": CustomEvent<Unit>,
"unitDeath": CustomEvent<Unit>,
"unitUpdated": CustomEvent<Unit>,
"unitMoveCommand": CustomEvent<Unit>,
"unitAttackCommand": CustomEvent<Unit>,
"unitLandCommand": CustomEvent<Unit>,
"unitSetAltitudeCommand": CustomEvent<Unit>,
"unitSetSpeedCommand": CustomEvent<Unit>,
"unitSetOption": CustomEvent<Unit>,
"groupCreation": CustomEvent<Unit[]>,
"groupDeletion": CustomEvent<Unit[]>,
"mapStateChanged": CustomEvent<string>,
"mapContextMenu": CustomEvent<>,
"mapVisibilityOptionsChanged": CustomEvent<>,
"commandModeOptionsChanged": CustomEvent<>,
"contactsUpdated": CustomEvent<Unit>,
}
declare global {
interface Document {
addEventListener<K extends keyof CustomEventMap>(type: K,
listener: (this: Document, ev: CustomEventMap[K]) => void): void;
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K]): void;
}
function getOlympusPlugin(): OlympusPlugin;
}
export { };

271
client/src/interfaces.ts Normal file
View File

@@ -0,0 +1,271 @@
import { LatLng } from "leaflet";
import { OlympusApp } from "./app";
import { Airbase } from "./mission/airbase";
export interface OlympusPlugin {
getName: () => string;
initialize: (app: OlympusApp) => boolean;
}
declare global {
function getOlympusPlugin(): OlympusPlugin;
}
export interface ConfigurationOptions {
port: number;
address: string;
}
export interface ContextMenuOption {
tooltip: string;
src: string;
callback: CallableFunction;
}
export interface AirbasesData {
airbases: { [key: string]: any },
sessionHash: string;
time: number;
}
export interface BullseyesData {
bullseyes: { [key: string]: { latitude: number, longitude: number, coalition: string } },
sessionHash: string;
time: number;
}
export interface MissionData {
mission: {
theatre: string,
dateAndTime: DateAndTime;
commandModeOptions: CommandModeOptions;
coalitions: { red: string[], blue: string[] };
}
time: number;
sessionHash: string;
}
export interface CommandModeOptions {
commandMode: string;
restrictSpawns: boolean;
restrictToCoalition: boolean;
setupTime: number;
spawnPoints: {
red: number,
blue: number
},
eras: string[]
}
export interface DateAndTime {
date: { Year: number, Month: number, Day: number };
time: { h: number, m: number, s: number };
elapsedTime: number;
startTime: number;
}
export interface LogData {
logs: { [key: string]: string },
sessionHash: string;
time: number;
}
export interface ServerRequestOptions {
time?: number;
commandHash?: string;
}
export interface UnitSpawnTable {
unitType: string,
location: LatLng,
altitude?: number,
loadout?: string,
liveryID: string
}
export interface ObjectIconOptions {
showState: boolean,
showVvi: boolean,
showHotgroup: boolean,
showUnitIcon: boolean,
showShortLabel: boolean,
showFuel: boolean,
showAmmo: boolean,
showSummary: boolean,
showCallsign: boolean,
rotateToHeading: boolean
}
export interface GeneralSettings {
prohibitJettison: boolean;
prohibitAA: boolean;
prohibitAG: boolean;
prohibitAfterburner: boolean;
prohibitAirWpn: boolean;
}
export interface TACAN {
isOn: boolean;
channel: number;
XY: string;
callsign: string;
}
export interface Radio {
frequency: number;
callsign: number;
callsignNumber: number;
}
export interface Ammo {
quantity: number,
name: string,
guidance: number,
category: number,
missileCategory: number
}
export interface Contact {
ID: number,
detectionMethod: number
}
export interface Offset {
x: number,
y: number,
z: number
}
export interface UnitData {
category: string,
ID: number;
alive: boolean;
human: boolean;
controlled: boolean;
coalition: string;
country: number;
name: string;
unitName: string;
groupName: string;
state: string;
task: string;
hasTask: boolean;
position: LatLng;
speed: number;
heading: number;
isTanker: boolean;
isAWACS: boolean;
onOff: boolean;
followRoads: boolean;
fuel: number;
desiredSpeed: number;
desiredSpeedType: string;
desiredAltitude: number;
desiredAltitudeType: string;
leaderID: number;
formationOffset: Offset;
targetID: number;
targetPosition: LatLng;
ROE: string;
reactionToThreat: string;
emissionsCountermeasures: string;
TACAN: TACAN;
radio: Radio;
generalSettings: GeneralSettings;
ammo: Ammo[];
contacts: Contact[];
activePath: LatLng[];
isLeader: boolean;
}
export interface LoadoutItemBlueprint {
name: string;
quantity: number;
effectiveAgainst?: string;
}
export interface LoadoutBlueprint {
fuel: number;
items: LoadoutItemBlueprint[];
roles: string[];
code: string;
name: string;
}
export interface UnitBlueprint {
name: string;
coalition: string;
era: string;
label: string;
shortLabel: string;
type?: string;
range?: string;
loadouts?: LoadoutBlueprint[];
filename?: string;
liveries?: { [key: string]: { name: string, countries: string[] } };
cost?: number;
}
export interface UnitSpawnOptions {
roleType: string;
name: string;
latlng: LatLng;
coalition: string;
count: number;
country: string;
loadout: LoadoutBlueprint | undefined;
airbase: Airbase | undefined;
liveryID: string | undefined;
altitude: number | undefined;
}
export interface AirbaseOptions {
name: string,
position: L.LatLng
}
export interface AirbaseChartData {
elevation: string,
ICAO: string,
TACAN: string,
runways: AirbaseChartRunwayData[]
}
export interface AirbaseChartRunwayHeadingData {
[index: string]: {
magHeading: string,
ILS: string
}
}
export interface AirbaseChartRunwayData {
headings: AirbaseChartRunwayHeadingData[],
length: string
}
export interface Listener {
callback: CallableFunction;
name?: string
}
export interface ShortcutOptions {
altKey?: boolean;
callback: CallableFunction;
ctrlKey?: boolean;
name?: string;
shiftKey?: boolean;
}
export interface KeyboardShortcutOptions extends ShortcutOptions {
code: string;
event?: "keydown" | "keyup";
}
export interface MouseShortcutOptions extends ShortcutOptions {
button: number;
event: "mousedown" | "mouseup";
}
export interface Manager {
add: CallableFunction;
}

View File

@@ -1,6 +1,7 @@
import { DivIcon } from 'leaflet';
import { CustomMarker } from '../map/markers/custommarker';
import { SVGInjector } from '@tanem/svg-injector';
import { AirbaseChartData, AirbaseOptions } from '../interfaces';
export class Airbase extends CustomMarker {

View File

@@ -10,6 +10,7 @@ import { aircraftDatabase } from "../unit/databases/aircraftdatabase";
import { helicopterDatabase } from "../unit/databases/helicopterdatabase";
import { navyUnitDatabase } from "../unit/databases/navyunitdatabase";
import { Popup } from "../popups/popup";
import { AirbasesData, BullseyesData, CommandModeOptions, DateAndTime, MissionData } from "../interfaces";
/** The MissionManager */
export class MissionManager {

View File

@@ -24,6 +24,7 @@ import { aircraftDatabase } from "./unit/databases/aircraftdatabase";
import { helicopterDatabase } from "./unit/databases/helicopterdatabase";
import { groundUnitDatabase } from "./unit/databases/groundunitdatabase";
import { navyUnitDatabase } from "./unit/databases/navyunitdatabase";
import { ConfigurationOptions } from "./interfaces";
export class OlympusApp {
/* Global data */

View File

@@ -8,6 +8,7 @@ import { Buffer } from "buffer";
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
import { Dropdown } from "../controls/dropdown";
import { navyUnitDatabase } from "../unit/databases/navyunitdatabase";
import { DateAndTime, UnitBlueprint } from "../interfaces";
export function bearing(lat1: number, lon1: number, lat2: number, lon2: number) {
const φ1 = deg2rad(lat1); // φ, λ in radians

View File

@@ -1,3 +1,4 @@
import { Listener } from "../interfaces";
import { EventsManager } from "../other/eventsmanager";
export class PanelEventsManager extends EventsManager {

View File

@@ -8,6 +8,7 @@ import { Panel } from "./panel";
import { Switch } from "../controls/switch";
import { ROEDescriptions, ROEs, altitudeIncrements, emissionsCountermeasures, emissionsCountermeasuresDescriptions, maxAltitudeValues, maxSpeedValues, minAltitudeValues, minSpeedValues, reactionsToThreat, reactionsToThreatDescriptions, speedIncrements } from "../constants/constants";
import { ftToM, knotsToMs, mToFt, msToKnots } from "../other/utils";
import { GeneralSettings, Radio, TACAN } from "../interfaces";
export class UnitControlPanel extends Panel {
#altitudeSlider: Slider;

View File

@@ -1,3 +1,4 @@
import { Ammo } from "../interfaces";
import { aircraftDatabase } from "../unit/databases/aircraftdatabase";
import { Unit } from "../unit/unit";
import { Panel } from "./panel";

View File

@@ -1,6 +1,7 @@
import path from "path";
import { Manager } from "../other/manager";
import { getApp } from "..";
import { OlympusPlugin } from "../interfaces";
/** The plugins manager is responsible for loading and initializing all the plugins. Plugins are located in the public/plugins folder.
* Each plugin must be comprised of a single folder containing a index.js file. Each plugin must set the globalThis.getOlympusPlugin variable to

View File

@@ -1,4 +1,5 @@
import { LatLng } from "leaflet";
import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN } from "../interfaces";
export class DataExtractor {
#seekPosition = 0;

View File

@@ -5,6 +5,7 @@ import { ServerStatusPanel } from '../panels/serverstatuspanel';
import { LogPanel } from '../panels/logpanel';
import { Popup } from '../popups/popup';
import { ConnectionStatusPanel } from '../panels/connectionstatuspanel';
import { AirbasesData, BullseyesData, GeneralSettings, MissionData, Radio, ServerRequestOptions, TACAN } from '../interfaces';
export class ServerManager {
#connected: boolean = false;

View File

@@ -1,3 +1,4 @@
import { KeyboardShortcutOptions, MouseShortcutOptions, ShortcutOptions } from "../interfaces";
import { keyEventWasInInput } from "../other/utils";
export abstract class Shortcut {

View File

@@ -1,6 +1,7 @@
import { LatLng } from "leaflet";
import { getApp } from "../..";
import { GAME_MASTER } from "../../constants/constants";
import { UnitBlueprint } from "../../interfaces";
export class UnitDatabase {
blueprints: { [key: string]: UnitBlueprint } = {};

View File

@@ -10,6 +10,7 @@ import { DataExtractor } from '../server/dataextractor';
import { groundUnitDatabase } from './databases/groundunitdatabase';
import { navyUnitDatabase } from './databases/navyunitdatabase';
import { Weapon } from '../weapon/weapon';
import { Ammo, Contact, GeneralSettings, LoadoutBlueprint, ObjectIconOptions, Offset, Radio, TACAN, UnitData } from '../interfaces';
var pathIcon = new Icon({
iconUrl: '/resources/theme/images/markers/marker-icon.png',

View File

@@ -13,6 +13,7 @@ import { navyUnitDatabase } from "./databases/navyunitdatabase";
import { TemporaryUnitMarker } from "../map/markers/temporaryunitmarker";
import { Popup } from "../popups/popup";
import { HotgroupPanel } from "../panels/hotgrouppanel";
import { Contact, UnitData, UnitSpawnTable } from "../interfaces";
/** The UnitsManager handles the creation, update, and control of units. Data is strictly updated by the server ONLY. This means that any interaction from the user will always and only
* result in a command to the server, executed by means of a REST PUT request. Any subsequent change in data will be reflected only when the new data is sent back by the server. This strategy allows

View File

@@ -5,6 +5,7 @@ import { CustomMarker } from '../map/markers/custommarker';
import { SVGInjector } from '@tanem/svg-injector';
import { DLINK, DataIndexes, GAME_MASTER, IRST, OPTIC, RADAR, VISUAL } from '../constants/constants';
import { DataExtractor } from '../server/dataextractor';
import { ObjectIconOptions } from '../interfaces';
export class Weapon extends CustomMarker {
ID: number;

View File

@@ -1,7 +1,8 @@
import { getApp } from "..";
import { Weapon } from "./weapon";
import { DataIndexes, GAME_MASTER } from "../constants/constants";
import { DataIndexes } from "../constants/constants";
import { DataExtractor } from "../server/dataextractor";
import { Contact } from "../interfaces";
/** The WeaponsManager handles the creation and update of weapons. Data is strictly updated by the server ONLY. */
export class WeaponsManager {