Compare commits

..

10 Commits

Author SHA1 Message Date
Wiso
dc89b713bc
Add hints in testimony, add pause alias. (#397)
Some checks are pending
CI / build-windows (push) Blocked by required conditions
CI / build-linux (push) Blocked by required conditions
CI / check-clang-format (push) Waiting to run
* Add hints in testimony, add pause alias.

end is most commonly used, provides more clarity that the testimony has "stopped" and further testimony is via /add and /update.

* Fix examine cmd on-going examination check

Previously did not stop users from calling examine mid-examination.

* formating attempt

i am sorry clang-format

* Change "your" to "the".

Co-authored-by: in1tiate <32779090+in1tiate@users.noreply.github.com>

---------

Co-authored-by: in1tiate <32779090+in1tiate@users.noreply.github.com>
2025-02-05 08:32:09 -06:00
in1tiate
b1b06cc9f2
fix erroneous position update and remove restriction (#396)
- Don't set the client's position for no reason
- Don't stop positions other than wit from recording testimony
2025-02-04 10:29:32 -06:00
Wiso
f332defa52
Allow = and >[number] testimony traversal options. (#393)
* Allow = and >[number] testimony traversal options.

Automatically loops back to 1 if the user inputs a value over the statement size. Could instead deny sending that message entirely with an OOC error.

* Adjust reg exp to capture <[Number], remove duplicate reg check
2025-02-04 10:28:26 -06:00
in1tiate
1c13786214
Mark AFK players in the player list (#390)
* Mark AFK players in the player list

* it works now

* remove accidental net debug
2025-01-28 02:40:19 -06:00
in1tiate
3ddd53e121
Don't send player updates unless info changed (#389) 2025-01-02 13:20:11 -06:00
in1tiate
ecc981ae53
add missing /area cmd to help json 2024-12-22 08:52:19 -06:00
stonedDiscord
2f1436a4fa
artifact v4 2024-09-15 21:10:30 +02:00
Scott Brenner
68325e067a
Fix icon path in README.md (#381) 2024-09-13 21:51:04 -05:00
stonedDiscord
ad028be80f
add ssl port (#378)
* add ssl port

* Webfiles (#376)

* add webfiles command

* only show chars who are swapping

Co-Authored-By: Salanto <62221668+Salanto@users.noreply.github.com>

* whitespace wow

---------

Co-authored-by: Salanto <62221668+Salanto@users.noreply.github.com>

* fuck moc files (#377)

---------

Co-authored-by: stoned <stoned@derpymail.org>
Co-authored-by: Salanto <62221668+Salanto@users.noreply.github.com>
2024-09-13 15:22:03 +02:00
in1tiate
3b7d6cafde
Make background locking a CM permission (#379) 2024-09-13 15:21:47 +02:00
13 changed files with 94 additions and 47 deletions

View File

@ -18,7 +18,7 @@ jobs:
name: check-clang-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Run clang-format style check.
uses: jidicula/clang-format-action@v4.5.0
with:
@ -33,7 +33,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
uses: awalsh128/cache-apt-pkgs-action@latest
@ -57,7 +57,7 @@ jobs:
done;
- name: Upload binary
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: akashi-linux
path: bin/
@ -112,7 +112,7 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: ilammy/msvc-dev-cmd@v1
- name: Cache Qt
@ -151,7 +151,7 @@ jobs:
copy .\openssl-1.1\x64\bin\libssl-1_1-x64.dll .\bin\libssl-1_1-x64.dll
- name: Upload zip
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: akashi-windows
path: bin\

View File

@ -1,4 +1,4 @@
# akashi <img src="https://github.com/AttorneyOnline/akashi/blob/master/akashi/resource/icon/256.png" width=30 height=30>
# akashi <img src="https://github.com/AttorneyOnline/akashi/blob/master/resource/icon/256.png" width=30 height=30>
A C++ server for Attorney Online 2<br><br>
![Code Format and Build](https://github.com/AttorneyOnline/akashi/actions/workflows/main.yml/badge.svg?event=push) [![Codecov branch](https://img.shields.io/codecov/c/gh/AttorneyOnline/akashi/master)](https://app.codecov.io/gh/AttorneyOnline/akashi) [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/AttorneyOnline/akashi/graphs/commit-activity) ![GitHub](https://img.shields.io/github/license/AttorneyOnline/akashi?color=blue)<br>

View File

@ -89,4 +89,7 @@ aliases = kickother
aliases = jukeboxskip
[play_ambience]
aliases = playambience playa
aliases = playambience playa
[pause]
aliases = end

View File

@ -5,6 +5,9 @@ max_players=100
; The port to listen for incoming connections on.
port=27016
; The port to advertise for SSL.
secure_port=-1
; The server description that will appear on the master server.
server_description=This is a placeholder server description. Tell the world of AO who you are here!

View File

@ -29,6 +29,13 @@
"usage":"/getarea",
"text":"Lists all clients in the area the caller is in. This command takes no arguments."
},
{
"names": [
"area"
],
"usage":"/area <id>",
"test":"Moves the caller to the area with the given ID."
},
{
"names": [
"ban"

View File

@ -33,8 +33,8 @@ const QMap<QString, AOClient::CommandInfo> AOClient::COMMANDS{
{"rootpass", {{ACLRole::SUPER}, 1, &AOClient::cmdSetRootPass}},
{"background", {{ACLRole::NONE}, 1, &AOClient::cmdSetBackground}},
{"side", {{ACLRole::NONE}, 0, &AOClient::cmdSetSide}},
{"lock_background", {{ACLRole::BGLOCK}, 0, &AOClient::cmdBgLock}},
{"unlock_background", {{ACLRole::BGLOCK}, 0, &AOClient::cmdBgUnlock}},
{"lock_background", {{ACLRole::CM}, 0, &AOClient::cmdBgLock}},
{"unlock_background", {{ACLRole::CM}, 0, &AOClient::cmdBgUnlock}},
{"adduser", {{ACLRole::MODIFY_USERS}, 2, &AOClient::cmdAddUser}},
{"removeuser", {{ACLRole::MODIFY_USERS}, 1, &AOClient::cmdRemoveUser}},
{"listusers", {{ACLRole::MODIFY_USERS}, 0, &AOClient::cmdListUsers}},
@ -198,6 +198,9 @@ void AOClient::handlePacket(AOPacket *packet)
if (m_is_afk)
sendServerMessage("You are no longer AFK.");
m_is_afk = false;
if (characterName().endsWith(" [AFK]")) {
setCharacterName(characterName().remove(" [AFK]"));
}
m_afk_timer->start(ConfigManager::afkTimeout() * 1000);
}
@ -502,8 +505,10 @@ QString AOClient::name() const { return m_ooc_name; }
void AOClient::setName(const QString &f_name)
{
m_ooc_name = f_name;
Q_EMIT nameChanged(m_ooc_name);
if (f_name != m_ooc_name) {
m_ooc_name = f_name;
Q_EMIT nameChanged(m_ooc_name);
}
}
int AOClient::areaId() const
@ -513,8 +518,10 @@ int AOClient::areaId() const
void AOClient::setAreaId(const int f_area_id)
{
m_current_area = f_area_id;
Q_EMIT areaIdChanged(m_current_area);
if (f_area_id != m_current_area) {
m_current_area = f_area_id;
Q_EMIT areaIdChanged(m_current_area);
}
}
QString AOClient::character() const
@ -524,16 +531,20 @@ QString AOClient::character() const
void AOClient::setCharacter(const QString &f_character)
{
m_current_char = f_character;
Q_EMIT characterChanged(m_current_char);
if (f_character != m_current_char) {
m_current_char = f_character;
Q_EMIT characterChanged(m_current_char);
}
}
QString AOClient::characterName() const { return m_showname; }
void AOClient::setCharacterName(const QString &f_showname)
{
m_showname = f_showname;
Q_EMIT characterNameChanged(m_showname);
if (f_showname != m_showname) {
m_showname = f_showname;
Q_EMIT characterNameChanged(m_showname);
}
}
void AOClient::setSpectator(bool f_spectator)
@ -548,8 +559,10 @@ bool AOClient::isSpectator() const
void AOClient::onAfkTimeout()
{
if (!m_is_afk)
if (!m_is_afk) {
sendServerMessage("You are now AFK.");
setCharacterName(characterName() + " [AFK]");
}
m_is_afk = true;
}

View File

@ -113,12 +113,12 @@ void AOClient::cmdTestify(int argc, QStringList argv)
AreaData *l_area = server->getAreaById(areaId());
if (l_area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING) {
sendServerMessage("Testimony recording is already in progress. Please stop it before starting a new one.");
sendServerMessage("Testimony recording is already in progress. Please stop it with /end before starting a new one.");
}
else {
clearTestimony();
l_area->setTestimonyRecording(AreaData::TestimonyRecording::RECORDING);
sendServerMessage("Started testimony recording.");
sendServerMessage("Started testimony recording. The next IC message will be a title. Use /end to stop recording.");
}
}
@ -129,15 +129,19 @@ void AOClient::cmdExamine(int argc, QStringList argv)
AreaData *l_area = server->getAreaById(areaId());
if (l_area->testimony().size() - 1 > 0) {
l_area->restartTestimony();
server->broadcast(PacketFactory::createPacket("RT", {"testimony2", "0"}), areaId());
server->broadcast(PacketFactory::createPacket("MS", {l_area->testimony()[0]}), areaId());
return;
if (l_area->testimonyRecording() == AreaData::TestimonyRecording::PLAYBACK) {
sendServerMessage("An examination is already running. Use /testimony to view the testimony.");
}
else {
l_area->restartTestimony();
server->broadcast(PacketFactory::createPacket("RT", {"testimony2", "0"}), areaId());
server->broadcast(PacketFactory::createPacket("MS", {l_area->testimony()[0]}), areaId());
return;
}
}
else {
sendServerMessage("Unable to start replay without prior testimony. Use /testify to start Or load a testimony with /loadtestimony.");
}
if (l_area->testimonyRecording() == AreaData::TestimonyRecording::PLAYBACK)
sendServerMessage("Unable to examine while another examination is running");
else
sendServerMessage("Unable to start replay without prior examination.");
}
void AOClient::cmdTestimony(int argc, QStringList argv)
@ -182,7 +186,7 @@ void AOClient::cmdUpdateStatement(int argc, QStringList argv)
Q_UNUSED(argv);
server->getAreaById(areaId())->setTestimonyRecording(AreaData::TestimonyRecording::UPDATE);
sendServerMessage("The next IC-Message will replace the last displayed replay message.");
sendServerMessage("The next IC-Message will replace the currently selected testimony line.");
}
void AOClient::cmdPauseTestimony(int argc, QStringList argv)
@ -193,7 +197,7 @@ void AOClient::cmdPauseTestimony(int argc, QStringList argv)
AreaData *l_area = server->getAreaById(areaId());
l_area->setTestimonyRecording(AreaData::TestimonyRecording::STOPPED);
server->broadcast(PacketFactory::createPacket("RT", {"testimony1", "1"}), areaId());
sendServerMessage("Testimony has been stopped.");
sendServerMessage("Testimony has been stopped. Use /examine to begin cross-examination.");
}
void AOClient::cmdAddStatement(int argc, QStringList argv)

View File

@ -64,8 +64,6 @@ QStringList AOClient::buildAreaList(int area_idx)
char_entry.insert(0, "[CM] ");
if (m_authenticated)
char_entry += " (" + l_client->getIpid() + "): " + l_client->name();
if (l_client->m_is_afk)
char_entry += " [AFK]";
entries.append(char_entry);
}
}

View File

@ -387,6 +387,7 @@ void AOClient::cmdAfk(int argc, QStringList argv)
m_is_afk = true;
sendServerMessage("You are now AFK.");
setCharacterName(characterName() + " [AFK]");
}
void AOClient::cmdCharCurse(int argc, QStringList argv)

View File

@ -71,17 +71,12 @@ bool ConfigManager::verifyServerConfig()
qCritical("port is not a valid port!");
return false;
}
bool web_ao = m_settings->value("webao_enable", false).toBool();
if (!web_ao) {
m_settings->setValue("webao_port", -1);
}
else {
m_settings->value("webao_port", 27017).toInt(&ok);
if (!ok) {
qCritical("webao_port is not a valid port!");
return false;
}
m_settings->value("secure_port", -1).toInt(&ok);
if (!ok) {
qCritical("secure_port is not a valid port!");
return false;
}
QString l_auth = m_settings->value("auth", "simple").toString().toLower();
if (!(l_auth == "simple" || l_auth == "advanced")) {
qCritical("auth is not a valid auth type!");
@ -327,6 +322,11 @@ int ConfigManager::serverPort()
return m_settings->value("Options/port", 27016).toInt();
}
int ConfigManager::securePort()
{
return m_settings->value("Options/secure_port", -1).toInt();
}
QString ConfigManager::serverDescription()
{
return m_settings->value("Options/server_description", "This is my flashy new server!").toString();

View File

@ -143,6 +143,13 @@ class ConfigManager
*/
static int serverPort();
/**
* @brief Returns the SSL port to listen for connections on.
*
* @return See short description.
*/
static int securePort();
/**
* @brief Returns the server description.
*

View File

@ -394,9 +394,7 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const
client_name = client.character(); // fallback in case of empty ooc name
}
if (area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING || area->testimonyRecording() == AreaData::TestimonyRecording::ADD) {
if (!l_args[5].startsWith("wit"))
return PacketFactory::createPacket("MS", l_args);
// -1 indicates title
if (area->statement() == -1) {
l_args[4] = "~~-- " + l_args[4] + " --";
l_args[14] = "3";
@ -434,9 +432,17 @@ AOPacket *PacketMS::validateIcPacket(AOClient &client) const
client.sendServerMessage("First statement reached.");
}
}
if (l_args[4] == "=") {
auto l_statement = area->jumpToStatement(area->statement());
l_args = l_statement.first;
l_progress = l_statement.second;
client.m_pos = l_args[5];
client.sendServerMessageArea(client_name + " repeated the current statement.");
}
QRegularExpressionMatch match = isTestimonyJumpCommand(client.decodeMessage(l_args[4])); // Get rid of that pesky encoding, then do the fun part
if (match.hasMatch()) {
client.m_pos = "wit";
int jump_idx = match.captured("int").toInt();
auto l_statement = area->jumpToStatement(jump_idx);
l_args = l_statement.first;
@ -473,6 +479,8 @@ QRegularExpressionMatch PacketMS::isTestimonyJumpCommand(QString message) const
// even if it hurts my heart
//
// and my grey matter
QRegularExpression jump("(?<arrow>>)(?<int>[0,1,2,3,4,5,6,7,8,9]+)");
//
// get well soon
QRegularExpression jump("(?<arrow>>|<)(?<int>\\d+)");
return jump.match(message);
}

View File

@ -58,6 +58,9 @@ void ServerPublisher::publishServer()
if (!ConfigManager::serverDomainName().trimmed().isEmpty()) {
serverinfo["ip"] = ConfigManager::serverDomainName();
}
if (ConfigManager::securePort() != -1) {
serverinfo["wss_port"] = ConfigManager::securePort();
}
serverinfo["port"] = 27106;
serverinfo["ws_port"] = ConfigManager::advertiseWSProxy() ? WS_REVERSE_PROXY : m_port;
serverinfo["players"] = *m_players;