Skip to content
This repository was archived by the owner on Sep 13, 2022. It is now read-only.
Open
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ build100.sh
keys.dat
.exefs100/
.exefs130/
build130.sh
build130.sh
.DS_Store
1 change: 1 addition & 0 deletions include/fl/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace smo
class InPacketPlayerTeleport : public InPacket
{
sead::Vector3f pos;
sead::Quatf rot;
public:
void parse(const u8* data, u32 len);
void on(Server& server);
Expand Down
12 changes: 6 additions & 6 deletions include/fl/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class PracticeUI
sead::Vector3f savedTrans;
sead::Quatf savedQuat;
bool saved = false;
bool teleportEnabled = false;
bool teleportEnabled = true;
s8 reloadStageForPos = -1;
sead::Vector3f reloadStagePos;
sead::Quatf reloadStageQuat;
Expand Down Expand Up @@ -45,10 +45,10 @@ class PracticeUI

inline StageScene* getStageScene() {return stageScene;}

bool shineRefresh = false;
bool gotShineRefresh = false;
bool alwaysWarp = false;
bool disableAutoSave = false;
bool shineRefresh = true;
bool gotShineRefresh = true;
bool alwaysWarp = true;
bool disableAutoSave = true;
bool skipBowser = false;

bool isModeDiverOrJungleGymRom = false;
Expand All @@ -60,7 +60,7 @@ class PracticeUI

enum Page : u8
{
About, Options, Stage, Misc, Info, Tas, MoonInfo, Modes, Debug
About, Options, Stage, Misc, Info, Info2, Info3, Tas, MoonInfo, Modes, Debug
};

enum MofumofuPattern : s8
Expand Down
2 changes: 2 additions & 0 deletions smo-tas-server/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <string>
#include <vector>

#define RAD(deg) (deg * (M_PI / 180))

namespace smo
{
static const std::vector<std::string>& getStages()
Expand Down
1 change: 1 addition & 0 deletions smo-tas-server/include/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace smo
{
public:
Vector3f pos;
Quatf rot;

u32 calcLen();
void construct(u8* dst);
Expand Down
2 changes: 2 additions & 0 deletions smo-tas-server/include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <types.h>
#include <unordered_map>
#include <packet.h>
#include <deque>

namespace smo
{
Expand All @@ -28,6 +29,7 @@ namespace smo
{
private:
s32 socketfd;
void handleScript(std::deque<std::string> args);
void loopThread();
public:
u8 start(u16 port);
Expand Down
6 changes: 6 additions & 0 deletions smo-tas-server/include/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <types.h>
#include <math.h>

namespace fl {
smo::Quatf eulerToQuat(smo::Vector3f euler);
}
6 changes: 5 additions & 1 deletion smo-tas-server/src/packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ void smo::OutPacketPlayerScriptInfo::construct(u8* dst)

u32 smo::OutPacketPlayerTeleport::calcLen()
{
return 12;
return 28;
}

void smo::OutPacketPlayerTeleport::construct(u8* dst)
{
*((float*) &dst[0]) = pos.x;
*((float*) &dst[4]) = pos.y;
*((float*) &dst[8]) = pos.z;
*((float*) &dst[12]) = rot.w;
*((float*) &dst[16]) = rot.x;
*((float*) &dst[20]) = rot.y;
*((float*) &dst[24]) = rot.z;
}

u32 smo::OutPacketPlayerGo::calcLen()
Expand Down
155 changes: 109 additions & 46 deletions smo-tas-server/src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "script.h"
#include "tas.h"
#include "types.h"
#include "util.h"
#include <chrono>
#include <ratio>
#include <server.h>
Expand Down Expand Up @@ -32,6 +33,10 @@

namespace smo
{
std::deque<std::string> scriptArgs;
std::deque<std::string> goArgs;
std::deque<std::string> tpArgs;

void smo::Client::connect()
{
struct in_addr ip;
Expand Down Expand Up @@ -115,23 +120,104 @@ namespace smo
return 0;
}

void smo::Server::handleScript(std::deque<std::string> args) {
if (args.size() != 1)
{
if (scriptArgs.empty()) {
std::cout << "script <script file>" << std::endl;
return;
}
else
args = scriptArgs;
}
if (!std::filesystem::exists(args[0]))
{
std::cout << "Specified script file does not exist" << std::endl;
return;
}
scriptArgs = args;
std::ifstream scriptFile(args[0]);
fl::TasScript script = fl::script::fromText(scriptFile);
scriptFile.close();

OutPacketPlayerScriptInfo p;
p.scriptName = args[0];
c.sendPacket(this, p, smo::OutPacketType::PlayerScriptInfo);

std::this_thread::sleep_for(std::chrono::milliseconds(32));

OutPacketPlayerScriptData pD;
{
u32 i = 0;
for (fl::TasFrame& f : script.frames)
{
pD.script.frames.push_back(f);
i++;
if (i >= 1500)
{
c.sendPacket(this, pD, smo::OutPacketType::PlayerScriptData);
pD.script.frames.clear();
i = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(script.frames.size() / 10000));
}
}
if (i != 0)
{
c.sendPacket(this, pD, smo::OutPacketType::PlayerScriptData);
}
}
}

void smo::Server::loopThread()
{
using namespace std::chrono_literals;
const std::unordered_map<std::string, std::function<void(std::deque<std::string>&)>> cmd = {
{"tp", [this](std::deque<std::string>& args)
{
if (args.size() != 3)
if (args.size() < 3)
{
std::cout << "tp <X> <Y> <Z>" << std::endl;
return;
if (tpArgs.empty()) {
std::cout << "tp <X> <Y> <Z> OR" << std::endl;
std::cout << "tp <X> <Y> <Z> <Y-rot> OR" << std::endl;
std::cout << "tp <X> <Y> <Z> <X-rot> <Y-rot> <Z-rot> OR" << std::endl;
std::cout << "tp <X> <Y> <Z> <quat-W> <quat-X> <quat-Y> <quat-Z>" << std::endl;
return;
}
else
args = tpArgs;
}
Vector3f pos;
Vector3f eulerAngles;
Quatf rot;
try
{
pos.x = std::stof(args[0]);
pos.y = std::stof(args[1]);
pos.z = std::stof(args[2]);
if (args.size() == 3) {
rot.w = 1;
rot.x = 0;
rot.y = 0;
rot.z = 0;
}
else if (args.size() == 4) {
eulerAngles.x = 0;
eulerAngles.y = RAD(std::stof(args[3]));
eulerAngles.z = 0;
rot = fl::eulerToQuat(eulerAngles);
}
else if (args.size() == 6) {
eulerAngles.x = RAD(std::stof(args[3]));
eulerAngles.y = RAD(std::stof(args[4]));
eulerAngles.z = RAD(std::stof(args[5]));
rot = fl::eulerToQuat(eulerAngles);
}
else if (args.size() == 7) {
rot.w = std::stof(args[3]);
rot.x = std::stof(args[4]);
rot.y = std::stof(args[5]);
rot.z = std::stof(args[6]);
}
}
catch (std::invalid_argument e)
{
Expand All @@ -140,14 +226,20 @@ namespace smo
}
OutPacketPlayerTeleport p;
p.pos = pos;
p.rot = rot;
tpArgs = args;
c.sendPacket(this, p, smo::OutPacketType::PlayerTeleport);
}},
{"go", [this](std::deque<std::string>& args)
{
if (args.size() == 0)
{
std::cout << "go <stage name> <scenario> <entrance> <start script (true:false)>" << std::endl;
return;
if (goArgs.empty()) {
std::cout << "go <stage name> <scenario> <entrance> <start script (true:false)>" << std::endl;
return;
}
else
args = goArgs;
}
std::string entrance = "start";
s8 scenario = -1;
Expand Down Expand Up @@ -181,56 +273,27 @@ namespace smo
p.scenario = scenario;
p.stageName = args[0];
p.entrance = entrance;
goArgs = args;
c.sendPacket(this, p, smo::OutPacketType::PlayerGo);
}},
{"script", [this](std::deque<std::string>& args)
{
if (args.size() != 1)
{
std::cout << "script <script file>" << std::endl;
return;
}
if (!std::filesystem::exists(args[0]))
{
std::cout << "Specified script file does not exist" << std::endl;
return;
}
std::ifstream scriptFile(args[0]);
fl::TasScript script = fl::script::fromText(scriptFile);
scriptFile.close();

OutPacketPlayerScriptInfo p;
p.scriptName = args[0];
c.sendPacket(this, p, smo::OutPacketType::PlayerScriptInfo);

std::this_thread::sleep_for(std::chrono::milliseconds(32));

OutPacketPlayerScriptData pD;
{
u32 i = 0;
for (fl::TasFrame& f : script.frames)
{
pD.script.frames.push_back(f);
i++;
if (i >= 1500)
{
c.sendPacket(this, pD, smo::OutPacketType::PlayerScriptData);
pD.script.frames.clear();
i = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(script.frames.size() / 10000));
}
}
if (i != 0)
{
c.sendPacket(this, pD, smo::OutPacketType::PlayerScriptData);
}
}
handleScript(args);
}},
{"s", [this](std::deque<std::string>& args)
{
handleScript(args);
}},
{"help", [this](std::deque<std::string>& args)
{
std::cout << "tp <X> <Y> <Z>\n Teleport Player to position" << std::endl;
std::cout << "tp <X> <Y> <Z>\n Teleport Player to position, rotation 0 degrees" << std::endl;
std::cout << "tp <X> <Y> <Z> <Y-rot>" << std::endl;
std::cout << "tp <X> <Y> <Z> <X-rot> <Y-rot> <Z-rot>" << std::endl;
std::cout << "tp <X> <Y> <Z> <quat-W> <quat-X> <quat-Y> <quat-Z>\n Teleport Player to position with specified rotation" << std::endl;
std::cout << "go <stage name> <entrance> <scenario>\n Teleport Player to stage" << std::endl;
std::cout << "script <script file>\n Start script" << std::endl;
std::cout << "s <script file>\n Start script" << std::endl;
std::cout << "run a command without arguments to run it with the last valid arguments you used" << std::endl;
}}
};
std::deque<std::string> lastCommand;
Expand Down
20 changes: 20 additions & 0 deletions smo-tas-server/src/util.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <util.h>

smo::Quatf fl::eulerToQuat(smo::Vector3f euler) {

smo::Quatf quat;

f32 cy = cos(euler.y / 2);
f32 sy = sin(euler.y / 2);
f32 cp = cos(euler.z / 2);
f32 sp = sin(euler.z / 2);
f32 cr = cos(euler.x / 2);
f32 sr = sin(euler.x / 2);

quat.w = cr * cp * cy + sr * sp * sy;
quat.x = sr * cp * cy - cr * sp * sy;
quat.z = cr * sp * cy + sr * cp * sy;
quat.y = cr * cp * sy - sr * sp * cy;

return quat;
}
5 changes: 5 additions & 0 deletions source/fl/packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ namespace smo
pos.x = *(float*) &data[0];
pos.y = *(float*) &data[4];
pos.z = *(float*) &data[8];
rot.w = *(float*) &data[12];
rot.x = *(float*) &data[16];
rot.y = *(float*) &data[20];
rot.z = *(float*) &data[24];
}

void InPacketPlayerTeleport::on(Server &server)
Expand All @@ -61,6 +65,7 @@ namespace smo
PlayerActorHakoniwa* player = rs::getPlayerActor(stageScene);
player->startDemoPuppetable();
al::setTrans(player, pos);
al::updatePoseQuat(player, rot);
player->endDemoPuppetable();
}

Expand Down
Loading