126 lines
4.3 KiB
C++
126 lines
4.3 KiB
C++
#include <chrono>
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#ifndef NOMINMAX
|
|
#define NOMINMAX
|
|
#endif
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
|
|
namespace {
|
|
|
|
bool MetaCoreInitializeWinsock() {
|
|
WSADATA wsaData{};
|
|
return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
|
|
}
|
|
|
|
void MetaCoreShutdownWinsock() {
|
|
WSACleanup();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main(int argc, char* argv[]) {
|
|
const std::string bindHost = argc > 1 ? argv[1] : "127.0.0.1";
|
|
const unsigned short port = argc > 2 ? static_cast<unsigned short>(std::strtoul(argv[2], nullptr, 10)) : 7001;
|
|
|
|
if (!MetaCoreInitializeWinsock()) {
|
|
std::cerr << "MetaCoreTcpSenderTool: WSAStartup failed\n";
|
|
return 1;
|
|
}
|
|
|
|
addrinfo hints{};
|
|
hints.ai_family = AF_INET;
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
hints.ai_flags = AI_PASSIVE;
|
|
|
|
addrinfo* result = nullptr;
|
|
const std::string portString = std::to_string(port);
|
|
if (getaddrinfo(bindHost.c_str(), portString.c_str(), &hints, &result) != 0 || result == nullptr) {
|
|
std::cerr << "MetaCoreTcpSenderTool: getaddrinfo failed\n";
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
|
|
SOCKET listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
|
if (listenSocket == INVALID_SOCKET) {
|
|
std::cerr << "MetaCoreTcpSenderTool: socket creation failed\n";
|
|
freeaddrinfo(result);
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
|
|
if (bind(listenSocket, result->ai_addr, static_cast<int>(result->ai_addrlen)) == SOCKET_ERROR) {
|
|
std::cerr << "MetaCoreTcpSenderTool: bind failed\n";
|
|
closesocket(listenSocket);
|
|
freeaddrinfo(result);
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
freeaddrinfo(result);
|
|
|
|
if (listen(listenSocket, 1) == SOCKET_ERROR) {
|
|
std::cerr << "MetaCoreTcpSenderTool: listen failed\n";
|
|
closesocket(listenSocket);
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "MetaCoreTcpSenderTool: listening on " << bindHost << ":" << port << '\n';
|
|
SOCKET clientSocket = accept(listenSocket, nullptr, nullptr);
|
|
closesocket(listenSocket);
|
|
if (clientSocket == INVALID_SOCKET) {
|
|
std::cerr << "MetaCoreTcpSenderTool: accept failed\n";
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "MetaCoreTcpSenderTool: client connected\n";
|
|
for (int frame = 0; frame < 600; ++frame) {
|
|
const double t = static_cast<double>(frame) * 0.05;
|
|
const float x = static_cast<float>(std::sin(t) * 2.0);
|
|
const bool visible = std::fmod(t, 2.0) < 1.0;
|
|
const bool valveVisible = std::fmod(t, 3.0) < 1.5;
|
|
const float r = 0.5F + static_cast<float>(std::sin(t) * 0.4);
|
|
const float g = 0.6F;
|
|
const float b = 0.9F - static_cast<float>(std::sin(t) * 0.2);
|
|
const float tankR = 0.25F + static_cast<float>((std::sin(t * 0.5) + 1.0) * 0.25);
|
|
const float tankG = 0.55F + static_cast<float>((std::cos(t * 0.5) + 1.0) * 0.15);
|
|
const float tankB = 0.35F;
|
|
const double alarmIntensity = valveVisible ? 2.5 : 0.0;
|
|
|
|
const std::string payload =
|
|
"cube.position vec3 " + std::to_string(x) + " 0.5 0.0\n" +
|
|
"cube.visible bool " + std::string(visible ? "true" : "false") + "\n" +
|
|
"cube.base_color vec3 " + std::to_string(r) + " " + std::to_string(g) + " " + std::to_string(b) + "\n" +
|
|
"valve.visible bool " + std::string(valveVisible ? "true" : "false") + "\n" +
|
|
"tank.base_color vec3 " + std::to_string(tankR) + " " + std::to_string(tankG) + " " + std::to_string(tankB) + "\n" +
|
|
"alarm.intensity double " + std::to_string(alarmIntensity) + "\n";
|
|
|
|
const int sent = send(clientSocket, payload.c_str(), static_cast<int>(payload.size()), 0);
|
|
if (sent == SOCKET_ERROR) {
|
|
std::cerr << "MetaCoreTcpSenderTool: send failed\n";
|
|
closesocket(clientSocket);
|
|
MetaCoreShutdownWinsock();
|
|
return 1;
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
}
|
|
|
|
shutdown(clientSocket, SD_SEND);
|
|
closesocket(clientSocket);
|
|
MetaCoreShutdownWinsock();
|
|
std::cout << "MetaCoreTcpSenderTool: stream completed\n";
|
|
return 0;
|
|
}
|