add music, lay groundwork for areas

This commit is contained in:
scatterflower 2020-08-30 01:25:30 -05:00
parent e574e70795
commit dc932451e6
6 changed files with 162 additions and 31 deletions

View File

@ -20,14 +20,22 @@
#include <QMap>
#include <QString>
#include <QSettings>
#include <QDebug>
class AreaData {
public:
AreaData(QStringList characters);
AreaData(QStringList p_characters, QString p_name, int p_index);
QString name;
int index;
QMap<QString, bool> characters_taken;
int player_count;
QString background;
bool showname_allowed;
bool locking_allowed;
bool iniswap_allowed;
};
#endif // AREA_DATA_H

View File

@ -42,11 +42,13 @@ class Server : public QObject {
void start();
AOClient* getClient(QString ipid);
void updateCharsTaken(AreaData* area);
void broadcast(AOPacket packet);
void broadcast(AOPacket packet, int area_index);
int player_count;
QStringList characters;
QVector<AreaData*> areas;
QStringList area_names;
QStringList music_list;
signals:

View File

@ -32,7 +32,7 @@ AOClient::AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent)
void AOClient::clientData()
{
QString data = QString::fromUtf8(socket->readAll());
// qDebug() << "From" << client->peerAddress() << ":" << data;
qDebug() << "From" << remote_ip << ":" << data;
if (is_partial) {
data = partial_packet + data;
@ -89,7 +89,7 @@ void AOClient::handlePacket(AOPacket packet)
"noencryption", "yellowtext", "prezoom",
"flipping", "customobjections", "fastloading",
"deskmod", "evidence", "cccc_ic_support",
"arup", "casing_alserts", "modcall_reason",
"arup", "casing_alerts", "modcall_reason",
"looping_sfx", "additive", "effects"};
AOPacket response_pn(
"PN", {QString::number(server->player_count), max_players});
@ -101,7 +101,7 @@ void AOClient::handlePacket(AOPacket packet)
// TODO: add user configurable content
// For testing purposes, we will just send enough to get things working
AOPacket response(
"SI", {QString::number(server->characters.length()), "0", "1"});
"SI", {QString::number(server->characters.length()), "0", QString::number(server->area_names.length() + server->music_list.length())});
sendPacket(response);
}
else if (packet.header == "RC") {
@ -109,16 +109,21 @@ void AOClient::handlePacket(AOPacket packet)
sendPacket(response);
}
else if (packet.header == "RM") {
AOPacket response("SM", {"~stop.mp3"});
AOPacket response("SM", server->area_names + server->music_list);
sendPacket(response);
}
else if (packet.header == "RD") {
server->player_count++;
joined = true;
server->updateCharsTaken(area);
QSettings areas_ini("areas.ini", QSettings::IniFormat);
QStringList areas = areas_ini.childGroups();
AOPacket response_fa("FA", areas);
AOPacket response_op("OPPASS", {"DEADBEEF"});
AOPacket response_done("DONE", {});
sendPacket(response_fa);
sendPacket(response_op);
sendPacket(response_done);
}
@ -157,15 +162,17 @@ void AOClient::handlePacket(AOPacket packet)
}
else if (packet.header == "MS") {
// TODO: validate, validate, validate
server->broadcast(packet);
server->broadcast(packet, current_area);
}
else if (packet.header == "CT") {
// TODO: commands
// TODO: zalgo strip
server->broadcast(packet);
server->broadcast(packet, current_area);
}
else if (packet.header == "CH") {
// Why does this packet exist
// At least Crystal made it useful
// It is now used for ping measurement
AOPacket response("CHECK", {});
sendPacket(response);
}
@ -174,16 +181,53 @@ void AOClient::handlePacket(AOPacket packet)
"CT", {"Made with love", "by scatterflower and windrammer"});
sendPacket(response);
}
else if (packet.header == "MC") {
// Due to historical reasons, this
// packet has two functions:
// Change area, and set music.
// First, we check if the provided
// argument is a valid song
QString argument = packet.contents[0];
bool is_song = false;
for (QString song : server->music_list) {
if (song == argument) {
is_song = true;
break;
}
}
if (is_song) {
// If we have a song, retransmit as-is
server->broadcast(packet, current_area);
return;
}
bool is_area = false;
for (QString area : server->area_names) {
if(area == argument) {
is_area = true;
break;
}
}
if (is_area) {
// TODO: change area function that resends all area data and sets user stuff
// For now, we pretend
AOPacket user_message("CT", {"Server", "Changed to area " + argument});
sendPacket(user_message);
}
}
else {
qDebug() << "Unimplemented packet:" << packet.header;
qDebug() << packet.contents;
}
socket->flush();
}
void AOClient::sendPacket(AOPacket packet)
{
//qDebug() << "Sent packet:" << packet.header << ":" << packet.contents;
qDebug() << "Sent packet:" << packet.header << ":" << packet.contents;
socket->write(packet.toUtf8());
socket->flush();
}
@ -192,6 +236,11 @@ QString AOClient::getHwid() { return hwid; }
void AOClient::setHwid(QString p_hwid)
{
// TODO: add support for longer hwids?
// This reduces the (fairly high) chance of
// birthday paradox issues arising. However,
// typing more than 8 characters might be a
// bit cumbersome.
hwid = p_hwid;
QCryptographicHash hash(

View File

@ -17,9 +17,15 @@
//////////////////////////////////////////////////////////////////////////////////////
#include "include/area_data.h"
AreaData::AreaData(QStringList characters)
AreaData::AreaData(QStringList characters, QString p_name, int p_index)
{
name = p_name;
index = p_index;
for (QString cur_char : characters) {
characters_taken.insert(cur_char, false);
}
QSettings areas_ini("areas.ini", QSettings::IniFormat);
areas_ini.beginGroup(p_name);
background = areas_ini.value("background", "gs4").toString();
areas_ini.endGroup();
}

View File

@ -91,6 +91,69 @@ bool ConfigManager::initConfig()
char_list.close();
}
QFileInfo music_list_info("music.txt");
if (!(music_list_info.exists() && music_list_info.isFile())) {
QFile music_list("music.txt");
if (!music_list.open(QIODevice::WriteOnly | QIODevice::Text))
qDebug() << "Couldn't create music list";
QTextStream file_stream(&music_list);
qDebug() << "Creating vanilla music list";
file_stream << "Announce The Truth (AA).opus\n";
file_stream << "Announce The Truth (AJ).opus\n";
file_stream << "Announce The Truth (JFA).opus\n";
file_stream << "Announce The Truth (Miles).opus\n";
file_stream << "Announce The Truth (T&T).opus\n";
file_stream << "Confrontation ~ Presto 2009.opus\n";
file_stream << "Crises of Fate.opus\n";
file_stream << "Forgotten Legend.opus\n";
file_stream << "Godot - The Fragrance of Dark Coffee.opus\n";
file_stream << "Great Revival ~ Franziska von Karma.opus\n";
file_stream << "Great Revival ~ Miles Edgeworth.opus\n";
file_stream << "Hotline of Fate.opus\n";
file_stream << "Interesting People.opus\n";
file_stream << "Logic and Trick.opus\n";
file_stream << "Luke Atmey ~ I Just Want Love.opus\n";
file_stream << "Noisy People.opus\n";
file_stream << "OBJECTION (AA).opus\n";
file_stream << "Objection (AJ).opus\n";
file_stream << "OBJECTION (JFA).opus\n";
file_stream << "Objection (Miles).opus\n";
file_stream << "OBJECTION (T&T).opus\n";
file_stream << "Others ~ Guilty love.opus\n";
file_stream << "Prelude (AA).opus\n";
file_stream << "Prelude (AJ).opus\n";
file_stream << "Prologue (AA).opus\n";
file_stream << "Pursuit (AA) - variation.opus\n";
file_stream << "Pursuit (AA).opus\n";
file_stream << "Pursuit (AJ).opus\n";
file_stream << "Pursuit (DS).opus\n";
file_stream << "Pursuit (JFA) - variation.opus\n";
file_stream << "Pursuit (JFA).opus\n";
file_stream << "Pursuit (Miles).opus\n";
file_stream << "Pursuit (T&T) - variation.opus\n";
file_stream << "Pursuit (T&T).opus\n";
file_stream << "Pursuit ~ I Want to Find the Truth (Orchestra).opus\n";
file_stream << "Questioning AA (Allegro).opus\n";
file_stream << "Questioning AA (Moderato).opus\n";
file_stream << "Questioning AJ (Allegro).opus\n";
file_stream << "Questioning AJ (Moderato).opus\n";
file_stream << "Questioning JFA (Allegro).opus\n";
file_stream << "Questioning JFA (Moderato).opus\n";
file_stream << "Questioning T&T (Allegro).opus\n";
file_stream << "Questioning T&T (Moderato).opus\n";
file_stream << "Speak up Pup.opus\n";
file_stream << "Suspense (AA).opus\n";
file_stream << "The Great Truth Burglar.opus\n";
file_stream << "Trial (AA).opus\n";
file_stream << "Trial (AJ).opus\n";
file_stream << "Trial (Miles).opus\n";
music_list.flush();
music_list.close();
}
config->beginGroup("Info");
QString config_version = config->value("version", "none").toString();
config->endGroup();

View File

@ -30,19 +30,6 @@ Server::Server(int p_port, int p_ws_port, QObject* parent) : QObject(parent)
void Server::start()
{
// TODO: websockets lul
// Maybe websockets should be handled by a separate intermediate part of the
// code? The idea being that it is a websocket server, and all it does is
// create a local connection to the raw tcp server. The main issue with this
// is that it will cause problems with bans, ipids, etc But perhaps this can
// be negotiated by sending some extra data over? No idea. I'll wait for
// long to read this massive comment and DM me on discord
//
// Upon thinking about this a bit more, I realized basically all of the
// communication only happens via QTcpSocket* pointers.
// If the Qt WebSocket server gives me QTcpSockets to work with,
// then they can all go into the same object. I doubt this is the case,
// though
if (!server->listen(QHostAddress::Any, port)) {
// TODO: signal server start failed
qDebug() << "Server error:" << server->errorString();
@ -61,10 +48,25 @@ void Server::start()
while (!char_list.atEnd()) {
characters.append(char_list.readLine().trimmed());
}
char_list.close();
// TODO: actually read areas from config
areas.append(new AreaData(characters));
areas[0]->name = "basement lol";
QFile music_file("music.txt");
music_file.open(QIODevice::ReadOnly | QIODevice::Text);
while (!music_file.atEnd()) {
music_list.append(music_file.readLine().trimmed());
}
music_file.close();
if(music_list[0].contains(".")) // Add a default category if none exists
music_list.insert(0, "Music");
// TODO: add verification that this exists
QSettings areas_ini("areas.ini", QSettings::IniFormat);
area_names = areas_ini.childGroups();
for (int i = 0; i < area_names.length(); i++) {
QString area_name = area_names[i];
areas.insert(i, new AreaData(characters, area_name, i));
qDebug() << "Added area" << area_name;
}
}
void Server::clientConnected()
@ -100,14 +102,15 @@ void Server::updateCharsTaken(AreaData* area)
}
AOPacket response_cc("CharsCheck", chars_taken);
broadcast(response_cc);
broadcast(response_cc, area->index);
}
void Server::broadcast(AOPacket packet)
void Server::broadcast(AOPacket packet, int area_index)
{
// TODO: make this selective to the current area only
for (AOClient* client : clients) {
client->sendPacket(packet);
if (client->current_area == area_index)
client->sendPacket(packet);
}
}