Adds q2 repos to migrate
This commit is contained in:
1 parent
ad1f62c4ee
commit
17f1c61c9e
991 files changed
+178451
No files matched your search
@@ -0,0 +1,29 @@
|
||||
SET(tts_SRCS
|
||||
main.cpp
|
||||
server.cpp
|
||||
worker.cpp
|
||||
|
||||
log4cxx_tetratestserver.props
|
||||
)
|
||||
|
||||
SET(tts_HDRS
|
||||
server.h
|
||||
worker.h
|
||||
)
|
||||
|
||||
NGL_ADD_EXECUTABLE(AAR SV tts ${tts_SRCS} ${tts_HDRS})
|
||||
NGL_TARGET_LINK_LIBRARIES(tts
|
||||
CoPrtCnv
|
||||
NGLLogger
|
||||
LtsCommandLineParser
|
||||
nglsettings
|
||||
nglcoreapplication
|
||||
Qt5::Network
|
||||
)
|
||||
NGL_INSTALL_TARGET(tts)
|
||||
|
||||
SET(LOG4CXX_PROPS_FILE log4cxx_tetratestserver.props)
|
||||
NGL_INSTALL(FILES SV ${CMAKE_CURRENT_SOURCE_DIR}/${LOG4CXX_PROPS_FILE} DESTINATION "bin")
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, stdout
|
||||
#log4j.rootLogger=WARN, file, stdout
|
||||
|
||||
log4j.logger.TTWorker=INFO
|
||||
log4j.logger.TTServer=INFO
|
||||
|
||||
|
||||
|
||||
# Appnd_File
|
||||
###########################################################
|
||||
log4j.appender.file=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_TetraTestServer.log
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %-5p %c{1} |#| %m (%-.30F:%L) %n
|
||||
|
||||
#log4j.appender.stdout.layout.ConversionPattern= %d %-5p %-30c |#| %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=FATAL
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
|
||||
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QPointF>
|
||||
#include <QtCore/QStringList>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
#include "server.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication::setApplicationName(QLatin1String("TTS"));
|
||||
QCoreApplication::setOrganizationName(QLatin1String("RME"));
|
||||
NGLCoreApplication app(argc, argv);
|
||||
|
||||
app.createLogger("tts", "log4cxx_tetratestserver.props");
|
||||
NGL::INGLLogger &logger = app.baseLogger();
|
||||
QScopedPointer<QSettings> settings(new QSettings(app.organizationName(), app.applicationName()));
|
||||
|
||||
ERROR_LOG(logger) << "Settings Directory: " << settings->fileName();
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options(LtsCommandLineParser::LtsCommandLineParser::CustomConfigFile);
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("p") << QLatin1String("player")
|
||||
, QLatin1String("number of players to be simulated.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("5")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("n") << QLatin1String("northing")
|
||||
, QLatin1String("initial position UTM north.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("77777")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("e") << QLatin1String("easting")
|
||||
, QLatin1String("initial position UTM east.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("99999")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("f") << QLatin1String("first-id")
|
||||
, QLatin1String("first equipment ID to use.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("1101")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("r") << QLatin1String("pprow")
|
||||
, QLatin1String("players per row.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("25")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("s") << QLatin1String("pspacing")
|
||||
, QLatin1String("utm based spacing between the players.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("100")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("z") << QLatin1String("issi")
|
||||
, QLatin1String("DestinationIssi / HostISSI")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("2")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("m") << QLatin1String("movements")
|
||||
, QLatin1String("how many movements per milliseconds to make.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("2000")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("d") << QLatin1String("death")
|
||||
, QLatin1String("minimum times, after the movements timer is triggered, a dead player can revive.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("100")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("o") << QLatin1String("death-offset")
|
||||
, QLatin1String("maximum times, after the movements timer is triggered, a dead player can revive.")
|
||||
, QLatin1String("(0 -> identical to min)")
|
||||
, QLatin1String("0")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("t") << QLatin1String("pattern")
|
||||
, QLatin1String("pattern the player has to walk [enter pattern by hand or pattern alias-name from settings file]\r\nfor more info, enter '--pattern-help'.")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("3,30,20#3,30,-20#3,-30,-20#3,-30,20")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("demand-old-broadcast-telegrams")
|
||||
, QLatin1String("player demand old broadcast telegrams starting at BCI <default value>")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("0")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("deactivate-single-mines")
|
||||
, QLatin1String("the first player deactivates single mines with ids from minimum-mine-id to maximum-mine-id")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("minimum-mine-id")
|
||||
, QLatin1String("sets the value for minimum-mine-id used within deactivate-single-mines command")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("minimum-mine-id 2048")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("maximum-mine-id")
|
||||
, QLatin1String("sets the value for maximum-mine-Id used within deactivate-single-mines command")
|
||||
, QLatin1String("Default value")
|
||||
, QLatin1String("maximum-mine-id 2100")
|
||||
});
|
||||
|
||||
options.addOption({ QStringList() << QLatin1String("pattern-help")
|
||||
, QLatin1String("help for the pattern interpreter.")
|
||||
});
|
||||
|
||||
|
||||
if (!options.init())
|
||||
{
|
||||
options.showHelp();
|
||||
return -1;
|
||||
}
|
||||
QSettings serverSettings(app.applicationDirPath() + QLatin1String("/") + options.iniFile(), QSettings::IniFormat);
|
||||
|
||||
TTSArgs ttsArgs;
|
||||
|
||||
ttsArgs.destIssi = options.isSet(QLatin1String("issi")) ? options.value(QLatin1String("issi")).toInt() : 2;
|
||||
ttsArgs.cntPlayer = options.isSet(QLatin1String("player")) ? options.value(QLatin1String("player")).toInt() : 0;
|
||||
int northPos_arg = options.isSet(QLatin1String("northing")) ? options.value(QLatin1String("northing")).toInt() : 77777;
|
||||
int eastPos_arg = options.isSet(QLatin1String("easting")) ? options.value(QLatin1String("easting")).toInt() : 90000;
|
||||
ttsArgs.position = QPointF(eastPos_arg, northPos_arg);
|
||||
ttsArgs.eqIdStart = options.isSet(QLatin1String("first-id")) ? options.value(QLatin1String("first-id")).toInt() : 1101;
|
||||
ttsArgs.pprow = options.isSet(QLatin1String("pprow")) ? options.value(QLatin1String("pprow")).toInt() : 25;
|
||||
ttsArgs.pspacing = options.isSet(QLatin1String("pspacing")) ? options.value(QLatin1String("pspacing")).toInt() : 100;
|
||||
ttsArgs.movs_per_msec = options.isSet(QLatin1String("movements")) ? options.value(QLatin1String("movements")).toInt() : 2000;
|
||||
ttsArgs.minimumDeathTicks = options.isSet(QLatin1String("death")) ? options.value(QLatin1String("death")).toInt() : 10;
|
||||
ttsArgs.maximumDeathTicks = options.isSet(QLatin1String("death-offset")) ? options.value(QLatin1String("death-offset")).toInt() : 20;
|
||||
ttsArgs.demandOldBraodcastTelegrams = options.isSet(QLatin1String("demand-old-broadcast-telegrams")) ? true : false;
|
||||
if (ttsArgs.demandOldBraodcastTelegrams)
|
||||
ttsArgs.demandOldBraodcastTelegramsCounter = options.value(QLatin1String("demand-old-broadcast-telegrams")).toInt();
|
||||
ttsArgs.deactivationSingleMines = options.isSet(QLatin1String("deactivate-single-mines")) ? true : false;
|
||||
ttsArgs.minimumMineId = options.isSet(QLatin1String("minimum-mine-id")) ? options.value(QLatin1String("minimum-mine-id")).toInt() : 2048;
|
||||
ttsArgs.maximumMineId = options.isSet(QLatin1String("maximum-mine-id")) ? options.value(QLatin1String("maximum-mine-id")).toInt() : 2100;
|
||||
ttsArgs.pattern = options.isSet(QLatin1String("pattern")) ? options.value(QLatin1String("pattern")) : QLatin1String("3,30,20#3,30,-20#3,-30,-20#3,-30,20");
|
||||
|
||||
if (options.isSet(QLatin1String("pattern-help")))
|
||||
{
|
||||
options.showHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ttsArgs.maximumDeathTicks == 0)
|
||||
ttsArgs.maximumDeathTicks = ttsArgs.minimumDeathTicks;
|
||||
|
||||
WARNING_LOG(logger) << "Simulating " << ttsArgs.cntPlayer << " players";
|
||||
WARNING_LOG(logger) << " ... DestinationIssi/HostIssi: " << ttsArgs.destIssi;
|
||||
WARNING_LOG(logger) << " ... on Position n/e: " << ttsArgs.position.y() << "/" << ttsArgs.position.x();
|
||||
WARNING_LOG(logger) << " ... first equipmentID is: " << ttsArgs.eqIdStart;
|
||||
WARNING_LOG(logger) << " ... player is reborn randomly after minimum " << ttsArgs.minimumDeathTicks
|
||||
<< " ticks and maximum " << ttsArgs.maximumDeathTicks << " ticks";
|
||||
WARNING_LOG(logger) << " ... pattern = " << ttsArgs.pattern;
|
||||
WARNING_LOG(logger) << " ... max. " << ttsArgs.pprow << " players per row";
|
||||
WARNING_LOG(logger) << " ... spacing of '" << ttsArgs.pspacing << " UTM east' between players";
|
||||
WARNING_LOG(logger) << " ... one player will be moved after " << ttsArgs.movs_per_msec << " msecs";
|
||||
|
||||
TTServer *s = new TTServer(ttsArgs);
|
||||
|
||||
if (!s->listen(QHostAddress::Any, serverSettings.value(QLatin1String("Radio/Port"), 4200).toInt()))
|
||||
{
|
||||
ERROR_LOG(logger) << "Error listening on localhost:" << serverSettings.value(QLatin1String("Radio/Port"), 52010).toInt() << ": "
|
||||
<< s->errorString();
|
||||
delete s;
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_LOG(logger) << "Starting Server";
|
||||
|
||||
int ret = app.exec();
|
||||
|
||||
delete s;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
#include "server.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
|
||||
#include "worker.h"
|
||||
|
||||
TTServer::TTServer(const TTSArgs &ttsArgs)
|
||||
: m_ttsArgs(ttsArgs)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TTServer"))
|
||||
{
|
||||
connect(this, &TTServer::newConnection,
|
||||
this, &TTServer::onNewConnection);
|
||||
}
|
||||
|
||||
void TTServer::onNewConnection()
|
||||
{
|
||||
QTcpSocket *sock = nextPendingConnection();
|
||||
if (!sock)
|
||||
return;
|
||||
NOTICE_LOG(m_logger) << "New incoming connection from "
|
||||
<< sock->peerName() << ":"
|
||||
<< sock->peerPort();
|
||||
|
||||
TTWorker *ttw = new TTWorker(sock, m_ttsArgs);
|
||||
if (!ttw->init())
|
||||
exit(5);
|
||||
|
||||
connect(sock, &QTcpSocket::disconnected,
|
||||
this, &TTServer::onDisconnect);
|
||||
}
|
||||
|
||||
void TTServer::onDisconnect()
|
||||
{
|
||||
NOTICE_LOG(m_logger) << "Disconnected";
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QPointF>
|
||||
#include <QtNetwork/QTcpServer>
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
|
||||
struct runningPattern
|
||||
{
|
||||
int steps = 0;
|
||||
int ethering = 0;
|
||||
int northering = 0;
|
||||
};
|
||||
|
||||
struct TTSArgs
|
||||
{
|
||||
QPointF position;
|
||||
QString pattern;
|
||||
QSettings *settings = nullptr;
|
||||
int destIssi = 0;
|
||||
unsigned int cntPlayer = 0;
|
||||
unsigned int eqIdStart = 0;
|
||||
unsigned int minimumDeathTicks = 0;
|
||||
unsigned int maximumDeathTicks = 0;
|
||||
unsigned int pprow = 0;
|
||||
unsigned int pspacing = 0;
|
||||
unsigned int movs_per_msec = ~0U;
|
||||
unsigned int minimumMineId = 0;
|
||||
unsigned int maximumMineId = 0;
|
||||
bool demandOldBraodcastTelegrams = false;
|
||||
int demandOldBraodcastTelegramsCounter = 0;
|
||||
bool deactivationSingleMines = false;
|
||||
};
|
||||
|
||||
class TTServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TTServer(const TTSArgs &m_ttsArgs);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onNewConnection();
|
||||
void onDisconnect();
|
||||
|
||||
protected:
|
||||
TTSArgs m_ttsArgs;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
TTS Tetra Test Server:
|
||||
Das Testprogramm tts wird als Ersatz des Tetra-Server gestartet. Es dient dazu, Lasttests im Gesamtsystem zu starten.
|
||||
-----------------------------------------------
|
||||
Teilnehmer anlegen:
|
||||
|
||||
In der Opperator-App in die Übung einloggen
|
||||
Vorplanung->Teilnehmer Truppe->Bearbeite Teilnehmer
|
||||
Einen Zug selektieren und Erstellen
|
||||
Eine Anfangs-Ausstattungsnummer wählen und mit Enter jede Menge Teilnehmer mit aufsteigender Ausstattungsnummererzeugen.
|
||||
-----------------------------------------------
|
||||
Verschlüsselung abschalten:
|
||||
auf dem Server EXCTDS01 die Datei /etc/lts-cc.conf öffnen
|
||||
|
||||
[TrainingAreaBase]
|
||||
UseTetraScrambling=false
|
||||
|
||||
-----------------------------------------------
|
||||
Tabelle pdm.pdm_radio_group aendern:
|
||||
Dazu vorher den Namen der Gruppe herausfinden:
|
||||
Als Administrator in der Operator App Vorplanung->Übungen->Übungen den Namen der Tetra Gruppe von der aktuellen Übung nehmen.
|
||||
|
||||
Die Einstellungen, die geändert werden vorher aufschreiben, um wieder zum Betrieb mit dem Gefechtsfeld zurückzukommen.
|
||||
In der Tabelle pdm.pdm_radio_group den Namen "radiohost" auf localhost und issi auf 2 einstellen
|
||||
In der Tabelle pdm.pdm_radio_group den radio_port auf 4200 einstellen
|
||||
-----------------------------------------------
|
||||
Servernamen in PrtCnv.dat ändern
|
||||
Auf dem Server (EXCTDS01) ala user ctc_sv im Verzeichnis bin die Datei PrtCnv.dat öffnen
|
||||
[Central]
|
||||
HostName=localhost
|
||||
-----------------------------------------------
|
||||
Serversoftware neu starten
|
||||
-----------------------------------------------
|
||||
tts starten:
|
||||
Auf dem Server (EXCTDS01) ala user ctc_sv im Verzeichnis bin
|
||||
./tts -p 800 -f 1200
|
||||
|
||||
Bedeutung:
|
||||
-p 800 Positionsmeldungen für 800 Teilnehmer erzeugen
|
||||
-f 1200 Anfangsausstattungsnummer vom Teilnehmer anlegen hier eingeben.
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-----------------------------------------------
|
||||
Relevante Tabellen sind:
|
||||
1) tab_prtcnv_member
|
||||
2) ex_nn.prtcnv_to_radio
|
||||
Hier werden die Telegramme (Rtg Gefechtsfeld) zwischengespeichert, bis sie quittiert sind.
|
||||
|
||||
Bei Problemen hat es sich als sinnvoll erwiesen, diese Tabellen zu löschen
|
||||
-----------------------------------------------
|
||||
-----------------------------------------------
|
||||
|
||||
-----------------------------------------------
|
||||
Optionen mit tts --help anzeigen lassen:
|
||||
|
||||
./tts --help
|
||||
Could not find log4cxx configuration file tetra_log4cxx.props
|
||||
Using default logging to stdout
|
||||
2020-09-03 13:19:15.300 ERROR tts |#| Settings Directory: /shd/CTC/TOOLS/.config/RME/TTS.conf (TDS-source/TetraIF/PrtCnv/TetraTestServer/main.cpp:30)
|
||||
Usage: ./tts [options]
|
||||
|
||||
Options:
|
||||
-i, --ini <filename> Default: /etc/lts-cc.conf
|
||||
-h, --help Displays this help.
|
||||
-v, --version Displays version
|
||||
information.
|
||||
-p, --player <Default value> number of players to be
|
||||
simulated.
|
||||
-n, --northing <Default value> initial position UTM north.
|
||||
-e, --easting <Default value> initial position UTM east.
|
||||
-f, --first-id <Default value> first equipment ID to use.
|
||||
-r, --pprow <Default value> players per row.
|
||||
-s, --pspacing <Default value> utm based spacing between
|
||||
the players.
|
||||
-m, --movements <Default value> how many movements per
|
||||
milliseconds to make.
|
||||
-d, --death <Default value> minimum times, after the
|
||||
movements timer is
|
||||
triggered, a dead player can
|
||||
revive.
|
||||
-o, --death-offset <(0 -> identical to min)> maximum times, after the
|
||||
movements timer is
|
||||
triggered, a dead player can
|
||||
revive.
|
||||
-t, --pattern <Default value> pattern the player has to
|
||||
walk [enter pattern by hand
|
||||
or pattern alias-name from
|
||||
settings file]
|
||||
for more info, enter
|
||||
'--pattern-help'.
|
||||
--demand-old-broadcast-telegrams <Default value> player demand old broadcast
|
||||
telegrams starting at BCI
|
||||
<default value>
|
||||
--deactivate-single-mines the first player
|
||||
deactivates single mines
|
||||
with ids from
|
||||
minimum-mine-id to
|
||||
maximum-mine-id
|
||||
--minimum-mine-id <Default value> sets the value for
|
||||
minimum-mine-id used within
|
||||
deactivate-single-mines
|
||||
command
|
||||
--maximum-mine-id <Default value> sets the value for
|
||||
maximum-mine-Id used within
|
||||
deactivate-single-mines
|
||||
command
|
||||
--pattern-help help for the pattern
|
||||
interpreter.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,645 @@
|
||||
|
||||
|
||||
|
||||
#include "worker.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <time.h>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
|
||||
TTWorker::TTWorker(QTcpSocket *socket, const TTSArgs &ttsArgs)
|
||||
: m_socket(socket)
|
||||
, m_timer(new QTimer(this))
|
||||
, m_counter(0)
|
||||
, m_toogle(true)
|
||||
, m_ttsArgs(ttsArgs)
|
||||
, m_patternList(interpretPattern(ttsArgs.pattern))
|
||||
, m_generalPosition(ttsArgs.position)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TTWorker"))
|
||||
{
|
||||
qsrand(time(nullptr));
|
||||
}
|
||||
|
||||
bool TTWorker::init()
|
||||
{
|
||||
connect(m_socket, &QTcpSocket::disconnected,
|
||||
this, &TTWorker::deleteLater);
|
||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
|
||||
this, &TTWorker::onSocketError);
|
||||
connect(m_socket, &QTcpSocket::readyRead,
|
||||
this, &TTWorker::onReadyRead);
|
||||
connect(m_timer, &QTimer::timeout,
|
||||
this, &TTWorker::onSendPlayerPositions);
|
||||
|
||||
if (m_ttsArgs.movs_per_msec < 200)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Invalid value for 'movements per milliseconds'! Please choose a number greater than 200 msecs or equal. Program stopped.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TTWorker::startExecution()
|
||||
{
|
||||
|
||||
m_timer->start(m_ttsArgs.movs_per_msec);
|
||||
NOTICE_LOG(m_logger) << "Start Exe login all Player";
|
||||
|
||||
for (unsigned int i = 0; i < m_ttsArgs.cntPlayer; i++)
|
||||
{
|
||||
int eqId = m_ttsArgs.eqIdStart + i;
|
||||
int issi = m_ttsArgs.eqIdStart + i + 2000;
|
||||
QPointF posUTM((m_generalPosition.x() + (i / m_ttsArgs.pprow) * m_ttsArgs.pspacing),
|
||||
(m_generalPosition.y() + (i % m_ttsArgs.pprow) * m_ttsArgs.pspacing));
|
||||
Player *p = new Player(eqId, issi, m_ttsArgs.minimumDeathTicks, m_ttsArgs.maximumDeathTicks, posUTM);
|
||||
m_playerList.append(p);
|
||||
|
||||
sendLogin(p->eqId, p->issi);
|
||||
}
|
||||
|
||||
if (m_ttsArgs.deactivationSingleMines)
|
||||
QTimer::singleShot(1000, this, &TTWorker::onSendDeaktivierungEinzelminen);
|
||||
|
||||
if (m_ttsArgs.demandOldBraodcastTelegrams)
|
||||
QTimer::singleShot(1000, this, &TTWorker::onSendNachforderungBroadcastTelegramm);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
QVector<runningPattern> TTWorker::interpretPattern(QString pattern) const
|
||||
{
|
||||
if (pattern.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "INVALID PATTERN - pattern-size < 1";
|
||||
exit(8);
|
||||
}
|
||||
|
||||
if (pattern.at(0) == QLatin1Char('%'))
|
||||
{
|
||||
pattern.remove(0, 1);
|
||||
|
||||
QString patternAlias = pattern;
|
||||
|
||||
pattern = m_ttsArgs.settings->value(QLatin1String("pattern/") + patternAlias).toString();
|
||||
|
||||
if (pattern.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "INVALID PATTERN - alias '" << patternAlias << "' is not available in settings file! Program halted.";
|
||||
exit(9);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (pattern.at(pattern.count() - 1) == QLatin1Char('#'))
|
||||
pattern.remove(pattern.count() - 1, 1);
|
||||
|
||||
QVector<runningPattern> newPatternList;
|
||||
runningPattern rp;
|
||||
QStringList strings = pattern.split(QLatin1Char('#'));
|
||||
QStringList stringy;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < strings.count(); i++)
|
||||
{
|
||||
stringy = strings.at(i).split(QLatin1Char(','));
|
||||
|
||||
if (stringy.count() != 3)
|
||||
break;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
rp.steps = stringy.at(0).toInt(&ok); if (!ok) break;
|
||||
rp.ethering = stringy.at(1).toInt(&ok); if (!ok) break;
|
||||
rp.northering = stringy.at(2).toInt(&ok); if (!ok) break;
|
||||
|
||||
newPatternList.append(rp);
|
||||
|
||||
if (i == strings.count() - 1)
|
||||
return newPatternList;
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "INVALID PATTERN: '" << strings.at(i) << "'. Cannot start without correct pattern!";
|
||||
|
||||
exit(5);
|
||||
|
||||
return QVector<runningPattern>();
|
||||
}
|
||||
|
||||
void TTWorker::sendLogin(uint32_t eqId, uint32_t issi)
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram *tele = new N_CoPrtCnv::CoPrtCnvRadioTelegram(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_LoginRequest, eqId, issi);
|
||||
|
||||
DEBUG_LOG(m_logger) << "SEND LOGIN FOR ISSI=" << issi << ", eqId=" << eqId;
|
||||
sendTelegram(tele, issi);
|
||||
}
|
||||
|
||||
void TTWorker::onReadyRead()
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram::PrtCnvRadioGwHeader header;
|
||||
qint64 bytesRead = m_socket->peek((char *)&header, sizeof(header));
|
||||
if (sizeof(header) != bytesRead)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "To few bytes to read from socket";
|
||||
return;
|
||||
}
|
||||
|
||||
if (N_CoPrtCnv::CoPrtCnvRadioTelegram::MAGIC_NUMBER != header.m_MagicNumber)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Disconnect because radio-Telegram does not begin with magic-number A5: I got "
|
||||
<< header.m_MagicNumber;
|
||||
m_socket->disconnectFromHost();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!N_CoPrtCnv::CoPrtCnvRadioTelegram::isTelegramLengthOk(header.m_Length))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Radio-Telegram length to big: " << header.m_Length
|
||||
<< " - but I proceed with this telegram.";
|
||||
}
|
||||
|
||||
|
||||
uint16_t dataSize = header.m_Length + sizeof(header);
|
||||
if (m_socket->bytesAvailable() < dataSize)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "not enough bytes available - waiting for more data";
|
||||
return;
|
||||
}
|
||||
QByteArray buf(dataSize, Qt::Uninitialized);
|
||||
|
||||
bytesRead = 0;
|
||||
while (bytesRead < dataSize)
|
||||
{
|
||||
qint64 br = m_socket->read(&buf.data()[bytesRead], dataSize - bytesRead);
|
||||
bytesRead += br;
|
||||
}
|
||||
handleReceivedTelegram(buf);
|
||||
|
||||
if (m_socket->bytesAvailable())
|
||||
QTimer::singleShot(0, this, &TTWorker::onReadyRead);
|
||||
}
|
||||
|
||||
void TTWorker::handleReceivedTelegram(const QByteArray &data)
|
||||
{
|
||||
INFO_LOG(m_logger) << data.size();
|
||||
|
||||
switch (data.at(4))
|
||||
{
|
||||
|
||||
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterInd:
|
||||
handleRegisterInd();
|
||||
startExecution();
|
||||
break;
|
||||
|
||||
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_DataIndReq:
|
||||
handleDataIndReq(data);
|
||||
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(m_logger) << "Radio-Telegram with PDU-Type=" << (int)data[4]
|
||||
<< " not implemented!";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TTWorker::sendTelegram(N_CoPrtCnv::CoPrtCnvRadioTelegram *radioTelegram, uint32_t issi)
|
||||
{
|
||||
radioTelegram->setZaehler(m_counter++);
|
||||
radioTelegram->setDestISSI(m_ttsArgs.destIssi);
|
||||
radioTelegram->setSrcISSI(issi);
|
||||
|
||||
m_socket->write(radioTelegram->data());
|
||||
m_socket->flush();
|
||||
delete radioTelegram;
|
||||
}
|
||||
|
||||
void TTWorker::onSendNachforderungBroadcastTelegramm()
|
||||
{
|
||||
Player *p = m_playerList.at(0);
|
||||
|
||||
if (p->isLogin)
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram tel(GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME,
|
||||
10, p->eqId);
|
||||
tel.setZaehler(0);
|
||||
tel.setBroadcastIndex(0);
|
||||
tel.setDestISSI(m_ttsArgs.destIssi);
|
||||
tel.setSrcISSI(p->issi);
|
||||
tel.setPayload4Byte(0);
|
||||
tel.setPayload1Byte(0);
|
||||
tel.setPayload2Byte(m_ttsArgs.demandOldBraodcastTelegramsCounter);
|
||||
m_socket->write(tel.data());
|
||||
}
|
||||
else
|
||||
QTimer::singleShot(1000, this, &TTWorker::onSendNachforderungBroadcastTelegramm);
|
||||
}
|
||||
|
||||
void TTWorker::onSendDeaktivierungEinzelminen()
|
||||
{
|
||||
if (m_playerList.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "No player for onSendDeaktivierungEinzelminen...";
|
||||
return;
|
||||
}
|
||||
Player *p = m_playerList.at(0);
|
||||
static unsigned int mineId = m_ttsArgs.minimumMineId;
|
||||
|
||||
NOTICE_LOG(m_logger) << "onSendDeaktivierungEinzelminen " << p->isLogin;
|
||||
if (p->isLogin)
|
||||
{
|
||||
TrainingAreaBase::TetraIcd::MineTriggered tele;
|
||||
tele.header.equipmentNumber = p->eqId;
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
tele.mineIndex = mineId++;
|
||||
tele.mineAreaId = 0;
|
||||
|
||||
sendTelegram(tele, p->issi);
|
||||
}
|
||||
|
||||
if (mineId <= m_ttsArgs.maximumMineId)
|
||||
QTimer::singleShot(1000, this, &TTWorker::onSendDeaktivierungEinzelminen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void TTWorker::sendTaktischerStatus(uint32_t eqId, uint32_t issi, TrainingAreaBase::TetraIcd::VulnerabilityState vbg)
|
||||
{
|
||||
TrainingAreaBase::TetraIcd::StateChange tele;
|
||||
tele.header.equipmentNumber = eqId;
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
|
||||
tele.tasVitality = 90;
|
||||
tele.tasVulnerabilityKindId = 459008;
|
||||
tele.vulnerabilityBits = 0;
|
||||
|
||||
for (Player *p : qAsConst(m_playerList))
|
||||
{
|
||||
if (p->eqId == eqId)
|
||||
{
|
||||
p->vbg = vbg;
|
||||
tele.vulnerabilityState = vbg;
|
||||
DEBUG_LOG(m_logger) << "Player (" << p->eqId << ") - VBG: " << int(vbg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sendTelegram(tele, issi);
|
||||
}
|
||||
|
||||
void TTWorker::sendSanitationReport(uint32_t eqId, uint32_t issi)
|
||||
{
|
||||
m_toogle = false;
|
||||
return;
|
||||
TrainingAreaBase::TetraIcd::SanitaryMaterialStockReport tele;
|
||||
tele.header.equipmentNumber = eqId;
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
int matCount = 14;
|
||||
tele.sanitaryMaterialCount = matCount;
|
||||
std::vector<int> mat;
|
||||
mat.reserve(matCount);
|
||||
for (int i = 1; i <= matCount; i++)
|
||||
mat.emplace_back(i);
|
||||
tele.sanitaryMaterialStock = mat;
|
||||
sendTelegram(tele, issi);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void TTWorker::sendBITE(uint32_t eqId, uint32_t issi)
|
||||
{
|
||||
TrainingAreaBase::TetraIcd::BiteReport tele;
|
||||
tele.header.equipmentNumber = eqId;
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
tele.loginType = TrainingAreaBase::TetraIcd::BiteReport::LoginType::Relogin;
|
||||
tele.configError = false;
|
||||
sendTelegram(tele, issi);
|
||||
sendTaktischerStatus(eqId, issi, TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady);
|
||||
}
|
||||
|
||||
void TTWorker::handleDataIndReq(const QByteArray &data)
|
||||
{
|
||||
QScopedPointer<N_CoPrtCnv::CoPrtCnvRadioTelegram> radioTelegram(new N_CoPrtCnv::CoPrtCnvRadioTelegram(data));
|
||||
int telID = radioTelegram->getTelID();
|
||||
|
||||
switch (telID)
|
||||
{
|
||||
#if 0
|
||||
TODO
|
||||
case GEF_AUSLOESUNG_DUS_TREFFER:
|
||||
{
|
||||
|
||||
|
||||
DEBUG_LOG(mLogger) << "handleAusloeserDUSTreffer: eqId=" << radioTelegram->getIdentity() <<
|
||||
" issi=" << radioTelegram->getDestISSI();
|
||||
|
||||
|
||||
XDR_Wrapper_it *wrapper = nullptr;
|
||||
if (!N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToCentral(wrapper, radioTelegram.data()))
|
||||
if (!wrapper)
|
||||
return;
|
||||
const ausloesung_dus_treffer_rt &rt_data = static_cast<XDR_AUSLOESUNG_DUS_TREFFER_Wrapper *>(wrapper)->get_rt();
|
||||
|
||||
if (rt_data.bek_wirkung > 90)
|
||||
sendTaktischerStatus(radioTelegram->getIdentity(), radioTelegram->getDestISSI(), TOTALAUSFALL);
|
||||
else
|
||||
sendTaktischerStatus(radioTelegram->getIdentity(), radioTelegram->getDestISSI(), ANNAEHENDER_TREFFER);
|
||||
delete wrapper;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
case GEF_TAKTISCHER_STATUS:
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvCentralTelegram *tele = N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToCentral(radioTelegram.data());
|
||||
TrainingAreaBase::TetraIcd::StateChange sc = TrainingAreaBase::TetraIcd::StateChange::fromJson(tele->jsonData());
|
||||
delete tele;
|
||||
DEBUG_LOG(m_logger) << " Try to Resetnd State " << sc.header.equipmentNumber << " we got state: " << static_cast<int>(sc.vulnerabilityState) << " and this bits here: " << sc.vulnerabilityBits;
|
||||
|
||||
sc.header.timeStamp = time(nullptr) * 1000;
|
||||
uint32_t issi = 0;
|
||||
for (int i = 0; i < m_playerList.count(); i++)
|
||||
{
|
||||
if (radioTelegram->getIdentity() == m_playerList.at(i)->eqId)
|
||||
{
|
||||
issi = m_playerList.at(i)->issi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << " Try to Resetnd S2tate " << sc.header.equipmentNumber << " we got state: " << static_cast<int>(sc.vulnerabilityState) << " and this bits here: " << sc.vulnerabilityBits;
|
||||
sendTelegram(sc, issi);
|
||||
return;
|
||||
}
|
||||
case GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN:
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvCentralTelegram *tele = N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToCentral(radioTelegram.data());
|
||||
TrainingAreaBase::TetraIcd::Sanitation sc = TrainingAreaBase::TetraIcd::Sanitation::fromJson(tele->jsonData());
|
||||
delete tele;
|
||||
|
||||
DEBUG_LOG(m_logger) << " Try to Resetnd State " << sc.header.equipmentNumber << " we got procedure: " << sc.proceduresTaken;
|
||||
|
||||
sc.header.timeStamp = time(nullptr) * 1000;
|
||||
uint32_t issi = 0;
|
||||
for (int i = 0; i < m_playerList.count(); i++)
|
||||
{
|
||||
if (radioTelegram->getIdentity() == m_playerList.at(i)->eqId)
|
||||
{
|
||||
issi = m_playerList.at(i)->issi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << " Try to Resetnd S2tate " << sc.header.equipmentNumber << " we got state: " << sc.proceduresTaken;
|
||||
sendTelegram(sc, issi);
|
||||
return;
|
||||
}
|
||||
case GEF_TREFFER_AUSLOESUNG:
|
||||
case GEF_INIT:
|
||||
{
|
||||
TrainingAreaBase::TetraIcd::StateChange tele;
|
||||
uint32_t issi = 0;
|
||||
for (int i = 0; i < m_playerList.count(); i++)
|
||||
{
|
||||
if (radioTelegram->getIdentity() == m_playerList.at(i)->eqId)
|
||||
{
|
||||
issi = m_playerList.at(i)->issi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TrainingAreaBase::TetraIcd::VulnerabilityState state = (telID == GEF_TREFFER_AUSLOESUNG)
|
||||
? static_cast<TrainingAreaBase::TetraIcd::VulnerabilityState>(radioTelegram->getPayloadDataUInt8(7))
|
||||
: TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady;
|
||||
|
||||
tele.originatorType = TrainingAreaBase::TetraIcd::OriginatorType::Initialisation;
|
||||
tele.header.equipmentNumber = radioTelegram->getIdentity();
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
uint32_t vulcomplete = radioTelegram->getPayloadDataUInt32(8, 2);
|
||||
uint32_t vitality = vulcomplete &= 0xF000;
|
||||
vitality >>= 12;
|
||||
|
||||
tele.tasVulnerabilityKindId = vulcomplete &= 0x0FFF;
|
||||
|
||||
tele.tasVulnerabilityKindId <<= 16;
|
||||
tele.tasVulnerabilityKindId |= 0xB1;
|
||||
|
||||
tele.tasVitality = (vitality - 1) * 10;
|
||||
if (tele.tasVitality < 0)
|
||||
tele.tasVitality = 100;
|
||||
|
||||
if (state == TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady && vitality > 0)
|
||||
tele.vulnerabilityState = TrainingAreaBase::TetraIcd::VulnerabilityState::MediumDamage;
|
||||
else
|
||||
tele.vulnerabilityState = state;
|
||||
|
||||
sendTelegram(tele, issi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (radioTelegram->isLoginTelegram())
|
||||
{
|
||||
|
||||
DEBUG_LOG(m_logger) << "player cont: " << m_playerList.count();
|
||||
for (int i = 0; i < m_playerList.count(); i++)
|
||||
{
|
||||
Player *p = m_playerList.at(i);
|
||||
if (radioTelegram->getDestISSI() == p->issi)
|
||||
{
|
||||
if (p->isLogin)
|
||||
return;
|
||||
DEBUG_LOG(m_logger) << "Player #" << i << " with eqId=" << p->eqId << " and issi=" << p->issi << " is now logged in.";
|
||||
p->isLogin = true;
|
||||
sendBITE(p->eqId, p->issi);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "Invalid player was logged in. issi: '" << radioTelegram->getDestISSI() << "'";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "Received unused or invalid telegram with Telegram-ID: " << telID;
|
||||
}
|
||||
|
||||
static void fillHeader(char *data, int len)
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram::PrtCnvRadioGwHeader *hdr
|
||||
= (N_CoPrtCnv::CoPrtCnvRadioTelegram::PrtCnvRadioGwHeader *)data;
|
||||
hdr->m_MagicNumber = N_CoPrtCnv::CoPrtCnvRadioTelegram::MAGIC_NUMBER;
|
||||
hdr->m_Counter = 0;
|
||||
hdr->m_Length = len;
|
||||
}
|
||||
|
||||
void TTWorker::handleRegisterInd()
|
||||
{
|
||||
m_counter = 1;
|
||||
|
||||
QByteArray buf;
|
||||
buf.resize(6);
|
||||
fillHeader(buf.data(), 2);
|
||||
buf[4] = N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterRsp;
|
||||
buf[5] = N_CoPrtCnv::CoPrtCnvRadioTelegram::e_IssiSuccessfulRegistered;
|
||||
|
||||
m_socket->write(buf);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TTWorker::movePlayer(Player *p)
|
||||
{
|
||||
|
||||
|
||||
if (p->patternInList > m_patternList.count() - 1)
|
||||
p->patternInList = 0;
|
||||
else
|
||||
{
|
||||
if (p->stepInPattern > m_patternList.at(p->patternInList).steps)
|
||||
{
|
||||
p->stepInPattern = 1;
|
||||
if (p->patternInList == m_patternList.count() - 1)
|
||||
p->patternInList = 0;
|
||||
else
|
||||
p->patternInList++;
|
||||
}
|
||||
}
|
||||
|
||||
p->posUTM.setX(p->posUTM.x() +
|
||||
m_patternList.at(p->patternInList).northering);
|
||||
p->posUTM.setY(p->posUTM.y() +
|
||||
m_patternList.at(p->patternInList).ethering);
|
||||
|
||||
p->stepInPattern++;
|
||||
}
|
||||
|
||||
void TTWorker::onSendPlayerPositions()
|
||||
{
|
||||
|
||||
qint64 bytesSent = 0;
|
||||
int playerCount = 0;
|
||||
TrainingAreaBase::TetraIcd::PositionReport tele;
|
||||
for (int i = 0; i < m_playerList.count(); i++)
|
||||
{
|
||||
Player *p = m_playerList.at(i);
|
||||
|
||||
if (!p->isLogin)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Player with eqId=" << p->eqId << " and issi=" << p->issi << " is not logged in.";
|
||||
break;
|
||||
}
|
||||
playerCount++;
|
||||
|
||||
|
||||
if (p->vbg != TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady && p->isEndOfTicks())
|
||||
sendTaktischerStatus(p->eqId, p->issi, TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady);
|
||||
|
||||
tele.header.equipmentNumber = p->eqId;
|
||||
if (m_toogle)
|
||||
sendSanitationReport(p->eqId, p->issi);
|
||||
|
||||
|
||||
movePlayer(p);
|
||||
tele.relPosition.offsetY = p->posUTM.y();
|
||||
tele.relPosition.offsetX = p->posUTM.x();
|
||||
|
||||
tele.header.timeStamp = time(nullptr) * 1000;
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvCentralTelegram ct(tele);
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram *tel = N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToRadio(&ct);
|
||||
tel->setZaehler(m_counter++);
|
||||
tel->setDestISSI(m_ttsArgs.destIssi);
|
||||
tel->setSrcISSI(p->issi);
|
||||
m_socket->write(tel->data());
|
||||
bytesSent += tel->getPayloadSize();
|
||||
delete tel;
|
||||
}
|
||||
bool bFlushed = m_socket->flush();
|
||||
INFO_LOG(m_logger) << "Sent " << bytesSent << "bytes (" << playerCount << " players), bFlushed=" << bFlushed;
|
||||
}
|
||||
|
||||
void TTWorker::onSocketError()
|
||||
{
|
||||
if (m_socket)
|
||||
m_socket->disconnectFromHost();
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointF>
|
||||
#include <QtCore/QMap>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <CoPrtCnv/CoPrtCnvCentralTelegram.hpp>
|
||||
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
|
||||
#include <CoPrtCnv/CoPrtCnvTelegramConverter.hpp>
|
||||
#include <TrainingAreaBase/training_area_telegrams.h>
|
||||
#include "server.h"
|
||||
|
||||
|
||||
class QTcpSocket;
|
||||
class QTimer;
|
||||
|
||||
class Player
|
||||
{
|
||||
private:
|
||||
void randomizeDeathTicks()
|
||||
{
|
||||
deathTicks = ((qrand() % (maximumDeathTicks - minimumDeathTicks + 1)) + minimumDeathTicks);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
uint32_t eqId;
|
||||
uint32_t issi;
|
||||
QPointF posUTM;
|
||||
|
||||
|
||||
bool isLogin;
|
||||
bool isValidBITE;
|
||||
TrainingAreaBase::TetraIcd::VulnerabilityState vbg;
|
||||
|
||||
|
||||
int patternInList;
|
||||
int stepInPattern;
|
||||
|
||||
|
||||
uint32_t deathTicks;
|
||||
uint32_t minimumDeathTicks;
|
||||
uint32_t maximumDeathTicks;
|
||||
|
||||
Player(int eqId_, int issi_, uint32_t minimumDeathTicks_, uint32_t maximumDeathTicks_, const QPointF &posUTM_)
|
||||
: eqId(eqId_)
|
||||
, issi(issi_)
|
||||
, posUTM(posUTM_)
|
||||
, isLogin(false)
|
||||
, isValidBITE(false)
|
||||
, vbg(TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady)
|
||||
, patternInList(0)
|
||||
, stepInPattern(1)
|
||||
, deathTicks(0)
|
||||
, minimumDeathTicks(minimumDeathTicks_)
|
||||
, maximumDeathTicks(maximumDeathTicks_)
|
||||
{
|
||||
randomizeDeathTicks();
|
||||
}
|
||||
|
||||
bool isEndOfTicks()
|
||||
{
|
||||
deathTicks--;
|
||||
if (deathTicks < 1)
|
||||
{
|
||||
randomizeDeathTicks();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class TTWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TTWorker(QTcpSocket *socket, const TTSArgs &ttsArgs);
|
||||
|
||||
bool init();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onReadyRead();
|
||||
void onSendPlayerPositions();
|
||||
|
||||
void onSocketError();
|
||||
void onSendNachforderungBroadcastTelegramm();
|
||||
void onSendDeaktivierungEinzelminen();
|
||||
|
||||
protected:
|
||||
void startExecution();
|
||||
QVector<runningPattern> interpretPattern(QString pattern) const;
|
||||
void movePlayer(Player *p);
|
||||
void handleReceivedTelegram(const QByteArray &data);
|
||||
void handleRegisterInd();
|
||||
void handleDataIndReq(const QByteArray &data);
|
||||
|
||||
void sendTelegram(N_CoPrtCnv::CoPrtCnvRadioTelegram *radioTelegram, uint32_t issi);
|
||||
template <typename T>
|
||||
void sendTelegram(const T &tele, uint32_t issi)
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvCentralTelegram ct(tele);
|
||||
sendTelegram(N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToRadio(&ct), issi);
|
||||
}
|
||||
void sendLogin(uint32_t eqId, uint32_t issi);
|
||||
void sendBITE(uint32_t eqId, uint32_t issi);
|
||||
void sendTaktischerStatus(uint32_t eqId, uint32_t issi, TrainingAreaBase::TetraIcd::VulnerabilityState vbg);
|
||||
void sendSanitationReport(uint32_t eqId, uint32_t issi);
|
||||
|
||||
private:
|
||||
QTcpSocket *m_socket;
|
||||
QTimer *m_timer;
|
||||
QByteArray m_buffer;
|
||||
unsigned int m_counter;
|
||||
bool m_toogle;
|
||||
|
||||
TTSArgs m_ttsArgs;
|
||||
|
||||
QVector<Player *> m_playerList;
|
||||
QVector<runningPattern> m_patternList;
|
||||
QPointF m_generalPosition;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
Reference in new issue
Block a user