forked from mirror/openmw-tes3mp
commit
2bc79fcdf4
@ -1,3 +1,6 @@
|
||||
[submodule "extern/breakpad"]
|
||||
path = extern/breakpad
|
||||
url = https://chromium.googlesource.com/breakpad/breakpad
|
||||
[submodule "extern/sol"]
|
||||
path = extern/sol
|
||||
url = https://github.com/ThePhD/sol2
|
||||
|
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Created by koncord on 04.09.17.
|
||||
//
|
||||
|
||||
#include "AdminRest.hpp"
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include "RestUtils.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace chrono;
|
||||
using namespace boost::property_tree;
|
||||
|
||||
|
||||
AdminRest::AdminRest(const std::string &cert, const std::string &key, const std::string &verifyFile,
|
||||
unsigned short port, std::shared_ptr<MasterServer> master) : httpServer(cert, key, verifyFile), master(master)
|
||||
{
|
||||
httpServer.config.port = port;
|
||||
}
|
||||
|
||||
void AdminRest::start()
|
||||
{
|
||||
static const string AdminArea = "^/api/admin?";
|
||||
|
||||
httpServer.resource[AdminArea]["POST"] = [this](auto response, auto request) {
|
||||
cout << request->method << endl;
|
||||
cout << request->path << endl;
|
||||
cout << request->http_version << endl;
|
||||
|
||||
for (auto &header : request->header)
|
||||
cout << header.first << ": " << header.second << endl;
|
||||
|
||||
string resp;
|
||||
master->luaStuff([&request, &response, &resp](sol::state &state) {
|
||||
sol::protected_function func = state["OnAdminRequest"];
|
||||
|
||||
sol::protected_function_result result = func.call(request->remote_endpoint_address, request->content.string());
|
||||
if (result.valid())
|
||||
*response << result.get<string>();
|
||||
else
|
||||
{
|
||||
cerr << "Error: " << result.get<string>() << endl;
|
||||
*response << response500;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/*httpServer.on_error = [](auto request, const boost::system::error_code& err)
|
||||
{
|
||||
std::cerr << "Error: " << err.message() << " " << err.category().name() << std::endl;
|
||||
};*/
|
||||
|
||||
httpServer.default_resource["GET"] = [](auto response, auto /*request*/) {
|
||||
cout << "Default request" << endl;
|
||||
*response << response400;
|
||||
};
|
||||
|
||||
thr = thread([this](){httpServer.start();});
|
||||
}
|
||||
|
||||
void AdminRest::stop()
|
||||
{
|
||||
httpServer.stop();
|
||||
if(thr.joinable())
|
||||
thr.join();
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by koncord on 04.09.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SimpleWeb/https_server.hpp"
|
||||
#include "MasterServer.hpp"
|
||||
|
||||
typedef SimpleWeb::Server<SimpleWeb::HTTPS> HttpsServer;
|
||||
|
||||
class AdminRest
|
||||
{
|
||||
public:
|
||||
AdminRest(const std::string &cert, const std::string &key, const std::string &verifyFile, unsigned short port, std::shared_ptr<MasterServer> master);
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
HttpsServer httpServer;
|
||||
std::shared_ptr<MasterServer> master;
|
||||
std::thread thr;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by koncord on 04.09.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "SimpleWeb/base_server.hpp"
|
||||
|
||||
static std::string response201 = "HTTP/1.1 201 Created\r\nContent-Length: 7\r\n\r\nCreated";
|
||||
static std::string response202 = "HTTP/1.1 202 Accepted\r\nContent-Length: 8\r\n\r\nAccepted";
|
||||
static std::string response400 = "HTTP/1.1 400 Bad Request\r\nContent-Length: 11\r\n\r\nbad request";
|
||||
|
||||
static std::string response403 = "HTTP/1.1 403 Forbidden\r\nContent-Length: 9\r\n\r\nForbidden";
|
||||
static std::string response500 = "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 21\r\n\r\nInternal Server Error";
|
||||
|
||||
template <class Protocol>
|
||||
inline void ResponseStr(std::shared_ptr<typename SimpleWeb::ServerBase<Protocol>::Response> response,
|
||||
std::string content, std::string type = "", std::string code = "200 OK")
|
||||
{
|
||||
*response << "HTTP/1.1 " << code << "\r\n";
|
||||
if (!type.empty())
|
||||
*response << "Content-Type: " << type <<"\r\n";
|
||||
*response << "Content-Length: " << content.length() << "\r\n\r\n" << content;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016 Ole Christian Eidheim
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,55 +1,42 @@
|
||||
/*
|
||||
* https://github.com/eidheim/Simple-Web-Server/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2014-2016 Ole Christian Eidheim
|
||||
*/
|
||||
|
||||
#ifndef SERVER_HTTP_HPP
|
||||
#define SERVER_HTTP_HPP
|
||||
#pragma once
|
||||
|
||||
#include "base_server.hpp"
|
||||
|
||||
namespace SimpleWeb
|
||||
{
|
||||
namespace SimpleWeb {
|
||||
|
||||
template<class socket_type>
|
||||
template <class socket_type>
|
||||
class Server : public ServerBase<socket_type> {};
|
||||
|
||||
typedef boost::asio::ip::tcp::socket HTTP;
|
||||
using HTTP = asio::ip::tcp::socket;
|
||||
|
||||
template<>
|
||||
class Server<HTTP> : public ServerBase<HTTP>
|
||||
{
|
||||
template <>
|
||||
class Server<HTTP> : public ServerBase<HTTP> {
|
||||
public:
|
||||
Server() : ServerBase<HTTP>::ServerBase(80)
|
||||
{}
|
||||
Server() noexcept : ServerBase<HTTP>::ServerBase(80) {}
|
||||
|
||||
protected:
|
||||
virtual void accept()
|
||||
{
|
||||
//Create new socket for this connection
|
||||
//Shared_ptr is used to pass temporary objects to the asynchronous functions
|
||||
auto socket = std::make_shared<HTTP>(*io_service);
|
||||
|
||||
acceptor->async_accept(*socket, [this, socket](const boost::system::error_code &ec)
|
||||
{
|
||||
//Immediately start accepting a new connection (if io_service hasn't been stopped)
|
||||
if (ec != boost::asio::error::operation_aborted)
|
||||
accept();
|
||||
|
||||
if (!ec)
|
||||
{
|
||||
boost::asio::ip::tcp::no_delay option(true);
|
||||
socket->set_option(option);
|
||||
|
||||
this->read_request_and_content(socket);
|
||||
void accept() override {
|
||||
auto session = std::make_shared<Session>(create_connection(*io_service));
|
||||
|
||||
acceptor->async_accept(*session->connection->socket, [this, session](const error_code &ec) {
|
||||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
|
||||
// Immediately start accepting a new connection (unless io_service has been stopped)
|
||||
if(ec != asio::error::operation_aborted)
|
||||
this->accept();
|
||||
|
||||
if(!ec) {
|
||||
asio::ip::tcp::no_delay option(true);
|
||||
error_code ec;
|
||||
session->connection->socket->set_option(option, ec);
|
||||
|
||||
this->read_request_and_content(session);
|
||||
}
|
||||
else if (on_error)
|
||||
on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //SERVER_HTTP_HPP
|
||||
} // namespace SimpleWeb
|
||||
|
@ -1,91 +1,82 @@
|
||||
#ifndef HTTPS_SERVER_HPP
|
||||
#define HTTPS_SERVER_HPP
|
||||
#pragma once
|
||||
|
||||
#include "base_server.hpp"
|
||||
|
||||
#ifdef USE_STANDALONE_ASIO
|
||||
#include <asio/ssl.hpp>
|
||||
#else
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace SimpleWeb
|
||||
{
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> HTTPS;
|
||||
namespace SimpleWeb {
|
||||
using HTTPS = asio::ssl::stream<asio::ip::tcp::socket>;
|
||||
|
||||
template<>
|
||||
class Server<HTTPS> : public ServerBase<HTTPS>
|
||||
{
|
||||
template <>
|
||||
class Server<HTTPS> : public ServerBase<HTTPS> {
|
||||
std::string session_id_context;
|
||||
bool set_session_id_context = false;
|
||||
|
||||
public:
|
||||
Server(const std::string &cert_file, const std::string &private_key_file,
|
||||
const std::string &verify_file = std::string()) : ServerBase<HTTPS>::ServerBase(443),
|
||||
context(boost::asio::ssl::context::tlsv12)
|
||||
{
|
||||
Server(const std::string &cert_file, const std::string &private_key_file, const std::string &verify_file = std::string())
|
||||
: ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {
|
||||
context.use_certificate_chain_file(cert_file);
|
||||
context.use_private_key_file(private_key_file, boost::asio::ssl::context::pem);
|
||||
context.use_private_key_file(private_key_file, asio::ssl::context::pem);
|
||||
|
||||
if (verify_file.size() > 0)
|
||||
{
|
||||
if(verify_file.size() > 0) {
|
||||
context.load_verify_file(verify_file);
|
||||
context.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert |
|
||||
boost::asio::ssl::verify_client_once);
|
||||
context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert | asio::ssl::verify_client_once);
|
||||
set_session_id_context = true;
|
||||
}
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
if (set_session_id_context)
|
||||
{
|
||||
void start() override {
|
||||
if(set_session_id_context) {
|
||||
// Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
|
||||
session_id_context = std::to_string(config.port) + ':';
|
||||
session_id_context.append(config.address.rbegin(), config.address.rend());
|
||||
SSL_CTX_set_session_id_context(context.native_handle(),
|
||||
reinterpret_cast<const unsigned char *>(session_id_context.data()),
|
||||
std::min<size_t>(session_id_context.size(),
|
||||
SSL_MAX_SSL_SESSION_ID_LENGTH));
|
||||
SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char *>(session_id_context.data()),
|
||||
std::min<size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));
|
||||
}
|
||||
ServerBase::start();
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::asio::ssl::context context;
|
||||
asio::ssl::context context;
|
||||
|
||||
virtual void accept()
|
||||
{
|
||||
//Create new socket for this connection
|
||||
//Shared_ptr is used to pass temporary objects to the asynchronous functions
|
||||
auto socket = std::make_shared<HTTPS>(*io_service, context);
|
||||
void accept() override {
|
||||
auto session = std::make_shared<Session>(create_connection(*io_service, context));
|
||||
|
||||
acceptor->async_accept((*socket).lowest_layer(), [this, socket](const boost::system::error_code &ec)
|
||||
{
|
||||
//Immediately start accepting a new connection (if io_service hasn't been stopped)
|
||||
if (ec != boost::asio::error::operation_aborted)
|
||||
accept();
|
||||
acceptor->async_accept(session->connection->socket->lowest_layer(), [this, session](const error_code &ec) {
|
||||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
|
||||
if(ec != asio::error::operation_aborted)
|
||||
this->accept();
|
||||
|
||||
if (!ec)
|
||||
{
|
||||
boost::asio::ip::tcp::no_delay option(true);
|
||||
socket->lowest_layer().set_option(option);
|
||||
if(!ec) {
|
||||
asio::ip::tcp::no_delay option(true);
|
||||
error_code ec;
|
||||
session->connection->socket->lowest_layer().set_option(option, ec);
|
||||
|
||||
//Set timeout on the following boost::asio::ssl::stream::async_handshake
|
||||
auto timer = get_timeout_timer(socket, config.timeout_request);
|
||||
socket->async_handshake(boost::asio::ssl::stream_base::server, [this, socket, timer]
|
||||
(const boost::system::error_code &ec)
|
||||
{
|
||||
if (timer)
|
||||
timer->cancel();
|
||||
if (!ec)
|
||||
read_request_and_content(socket);
|
||||
else if (on_error)
|
||||
on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
|
||||
session->connection->set_timeout(config.timeout_request);
|
||||
session->connection->socket->async_handshake(asio::ssl::stream_base::server, [this, session](const error_code &ec) {
|
||||
session->connection->cancel_timeout();
|
||||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if(!ec)
|
||||
this->read_request_and_content(session);
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
}
|
||||
else if (on_error)
|
||||
on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //HTTPS_SERVER_HPP
|
||||
} // namespace SimpleWeb
|
||||
|
@ -0,0 +1,154 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace SimpleWeb {
|
||||
enum class StatusCode {
|
||||
unknown = 0,
|
||||
information_continue = 100,
|
||||
information_switching_protocols,
|
||||
information_processing,
|
||||
success_ok = 200,
|
||||
success_created,
|
||||
success_accepted,
|
||||
success_non_authoritative_information,
|
||||
success_no_content,
|
||||
success_reset_content,
|
||||
success_partial_content,
|
||||
success_multi_status,
|
||||
success_already_reported,
|
||||
success_im_used = 226,
|
||||
redirection_multiple_choices = 300,
|
||||
redirection_moved_permanently,
|
||||
redirection_found,
|
||||
redirection_see_other,
|
||||
redirection_not_modified,
|
||||
redirection_use_proxy,
|
||||
redirection_switch_proxy,
|
||||
redirection_temporary_redirect,
|
||||
redirection_permanent_redirect,
|
||||
client_error_bad_request = 400,
|
||||
client_error_unauthorized,
|
||||
client_error_payment_required,
|
||||
client_error_forbidden,
|
||||
client_error_not_found,
|
||||
client_error_method_not_allowed,
|
||||
client_error_not_acceptable,
|
||||
client_error_proxy_authentication_required,
|
||||
client_error_request_timeout,
|
||||
client_error_conflict,
|
||||
client_error_gone,
|
||||
client_error_length_required,
|
||||
client_error_precondition_failed,
|
||||
client_error_payload_too_large,
|
||||
client_error_uri_too_long,
|
||||
client_error_unsupported_media_type,
|
||||
client_error_range_not_satisfiable,
|
||||
client_error_expectation_failed,
|
||||
client_error_im_a_teapot,
|
||||
client_error_misdirection_required = 421,
|
||||
client_error_unprocessable_entity,
|
||||
client_error_locked,
|
||||
client_error_failed_dependency,
|
||||
client_error_upgrade_required = 426,
|
||||
client_error_precondition_required = 428,
|
||||
client_error_too_many_requests,
|
||||
client_error_request_header_fields_too_large = 431,
|
||||
client_error_unavailable_for_legal_reasons = 451,
|
||||
server_error_internal_server_error = 500,
|
||||
server_error_not_implemented,
|
||||
server_error_bad_gateway,
|
||||
server_error_service_unavailable,
|
||||
server_error_gateway_timeout,
|
||||
server_error_http_version_not_supported,
|
||||
server_error_variant_also_negotiates,
|
||||
server_error_insufficient_storage,
|
||||
server_error_loop_detected,
|
||||
server_error_not_extended = 510,
|
||||
server_error_network_authentication_required
|
||||
};
|
||||
|
||||
const static std::vector<std::pair<StatusCode, std::string>> &status_codes() noexcept {
|
||||
const static std::vector<std::pair<StatusCode, std::string>> status_codes = {
|
||||
{StatusCode::unknown, ""},
|
||||
{StatusCode::information_continue, "100 Continue"},
|
||||
{StatusCode::information_switching_protocols, "101 Switching Protocols"},
|
||||
{StatusCode::information_processing, "102 Processing"},
|
||||
{StatusCode::success_ok, "200 OK"},
|
||||
{StatusCode::success_created, "201 Created"},
|
||||
{StatusCode::success_accepted, "202 Accepted"},
|
||||
{StatusCode::success_non_authoritative_information, "203 Non-Authoritative Information"},
|
||||
{StatusCode::success_no_content, "204 No Content"},
|
||||
{StatusCode::success_reset_content, "205 Reset Content"},
|
||||
{StatusCode::success_partial_content, "206 Partial Content"},
|
||||
{StatusCode::success_multi_status, "207 Multi-Status"},
|
||||
{StatusCode::success_already_reported, "208 Already Reported"},
|
||||
{StatusCode::success_im_used, "226 IM Used"},
|
||||
{StatusCode::redirection_multiple_choices, "300 Multiple Choices"},
|
||||
{StatusCode::redirection_moved_permanently, "301 Moved Permanently"},
|
||||
{StatusCode::redirection_found, "302 Found"},
|
||||
{StatusCode::redirection_see_other, "303 See Other"},
|
||||
{StatusCode::redirection_not_modified, "304 Not Modified"},
|
||||
{StatusCode::redirection_use_proxy, "305 Use Proxy"},
|
||||
{StatusCode::redirection_switch_proxy, "306 Switch Proxy"},
|
||||
{StatusCode::redirection_temporary_redirect, "307 Temporary Redirect"},
|
||||
{StatusCode::redirection_permanent_redirect, "308 Permanent Redirect"},
|
||||
{StatusCode::client_error_bad_request, "400 Bad Request"},
|
||||
{StatusCode::client_error_unauthorized, "401 Unauthorized"},
|
||||
{StatusCode::client_error_payment_required, "402 Payment Required"},
|
||||
{StatusCode::client_error_forbidden, "403 Forbidden"},
|
||||
{StatusCode::client_error_not_found, "404 Not Found"},
|
||||
{StatusCode::client_error_method_not_allowed, "405 Method Not Allowed"},
|
||||
{StatusCode::client_error_not_acceptable, "406 Not Acceptable"},
|
||||
{StatusCode::client_error_proxy_authentication_required, "407 Proxy Authentication Required"},
|
||||
{StatusCode::client_error_request_timeout, "408 Request Timeout"},
|
||||
{StatusCode::client_error_conflict, "409 Conflict"},
|
||||
{StatusCode::client_error_gone, "410 Gone"},
|
||||
{StatusCode::client_error_length_required, "411 Length Required"},
|
||||
{StatusCode::client_error_precondition_failed, "412 Precondition Failed"},
|
||||
{StatusCode::client_error_payload_too_large, "413 Payload Too Large"},
|
||||
{StatusCode::client_error_uri_too_long, "414 URI Too Long"},
|
||||
{StatusCode::client_error_unsupported_media_type, "415 Unsupported Media Type"},
|
||||
{StatusCode::client_error_range_not_satisfiable, "416 Range Not Satisfiable"},
|
||||
{StatusCode::client_error_expectation_failed, "417 Expectation Failed"},
|
||||
{StatusCode::client_error_im_a_teapot, "418 I'm a teapot"},
|
||||
{StatusCode::client_error_misdirection_required, "421 Misdirected Request"},
|
||||
{StatusCode::client_error_unprocessable_entity, "422 Unprocessable Entity"},
|
||||
{StatusCode::client_error_locked, "423 Locked"},
|
||||
{StatusCode::client_error_failed_dependency, "424 Failed Dependency"},
|
||||
{StatusCode::client_error_upgrade_required, "426 Upgrade Required"},
|
||||
{StatusCode::client_error_precondition_required, "428 Precondition Required"},
|
||||
{StatusCode::client_error_too_many_requests, "429 Too Many Requests"},
|
||||
{StatusCode::client_error_request_header_fields_too_large, "431 Request Header Fields Too Large"},
|
||||
{StatusCode::client_error_unavailable_for_legal_reasons, "451 Unavailable For Legal Reasons"},
|
||||
{StatusCode::server_error_internal_server_error, "500 Internal Server Error"},
|
||||
{StatusCode::server_error_not_implemented, "501 Not Implemented"},
|
||||
{StatusCode::server_error_bad_gateway, "502 Bad Gateway"},
|
||||
{StatusCode::server_error_service_unavailable, "503 Service Unavailable"},
|
||||
{StatusCode::server_error_gateway_timeout, "504 Gateway Timeout"},
|
||||
{StatusCode::server_error_http_version_not_supported, "505 HTTP Version Not Supported"},
|
||||
{StatusCode::server_error_variant_also_negotiates, "506 Variant Also Negotiates"},
|
||||
{StatusCode::server_error_insufficient_storage, "507 Insufficient Storage"},
|
||||
{StatusCode::server_error_loop_detected, "508 Loop Detected"},
|
||||
{StatusCode::server_error_not_extended, "510 Not Extended"},
|
||||
{StatusCode::server_error_network_authentication_required, "511 Network Authentication Required"}};
|
||||
return status_codes;
|
||||
}
|
||||
|
||||
inline StatusCode status_code(const std::string &status_code_str) noexcept {
|
||||
for(auto &status_code : status_codes()) {
|
||||
if(status_code.second == status_code_str)
|
||||
return status_code.first;
|
||||
}
|
||||
return StatusCode::unknown;
|
||||
}
|
||||
|
||||
inline const std::string &status_code(StatusCode status_code_enum) noexcept {
|
||||
for(auto &status_code : status_codes()) {
|
||||
if(status_code.first == status_code_enum)
|
||||
return status_code.second;
|
||||
}
|
||||
return status_codes()[0].second;
|
||||
}
|
||||
} // namespace SimpleWeb
|
@ -0,0 +1,340 @@
|
||||
#pragma once
|
||||
|
||||
#include "status_code.hpp"
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace SimpleWeb {
|
||||
inline bool case_insensitive_equal(const std::string &str1, const std::string &str2) noexcept {
|
||||
return str1.size() == str2.size() &&
|
||||
std::equal(str1.begin(), str1.end(), str2.begin(), [](char a, char b) {
|
||||
return tolower(a) == tolower(b);
|
||||
});
|
||||
}
|
||||
class CaseInsensitiveEqual {
|
||||
public:
|
||||
bool operator()(const std::string &str1, const std::string &str2) const noexcept {
|
||||
return case_insensitive_equal(str1, str2);
|
||||
}
|
||||
};
|
||||
// Based on https://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x/2595226#2595226
|
||||
class CaseInsensitiveHash {
|
||||
public:
|
||||
size_t operator()(const std::string &str) const noexcept {
|
||||
size_t h = 0;
|
||||
std::hash<int> hash;
|
||||
for(auto c : str)
|
||||
h ^= hash(tolower(c)) + 0x9e3779b9 + (h << 6) + (h >> 2);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
using CaseInsensitiveMultimap = std::unordered_multimap<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual>;
|
||||
|
||||
/// Percent encoding and decoding
|
||||
class Percent {
|
||||
public:
|
||||
/// Returns percent-encoded string
|
||||
static std::string encode(const std::string &value) noexcept {
|
||||
static auto hex_chars = "0123456789ABCDEF";
|
||||
|
||||
std::string result;
|
||||
result.reserve(value.size()); // Minimum size of result
|
||||
|
||||
for(auto &chr : value) {
|
||||
if(chr == ' ')
|
||||
result += '+';
|
||||
else if(chr == '!' || chr == '#' || chr == '$' || (chr >= '&' && chr <= ',') || (chr >= '/' && chr <= ';') || chr == '=' || chr == '?' || chr == '@' || chr == '[' || chr == ']')
|
||||
result += std::string("%") + hex_chars[chr >> 4] + hex_chars[chr & 15];
|
||||
else
|
||||
result += chr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns percent-decoded string
|
||||
static std::string decode(const std::string &value) noexcept {
|
||||
std::string result;
|
||||
result.reserve(value.size() / 3 + (value.size() % 3)); // Minimum size of result
|
||||
|
||||
for(size_t i = 0; i < value.size(); ++i) {
|
||||
auto &chr = value[i];
|
||||
if(chr == '%' && i + 2 < value.size()) {
|
||||
auto hex = value.substr(i + 1, 2);
|
||||
auto decoded_chr = static_cast<char>(std::strtol(hex.c_str(), nullptr, 16));
|
||||
result += decoded_chr;
|
||||
i += 2;
|
||||
}
|
||||
else if(chr == '+')
|
||||
result += ' ';
|
||||
else
|
||||
result += chr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// Query string creation and parsing
|
||||
class QueryString {
|
||||
public:
|
||||
/// Returns query string created from given field names and values
|
||||
static std::string create(const CaseInsensitiveMultimap &fields) noexcept {
|
||||
std::string result;
|
||||
|
||||
bool first = true;
|
||||
for(auto &field : fields) {
|
||||
result += (!first ? "&" : "") + field.first + '=' + Percent::encode(field.second);
|
||||
first = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns query keys with percent-decoded values.
|
||||
static CaseInsensitiveMultimap parse(const std::string &query_string) noexcept {
|
||||
CaseInsensitiveMultimap result;
|
||||
|
||||
if(query_string.empty())
|
||||
return result;
|
||||
|
||||
size_t name_pos = 0;
|
||||
auto name_end_pos = std::string::npos;
|
||||
auto value_pos = std::string::npos;
|
||||
for(size_t c = 0; c < query_string.size(); ++c) {
|
||||
if(query_string[c] == '&') {
|
||||
auto name = query_string.substr(name_pos, (name_end_pos == std::string::npos ? c : name_end_pos) - name_pos);
|
||||
if(!name.empty()) {
|
||||
auto value = value_pos == std::string::npos ? std::string() : query_string.substr(value_pos, c - value_pos);
|
||||
result.emplace(std::move(name), Percent::decode(value));
|
||||
}
|
||||
name_pos = c + 1;
|
||||
name_end_pos = std::string::npos;
|
||||
value_pos = std::string::npos;
|
||||
}
|
||||
else if(query_string[c] == '=') {
|
||||
name_end_pos = c;
|
||||
value_pos = c + 1;
|
||||
}
|
||||
}
|
||||
if(name_pos < query_string.size()) {
|
||||
auto name = query_string.substr(name_pos, name_end_pos - name_pos);
|
||||
if(!name.empty()) {
|
||||
auto value = value_pos >= query_string.size() ? std::string() : query_string.substr(value_pos);
|
||||
result.emplace(std::move(name), Percent::decode(value));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class HttpHeader {
|
||||
public:
|
||||
/// Parse header fields
|
||||
static CaseInsensitiveMultimap parse(std::istream &stream) noexcept {
|
||||
CaseInsensitiveMultimap result;
|
||||
std::string line;
|
||||
getline(stream, line);
|
||||
size_t param_end;
|
||||
while((param_end = line.find(':')) != std::string::npos) {
|
||||
size_t value_start = param_end + 1;
|
||||
if(value_start < line.size()) {
|
||||
if(line[value_start] == ' ')
|
||||
value_start++;
|
||||
if(value_start < line.size())
|
||||
result.emplace(line.substr(0, param_end), line.substr(value_start, line.size() - value_start - 1));
|
||||
}
|
||||
|
||||
getline(stream, line);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class RequestMessage {
|
||||
public:
|
||||
/// Parse request line and header fields
|
||||
static bool parse(std::istream &stream, std::string &method, std::string &path, std::string &query_string, std::string &version, CaseInsensitiveMultimap &header) noexcept {
|
||||
header.clear();
|
||||
std::string line;
|
||||
getline(stream, line);
|
||||
size_t method_end;
|
||||
if((method_end = line.find(' ')) != std::string::npos) {
|
||||
method = line.substr(0, method_end);
|
||||
|
||||
size_t query_start = std::string::npos;
|
||||
size_t path_and_query_string_end = std::string::npos;
|
||||
for(size_t i = method_end + 1; i < line.size(); ++i) {
|
||||
if(line[i] == '?' && (i + 1) < line.size())
|
||||
query_start = i + 1;
|
||||
else if(line[i] == ' ') {
|
||||
path_and_query_string_end = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(path_and_query_string_end != std::string::npos) {
|
||||
if(query_start != std::string::npos) {
|
||||
path = line.substr(method_end + 1, query_start - method_end - 2);
|
||||
query_string = line.substr(query_start, path_and_query_string_end - query_start);
|
||||
}
|
||||
else
|
||||
path = line.substr(method_end + 1, path_and_query_string_end - method_end - 1);
|
||||
|
||||
size_t protocol_end;
|
||||
if((protocol_end = line.find('/', path_and_query_string_end + 1)) != std::string::npos) {
|
||||
if(line.compare(path_and_query_string_end + 1, protocol_end - path_and_query_string_end - 1, "HTTP") != 0)
|
||||
return false;
|
||||
version = line.substr(protocol_end + 1, line.size() - protocol_end - 2);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
header = HttpHeader::parse(stream);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ResponseMessage {
|
||||
public:
|
||||
/// Parse status line and header fields
|
||||
static bool parse(std::istream &stream, std::string &version, std::string &status_code, CaseInsensitiveMultimap &header) noexcept {
|
||||
header.clear();
|
||||
std::string line;
|
||||
getline(stream, line);
|
||||
size_t version_end = line.find(' ');
|
||||
if(version_end != std::string::npos) {
|
||||
if(5 < line.size())
|
||||
version = line.substr(5, version_end - 5);
|
||||
else
|
||||
return false;
|
||||
if((version_end + 1) < line.size())
|
||||
status_code = line.substr(version_end + 1, line.size() - (version_end + 1) - 1);
|
||||
else
|
||||
return false;
|
||||
|
||||
header = HttpHeader::parse(stream);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ContentDisposition {
|
||||
public:
|
||||
/// Can be used to parse the Content-Disposition header field value when
|
||||
/// clients are posting requests with enctype="multipart/form-data"
|
||||
static CaseInsensitiveMultimap parse(const std::string &line) {
|
||||
CaseInsensitiveMultimap result;
|
||||
|
||||
size_t para_start_pos = 0;
|
||||
size_t para_end_pos = std::string::npos;
|
||||
size_t value_start_pos = std::string::npos;
|
||||
for(size_t c = 0; c < line.size(); ++c) {
|
||||
if(para_start_pos != std::string::npos) {
|
||||
if(para_end_pos == std::string::npos) {
|
||||
if(line[c] == ';') {
|
||||
result.emplace(line.substr(para_start_pos, c - para_start_pos), std::string());
|
||||
para_start_pos = std::string::npos;
|
||||
}
|
||||
else if(line[c] == '=')
|
||||
para_end_pos = c;
|
||||
}
|
||||
else {
|
||||
if(value_start_pos == std::string::npos) {
|
||||
if(line[c] == '"' && c + 1 < line.size())
|
||||
value_start_pos = c + 1;
|
||||
}
|
||||
else if(line[c] == '"') {
|
||||
result.emplace(line.substr(para_start_pos, para_end_pos - para_start_pos), line.substr(value_start_pos, c - value_start_pos));
|
||||
para_start_pos = std::string::npos;
|
||||
para_end_pos = std::string::npos;
|
||||
value_start_pos = std::string::npos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(line[c] != ' ' && line[c] != ';')
|
||||
para_start_pos = c;
|
||||
}
|
||||
if(para_start_pos != std::string::npos && para_end_pos == std::string::npos)
|
||||
result.emplace(line.substr(para_start_pos), std::string());
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} // namespace SimpleWeb
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
namespace SimpleWeb {
|
||||
inline void spin_loop_pause() noexcept { _mm_pause(); }
|
||||
} // namespace SimpleWeb
|
||||
// TODO: need verification that the following checks are correct:
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1800 && (defined(_M_X64) || defined(_M_IX86))
|
||||
#include <intrin.h>
|
||||
namespace SimpleWeb {
|
||||
inline void spin_loop_pause() noexcept { _mm_pause(); }
|
||||
} // namespace SimpleWeb
|
||||
#else
|
||||
namespace SimpleWeb {
|
||||
inline void spin_loop_pause() noexcept {}
|
||||
} // namespace SimpleWeb
|
||||
#endif
|
||||
|
||||
namespace SimpleWeb {
|
||||
/// Makes it possible to for instance cancel Asio handlers without stopping asio::io_service
|
||||
class ScopeRunner {
|
||||
/// Scope count that is set to -1 if scopes are to be canceled
|
||||
std::atomic<long> count;
|
||||
|
||||
public:
|
||||
class SharedLock {
|
||||
friend class ScopeRunner;
|
||||
std::atomic<long> &count;
|
||||
SharedLock(std::atomic<long> &count) noexcept : count(count) {}
|
||||
SharedLock &operator=(const SharedLock &) = delete;
|
||||
SharedLock(const SharedLock &) = delete;
|
||||
|
||||
public:
|
||||
~SharedLock() noexcept {
|
||||
count.fetch_sub(1);
|
||||
}
|
||||
};
|
||||
|
||||
ScopeRunner() noexcept : count(0) {}
|
||||
|
||||
/// Returns nullptr if scope should be exited, or a shared lock otherwise
|
||||
std::unique_ptr<SharedLock> continue_lock() noexcept {
|
||||
long expected = count;
|
||||
while(expected >= 0 && !count.compare_exchange_weak(expected, expected + 1))
|
||||
spin_loop_pause();
|
||||
|
||||
if(expected < 0)
|
||||
return nullptr;
|
||||
else
|
||||
return std::unique_ptr<SharedLock>(new SharedLock(count));
|
||||
}
|
||||
|
||||
/// Blocks until all shared locks are released, then prevents future shared locks
|
||||
void stop() noexcept {
|
||||
long expected = 0;
|
||||
while(!count.compare_exchange_weak(expected, -1)) {
|
||||
if(expected < 0)
|
||||
return;
|
||||
expected = 0;
|
||||
spin_loop_pause();
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace SimpleWeb
|
@ -0,0 +1,281 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Actors.hpp"
|
||||
#include "Cell.hpp"
|
||||
#include "CellController.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Actor::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Actor>("Actor",
|
||||
"getPosition", &NetActor::getPosition,
|
||||
"setPosition", &NetActor::setPosition,
|
||||
"getRotation", &NetActor::getRotation,
|
||||
"setRotation", &NetActor::setRotation,
|
||||
|
||||
"getHealth", &NetActor::getHealth,
|
||||
"setHealth", &NetActor::setHealth,
|
||||
"getMagicka", &NetActor::getMagicka,
|
||||
"setMagicka", &NetActor::setMagicka,
|
||||
"getFatigue", &NetActor::getFatigue,
|
||||
"setFatigue", &NetActor::setFatigue,
|
||||
|
||||
"getCell", &NetActor::getCell,
|
||||
"getInventory", &NetActor::getInventory,
|
||||
|
||||
"refId", sol::property(&Actor::getRefId, &Actor::setRefId),
|
||||
"refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex),
|
||||
"mpNum", sol::property(&Actor::getMpNum, &Actor::setMpNum)
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Actor::Actor() : NetActor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Actor::getRefId() const
|
||||
{
|
||||
return actor->refId;
|
||||
}
|
||||
|
||||
void Actor::setRefId(const std::string &refId)
|
||||
{
|
||||
actor->refId = refId;
|
||||
}
|
||||
|
||||
int Actor::getRefNumIndex() const
|
||||
{
|
||||
return actor->refNumIndex;
|
||||
}
|
||||
|
||||
void Actor::setRefNumIndex(int refNumIndex)
|
||||
{
|
||||
actor->refNumIndex = refNumIndex;
|
||||
}
|
||||
|
||||
int Actor::getMpNum() const
|
||||
{
|
||||
return actor->mpNum;
|
||||
}
|
||||
|
||||
void Actor::setMpNum(int mpNum)
|
||||
{
|
||||
actor->mpNum = mpNum;
|
||||
}
|
||||
|
||||
bool Actor::doesHavePosition() const
|
||||
{
|
||||
return actor->hasPositionData;
|
||||
}
|
||||
|
||||
bool Actor::doesHaveStatsDynamic() const
|
||||
{
|
||||
return actor->hasStatsDynamicData;
|
||||
}
|
||||
|
||||
void ActorController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table playersTable = lua.getState()->create_named_table("Actors");
|
||||
|
||||
playersTable.set_function("createActor", [&lua](){
|
||||
return lua.getActorCtrl().createActor();
|
||||
});
|
||||
|
||||
playersTable.set_function("sendActors", [&lua](shared_ptr<Player> player, vector<shared_ptr<Actor>> actors,
|
||||
const std::string &cellDescription, bool sendToAll) {
|
||||
lua.getActorCtrl().sendActors(player, actors, Utils::getCellFromDescription(cellDescription), sendToAll);
|
||||
});
|
||||
|
||||
playersTable.set_function("sendList", [&lua](shared_ptr<Player> player, vector<shared_ptr<Actor>> actors,
|
||||
const std::string &cellDescription, bool sendToAll) {
|
||||
lua.getActorCtrl().sendList(player, actors, Utils::getCellFromDescription(cellDescription), sendToAll);
|
||||
});
|
||||
|
||||
playersTable.set_function("requestList", [&lua](shared_ptr<Player> player, const std::string &cellDescription){
|
||||
lua.getActorCtrl().requestList(player, Utils::getCellFromDescription(cellDescription));
|
||||
});
|
||||
|
||||
playersTable.set_function("getActors", [&lua](shared_ptr<Player> player, const std::string &cellDescription){
|
||||
lua.getActorCtrl().getActors(player, Utils::getCellFromDescription(cellDescription));
|
||||
});
|
||||
}
|
||||
|
||||
ActorController::ActorController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ActorController::~ActorController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Actor> ActorController::createActor()
|
||||
{
|
||||
Actor *actor = new Actor();
|
||||
actor->actor.reset(new mwmp::BaseActor);
|
||||
|
||||
return shared_ptr<Actor>(actor);
|
||||
}
|
||||
|
||||
void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors,
|
||||
const ESM::Cell &cell, bool sendToAll)
|
||||
{
|
||||
actorList.cell = cell;
|
||||
actorList.guid = player->guid;
|
||||
|
||||
bool positionChanged = false;
|
||||
bool statsChanged = false;
|
||||
/*bool attributesChanged = false;
|
||||
bool skillsChanged = false;
|
||||
bool baseInfoChanged = false;*/
|
||||
bool equipmentChanged = false;
|
||||
bool changedCell = false;
|
||||
|
||||
actorList.baseActors.clear();
|
||||
for (auto &actor : actors)
|
||||
{
|
||||
actorList.baseActors.push_back(actor->actor);
|
||||
|
||||
if (actor->positionChanged)
|
||||
positionChanged = true;
|
||||
if (actor->statsChanged)
|
||||
statsChanged = true;
|
||||
/*if (actor->attributesChanged)
|
||||
attributesChanged = true;
|
||||
if (actor->skillsChanged)
|
||||
skillsChanged = true;
|
||||
if (actor->baseInfoChanged)
|
||||
baseInfoChanged = true;*/
|
||||
if (actor->inventory.isEquipmentChanged())
|
||||
{
|
||||
equipmentChanged = true;
|
||||
actor->inventory.resetEquipmentFlag();
|
||||
}
|
||||
if (actor->cellAPI.isChangedCell())
|
||||
{
|
||||
changedCell = true;
|
||||
actor->cellAPI.resetChangedCell();
|
||||
}
|
||||
actor->resetUpdateFlags();
|
||||
}
|
||||
|
||||
auto actorCtrl = mwmp::Networking::get().getActorPacketController();
|
||||
Cell *serverCell = nullptr;
|
||||
|
||||
if (sendToAll)
|
||||
serverCell = CellController::get()->getCell(&actorList.cell);
|
||||
|
||||
if (positionChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (statsChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_STATS_DYNAMIC);
|
||||
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
|
||||
}
|
||||
/*if (attributesChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}
|
||||
if (skillsChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}
|
||||
if (baseInfoChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}*/
|
||||
|
||||
if (equipmentChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_EQUIPMENT);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (changedCell)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorController::sendList(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors,
|
||||
const ESM::Cell &cell, bool sendToAll)
|
||||
{
|
||||
actorList.cell = player->cell;
|
||||
actorList.guid = player->guid;
|
||||
actorList.action = mwmp::BaseActorList::SET;
|
||||
|
||||
for (auto &actor : actors)
|
||||
{
|
||||
actorList.baseActors.push_back(actor->actor);
|
||||
}
|
||||
|
||||
auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
if (sendToAll)
|
||||
CellController::get()->getCell(&actorList.cell)->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
|
||||
void ActorController::requestList(std::shared_ptr<Player> player, const ESM::Cell &cell)
|
||||
{
|
||||
actorList.cell = player->cell;
|
||||
actorList.guid = player->guid;
|
||||
actorList.action = mwmp::BaseActorList::REQUEST;
|
||||
|
||||
auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> ActorController::getActors(std::shared_ptr<Player> player, const ESM::Cell &cell)
|
||||
{
|
||||
Cell *serverCell = CellController::get()->getCell(&player->cell);
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> actorList;
|
||||
|
||||
for (auto actor : serverCell->getActorList()->baseActors)
|
||||
{
|
||||
Actor *a = new Actor;
|
||||
a->actor = actor;
|
||||
actorList.emplace_back(a);
|
||||
}
|
||||
|
||||
return actorList;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BaseActor.hpp>
|
||||
#include "NetActor.hpp"
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Actor: public NetActor
|
||||
{
|
||||
friend class ActorController;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Actor();
|
||||
std::string getRefId() const;
|
||||
void setRefId(const std::string &refId);
|
||||
|
||||
int getRefNumIndex() const;
|
||||
void setRefNumIndex(int refNumIndex);
|
||||
int getMpNum() const;
|
||||
void setMpNum(int mpNum);
|
||||
bool doesHavePosition() const; // ????
|
||||
bool doesHaveStatsDynamic() const; // ????
|
||||
|
||||
std::shared_ptr<mwmp::BaseActor> actor;
|
||||
};
|
||||
|
||||
class ActorController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
ActorController();
|
||||
~ActorController();
|
||||
|
||||
std::shared_ptr<Actor> createActor();
|
||||
void sendActors(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, const ESM::Cell &cell, bool sendToAll = false);
|
||||
void sendList(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, const ESM::Cell &cell, bool sendToAll = false);
|
||||
|
||||
void requestList(std::shared_ptr<Player> player, const ESM::Cell &cell);
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> getActors(std::shared_ptr<Player> player, const ESM::Cell &cell);
|
||||
|
||||
private:
|
||||
mwmp::BaseActorList actorList;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Books.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
void Books::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Books>("Books",
|
||||
"addBook", &Books::addBook,
|
||||
"getBookId", &Books::getBookId,
|
||||
"getChanges", &Books::getChanges,
|
||||
"reset", &Books::reset
|
||||
);
|
||||
}
|
||||
|
||||
Books::Books(Player *player) : player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Books::~Books()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Books::addBook(const std::string &bookId)
|
||||
{
|
||||
if (!changed)
|
||||
reset();
|
||||
player->bookChanges.books.push_back({bookId});
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::string Books::getBookId(unsigned i) const
|
||||
{
|
||||
if (i >= player->bookChanges.books.size())
|
||||
return "invalid";
|
||||
|
||||
return player->bookChanges.books.at(i).bookId;
|
||||
}
|
||||
|
||||
unsigned Books::getChanges() const
|
||||
{
|
||||
return player->bookChanges.books.size();
|
||||
}
|
||||
|
||||
void Books::reset()
|
||||
{
|
||||
player->bookChanges.books.clear();
|
||||
}
|
||||
|
||||
void Books::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Books
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
explicit Books(Player *player);
|
||||
~Books();
|
||||
|
||||
void addBook(const std::string &bookId);
|
||||
std::string getBookId(unsigned i) const;
|
||||
unsigned getChanges() const;
|
||||
void reset();
|
||||
|
||||
void update();
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
|
||||
#include "CellState.hpp"
|
||||
|
||||
void CellState::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<CellState>("CellState",
|
||||
"type", sol::property(&CellState::getStateType),
|
||||
"description", sol::property(&CellState::getDescription)
|
||||
);
|
||||
}
|
||||
|
||||
CellState::CellState(mwmp::CellState state) : state(state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CellState::getStateType() const
|
||||
{
|
||||
return state.type;
|
||||
}
|
||||
|
||||
std::string CellState::getDescription() const
|
||||
{
|
||||
return state.cell.getDescription();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
|
||||
class CellState
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
|
||||
explicit CellState(mwmp::CellState state);
|
||||
public:
|
||||
int getStateType() const;
|
||||
std::string getDescription() const;
|
||||
|
||||
private:
|
||||
mwmp::CellState state;
|
||||
};
|
@ -0,0 +1,100 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Cells.hpp"
|
||||
#include "NetActor.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Cells::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Cells>("Cell",
|
||||
"description", sol::property(&Cells::getDescription, &Cells::setDescription),
|
||||
"getExterior", &Cells::getExterior,
|
||||
"setExterior", &Cells::setExterior,
|
||||
"getRegion", &Cells::getRegion,
|
||||
|
||||
"isExterior", &Cells::isExterior,
|
||||
"isChangingRegion", &Cells::isChangingRegion
|
||||
);
|
||||
}
|
||||
|
||||
Cells::Cells(NetActor *netActor) : netActor(netActor), changedCell(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Cells::~Cells()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cells::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Cells::getDescription() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.getDescription();
|
||||
}
|
||||
|
||||
void Cells::setDescription(const std::string &cellDescription)
|
||||
{
|
||||
/*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %s", netActor->getNetCreature()->npc.mName.c_str(),
|
||||
netActor->getNetCreature()->cell.getDescription().c_str(), cellDescription.c_str());*/
|
||||
|
||||
netActor->getNetCreature()->cell = Utils::getCellFromDescription(cellDescription);
|
||||
changedCell = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int> Cells::getExterior() const
|
||||
{
|
||||
return make_tuple(netActor->getNetCreature()->cell.mData.mX, netActor->getNetCreature()->cell.mData.mY);
|
||||
}
|
||||
|
||||
void Cells::setExterior(int x, int y)
|
||||
{
|
||||
/*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %i,%i", netActor->getNetCreature()->npc.mName.c_str(),
|
||||
netActor->getNetCreature()->cell.getDescription().c_str(), x, y);*/
|
||||
|
||||
// If the player is currently in an interior, turn off the interior flag from the cell
|
||||
if (!netActor->getNetCreature()->cell.isExterior())
|
||||
netActor->getNetCreature()->cell.mData.mFlags &= ~ESM::Cell::Interior;
|
||||
|
||||
netActor->getNetCreature()->cell.mData.mX = x;
|
||||
netActor->getNetCreature()->cell.mData.mY = y;
|
||||
changedCell = true;
|
||||
}
|
||||
|
||||
bool Cells::isExterior() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.isExterior();
|
||||
}
|
||||
|
||||
bool Cells::isChangingRegion() const
|
||||
{
|
||||
return netActor->getNetCreature()->isChangingRegion;
|
||||
}
|
||||
|
||||
std::string Cells::getRegion() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.mRegion;
|
||||
}
|
||||
|
||||
bool Cells::isChangedCell() const
|
||||
{
|
||||
return changedCell;
|
||||
}
|
||||
|
||||
void Cells::resetChangedCell()
|
||||
{
|
||||
changedCell = false;
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class NetActor;
|
||||
|
||||
class Cells
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Cells(NetActor *netActor);
|
||||
~Cells();
|
||||
|
||||
void update();
|
||||
|
||||
std::string getDescription() const;
|
||||
void setDescription(const std::string &cellDescription);
|
||||
|
||||
std::tuple<int, int> getExterior() const;
|
||||
void setExterior(int x, int y);
|
||||
|
||||
bool isExterior() const;
|
||||
bool isChangingRegion() const;
|
||||
|
||||
std::string getRegion() const;
|
||||
|
||||
bool isChangedCell() const;
|
||||
void resetChangedCell();
|
||||
|
||||
private:
|
||||
NetActor *netActor;
|
||||
bool changedCell;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,156 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "CharClass.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CharClass::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<CharClass>("Class",
|
||||
//"__gc", sol::destructor(deleter),
|
||||
"default", sol::property(&CharClass::getDefault, &CharClass::setDefault),
|
||||
"isCustom", &CharClass::isCustom,
|
||||
|
||||
"name", sol::property(&CharClass::getName, &CharClass::setName),
|
||||
"description", sol::property(&CharClass::getDescription, &CharClass::setDescription),
|
||||
"specialization",
|
||||
sol::property(&CharClass::getSpecialization, &CharClass::setSpecialization),
|
||||
|
||||
"getMajorAttributes", &CharClass::getMajorAttributes,
|
||||
"setMajorAttributes", &CharClass::setMajorAttributes,
|
||||
|
||||
"getMinorSkills", &CharClass::getMinorSkills,
|
||||
"setMinorSkills", &CharClass::setMinorSkills,
|
||||
|
||||
"getMajorSkills", &CharClass::getMajorSkills,
|
||||
"setMajorSkills", &CharClass::setMajorSkills
|
||||
);
|
||||
}
|
||||
|
||||
CharClass::CharClass(Player *player) : player(player), changed(false)
|
||||
{
|
||||
printf("CharClass::CharClass()\n");
|
||||
}
|
||||
|
||||
CharClass::~CharClass()
|
||||
{
|
||||
printf("CharClass::~CharClass()\n");
|
||||
}
|
||||
|
||||
string CharClass::getDefault() const
|
||||
{
|
||||
return player->charClass.mId;
|
||||
}
|
||||
|
||||
void CharClass::setDefault(const string &className)
|
||||
{
|
||||
player->charClass.mId = className;
|
||||
changed = true;
|
||||
printf("CharClass::setDefault()\n");
|
||||
}
|
||||
|
||||
bool CharClass::isCustom() const
|
||||
{
|
||||
return player->charClass.mId.empty();
|
||||
}
|
||||
|
||||
void CharClass::setName(const string &className)
|
||||
{
|
||||
player->charClass.mName = className;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
string CharClass::getName() const
|
||||
{
|
||||
return player->charClass.mName;
|
||||
}
|
||||
|
||||
std::string CharClass::getDescription() const
|
||||
{
|
||||
return player->charClass.mDescription;
|
||||
}
|
||||
|
||||
void CharClass::setDescription(const string &desc)
|
||||
{
|
||||
player->charClass.mDescription = desc;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int> CharClass::getMajorAttributes() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple(data.mAttribute[0], data.mAttribute[1]);
|
||||
}
|
||||
|
||||
void CharClass::setMajorAttributes(int first, int second)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mAttribute[0] = first;
|
||||
data.mAttribute[1] = second;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int CharClass::getSpecialization() const
|
||||
{
|
||||
return player->charClass.mData.mSpecialization;
|
||||
}
|
||||
|
||||
void CharClass::setSpecialization(int spec)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSpecialization = spec;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int, int, int, int> CharClass::getMinorSkills() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple( data.mSkills[0][0], data.mSkills[1][0], data.mSkills[2][0], data.mSkills[3][0], data.mSkills[4][0]);
|
||||
}
|
||||
|
||||
void CharClass::setMinorSkills(int first, int second, int third, int fourth, int fifth)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSkills[0][0] = first;
|
||||
data.mSkills[1][0] = second;
|
||||
data.mSkills[2][0] = third;
|
||||
data.mSkills[3][0] = fourth;
|
||||
data.mSkills[4][0] = fifth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int, int, int, int> CharClass::getMajorSkills() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple( data.mSkills[0][1], data.mSkills[1][1], data.mSkills[2][1], data.mSkills[3][1], data.mSkills[4][1]);
|
||||
}
|
||||
|
||||
void CharClass::setMajorSkills(int first, int second, int third, int fourth, int fifth)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSkills[0][1] = first;
|
||||
data.mSkills[1][1] = second;
|
||||
data.mSkills[2][1] = third;
|
||||
data.mSkills[3][1] = fourth;
|
||||
data.mSkills[4][1] = fifth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void CharClass::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
printf("CharClass::update()\n");
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(false);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class CharClass
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
|
||||
public:
|
||||
explicit CharClass(Player *player);
|
||||
~CharClass();
|
||||
void update();
|
||||
|
||||
std::string getDefault() const;
|
||||
void setDefault(const std::string &className);
|
||||
bool isCustom() const;
|
||||
|
||||
std::string getName() const;
|
||||
void setName(const std::string &className);
|
||||
|
||||
std::string getDescription() const;
|
||||
void setDescription(const std::string &desc);
|
||||
|
||||
std::tuple<int, int> getMajorAttributes() const;
|
||||
void setMajorAttributes(int first, int second);
|
||||
|
||||
int getSpecialization() const;
|
||||
void setSpecialization(int spec);
|
||||
|
||||
std::tuple<int, int, int, int, int> getMinorSkills() const;
|
||||
void setMinorSkills(int fisrt, int second, int third, int fourth, int fifth);
|
||||
|
||||
std::tuple<int, int, int, int, int> getMajorSkills() const;
|
||||
void setMajorSkills(int fisrt, int second, int third, int fourth, int fifth);
|
||||
private:
|
||||
// not controlled pointer
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Dialogue.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
void Dialogue::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Dialogue>("Dialogue",
|
||||
"addTopic", &Dialogue::addTopic,
|
||||
"getTopicId", &Dialogue::getTopicId,
|
||||
"getChanges", &Dialogue::getChanges,
|
||||
"reset", &Dialogue::reset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Dialogue::Dialogue(Player *player) : player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Dialogue::reset()
|
||||
{
|
||||
player->topicChanges.topics.clear();
|
||||
}
|
||||
|
||||
void Dialogue::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
|
||||
void Dialogue::addTopic(const std::string &topicId)
|
||||
{
|
||||
if (!changed)
|
||||
reset();
|
||||
changed = true;
|
||||
player->topicChanges.topics.push_back({topicId});
|
||||
}
|
||||
|
||||
std::string Dialogue::getTopicId(unsigned int i) const
|
||||
{
|
||||
return player->topicChanges.topics.at(i).topicId;
|
||||
}
|
||||
|
||||
unsigned int Dialogue::getChanges() const
|
||||
{
|
||||
return player->topicChanges.topics.size();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Dialogue
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Dialogue(Player *player);
|
||||
|
||||
void addTopic(const std::string &topicId);
|
||||
std::string getTopicId(unsigned int i) const;
|
||||
unsigned int getChanges() const;
|
||||
|
||||
void reset();
|
||||
void update();
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,155 @@
|
||||
//
|
||||
// Created by koncord on 17.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Factions.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
void Factions::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Factions>("Factions",
|
||||
"addFaction", &Factions::addFaction,
|
||||
"changesAction", sol::property(&Factions::getFactionChangesAction, &Factions::setFactionChangesAction),
|
||||
"getFaction", &Factions::getFaction,
|
||||
"setFaction", &Factions::setFaction,
|
||||
"clear", &Factions::clear,
|
||||
"size", &Factions::size
|
||||
|
||||
);
|
||||
/*"InitializeFactionChanges", FactionFunctions::InitializeFactionChanges,
|
||||
"GetFactionChangesSize", FactionFunctions::GetFactionChangesSize,
|
||||
"GetFactionChangesAction", FactionFunctions::GetFactionChangesAction,
|
||||
"GetFactionId", FactionFunctions::GetFactionId,
|
||||
"GetFactionRank", FactionFunctions::GetFactionRank,
|
||||
"GetFactionExpulsionState", FactionFunctions::GetFactionExpulsionState,
|
||||
"GetFactionReputation", FactionFunctions::GetFactionReputation,
|
||||
"SetFactionChangesAction", FactionFunctions::SetFactionChangesAction,
|
||||
"SetFactionId", FactionFunctions::SetFactionId,
|
||||
"SetFactionRank", FactionFunctions::SetFactionRank,
|
||||
"SetFactionExpulsionState", FactionFunctions::SetFactionExpulsionState,
|
||||
"SetFactionReputation", FactionFunctions::SetFactionReputation,
|
||||
"AddFaction", FactionFunctions::AddFaction,
|
||||
"SendFactionChanges", FactionFunctions::SendFactionChanges*/
|
||||
}
|
||||
|
||||
Factions::Factions(Player *player): player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Factions::~Factions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Factions::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet =mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
clear();
|
||||
}
|
||||
|
||||
int Factions::getFactionChangesAction() const
|
||||
{
|
||||
return player->factionChanges.action;
|
||||
}
|
||||
|
||||
void Factions::setFactionChangesAction(int action)
|
||||
{
|
||||
player->factionChanges.action = action;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Factions::addFaction(Faction faction)
|
||||
{
|
||||
player->factionChanges.factions.push_back(faction.faction);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
Faction Factions::getFaction(int id) const
|
||||
{
|
||||
return Faction(player->factionChanges.factions.at(id));
|
||||
}
|
||||
|
||||
void Factions::setFaction(int id, Faction faction)
|
||||
{
|
||||
player->factionChanges.factions.at(id) = faction.faction;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Factions::clear()
|
||||
{
|
||||
player->factionChanges.factions.clear();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
size_t Factions::size() const
|
||||
{
|
||||
return player->factionChanges.factions.size();
|
||||
}
|
||||
|
||||
void Faction::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Faction>("Faction",
|
||||
"factionId", sol::property(&Faction::getFactionId, &Faction::setFactionId),
|
||||
"rank", sol::property(&Faction::getFactionRank, &Faction::setFactionRank),
|
||||
"isExpelled", sol::property(&Faction::getFactionExpulsionState, &Faction::setFactionExpulsionState),
|
||||
"reputation", sol::property(&Faction::getFactionReputation, &Faction::setFactionReputation)
|
||||
);
|
||||
}
|
||||
|
||||
Faction::Faction(mwmp::Faction &faction): faction(faction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Faction::getFactionId() const
|
||||
{
|
||||
return faction.factionId;
|
||||
}
|
||||
|
||||
void Faction::setFactionId(const std::string &factionId)
|
||||
{
|
||||
faction.factionId = factionId;
|
||||
}
|
||||
|
||||
int Faction::getFactionRank() const
|
||||
{
|
||||
return faction.rank;
|
||||
}
|
||||
|
||||
void Faction::setFactionRank(unsigned int rank)
|
||||
{
|
||||
faction.rank = rank;
|
||||
}
|
||||
|
||||
bool Faction::getFactionExpulsionState() const
|
||||
{
|
||||
return faction.isExpelled;
|
||||
}
|
||||
|
||||
void Faction::setFactionExpulsionState(bool expulsionState)
|
||||
{
|
||||
faction.isExpelled = expulsionState;
|
||||
}
|
||||
|
||||
int Faction::getFactionReputation() const
|
||||
{
|
||||
return faction.reputation;
|
||||
}
|
||||
|
||||
void Faction::setFactionReputation(int reputation)
|
||||
{
|
||||
faction.reputation = reputation;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Created by koncord on 17.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Faction
|
||||
{
|
||||
friend class Factions;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Faction(mwmp::Faction &faction);
|
||||
|
||||
std::string getFactionId() const;
|
||||
void setFactionId(const std::string &factionId);
|
||||
|
||||
int getFactionRank() const;
|
||||
void setFactionRank(unsigned int rank);
|
||||
|
||||
bool getFactionExpulsionState() const;
|
||||
void setFactionExpulsionState(bool expulsionState);
|
||||
|
||||
int getFactionReputation() const;
|
||||
void setFactionReputation(int reputation);
|
||||
|
||||
mwmp::Faction faction;
|
||||
};
|
||||
|
||||
class Factions
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Factions(Player *player);
|
||||
~Factions();
|
||||
|
||||
void update();
|
||||
|
||||
int getFactionChangesAction() const;
|
||||
void setFactionChangesAction(int action);
|
||||
|
||||
void addFaction(Faction faction);
|
||||
Faction getFaction(int id) const;
|
||||
void setFaction(int id, Faction faction);
|
||||
size_t size() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
mwmp::Faction tempFaction;
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
@ -0,0 +1,145 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "GUI.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void GUI::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<GUI>("GUI",
|
||||
"messageBox", &GUI::messageBox,
|
||||
"customMessageBox", &GUI::customMessageBox,
|
||||
"inputDialog", &GUI::inputDialog,
|
||||
"passwordDialog", &GUI::passwordDialog,
|
||||
"listBox", &GUI::listBox,
|
||||
"setMapVisibility", &GUI::setMapVisibility,
|
||||
"setMapVisibilityAll", &GUI::setMapVisibilityAll,
|
||||
"createWindow", &GUI::createWindow,
|
||||
"deleteWindow", &GUI::deleteWindow
|
||||
);
|
||||
Window::Init(lua);
|
||||
}
|
||||
|
||||
GUI::GUI(Player *player): player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GUI::~GUI()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GUI::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(false);
|
||||
}
|
||||
|
||||
void GUI::messageBox(int id, const char *label)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::MessageBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::customMessageBox(int id, const char *label, const char *buttons)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.buttons = buttons;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::CustomMessageBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::inputDialog(int id, const char *label)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::InputDialog;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::passwordDialog(int id, const char *label, const char *note)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.note = note;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::PasswordDialog;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::listBox(int id, const char *label, const char *items)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.data = items;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::ListBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
||||
|
||||
void GUI::setMapVisibilityAll(unsigned short targetPID, unsigned short state)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
||||
|
||||
std::shared_ptr<Window> GUI::createWindow(short x, short y, sol::function fn, sol::this_environment te)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
for (auto &window : windows)
|
||||
{
|
||||
if (window.second == nullptr)
|
||||
{
|
||||
id = window.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
id = lastWindowId++;
|
||||
|
||||
auto window = std::make_shared<Window>(player, id);
|
||||
window->setSize(x, y);
|
||||
window->setCallback(fn);
|
||||
|
||||
windows[id] = window;
|
||||
return window;
|
||||
}
|
||||
|
||||
void GUI::deleteWindow(std::shared_ptr<Window> window)
|
||||
{
|
||||
auto it = windows.find(window->getID());
|
||||
if (it != windows.end())
|
||||
{
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::onGUIWindowAction()
|
||||
{
|
||||
auto it = windows.find(player->guiWindow.id);
|
||||
if (it != windows.end() && it->second != nullptr)
|
||||
{
|
||||
it->second->call(player->guiWindow);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Window.hpp"
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class GUI
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit GUI(Player *player);
|
||||
~GUI();
|
||||
|
||||
void update();
|
||||
|
||||
void messageBox(int id, const char *label);
|
||||
|
||||
void customMessageBox(int id, const char *label, const char *buttons);
|
||||
void inputDialog(int id, const char *label);
|
||||
void passwordDialog(int id, const char *label, const char *note);
|
||||
|
||||
void listBox(int id, const char *label, const char *items);
|
||||
|
||||
//state 0 - disallow, 1 - allow
|
||||
void setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state);
|
||||
void setMapVisibilityAll(unsigned short targetPID, unsigned short state);
|
||||
|
||||
std::shared_ptr<Window> createWindow(short x, short y, sol::function fn, sol::this_environment te);
|
||||
void deleteWindow(std::shared_ptr<Window> window);
|
||||
void onGUIWindowAction();
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
std::unordered_map<int, std::shared_ptr<Window>> windows;
|
||||
int lastWindowId;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,173 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw/mwworld/inventorystore.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Inventory.hpp"
|
||||
#include "NetActor.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Inventory::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Inventory>("Inventory",
|
||||
"getInventoryChangesSize", &Inventory::getChangesSize,
|
||||
"addItem", &Inventory::addItem,
|
||||
"removeItem", &Inventory::removeItem,
|
||||
"getInventoryItem", &Inventory::getInventoryItem,
|
||||
|
||||
"equipItem", &Inventory::equipItem,
|
||||
"unequipItem", &Inventory::unequipItem,
|
||||
"hasItemEquipped", &Inventory::hasItemEquipped,
|
||||
"getEquipmentItem", &Inventory::getEquipmentItem
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(0)
|
||||
{
|
||||
printf("Inventory::Inventory()\n");
|
||||
}
|
||||
|
||||
Inventory::~Inventory()
|
||||
{
|
||||
printf("Inventory::~Inventory()\n");
|
||||
}
|
||||
|
||||
void Inventory::update()
|
||||
{
|
||||
printf("Inventory::update()");
|
||||
/*if (equipmentChanged)
|
||||
{
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT);
|
||||
packet->setPlayer(netActor->getNetCreature());
|
||||
packet->Send(false);
|
||||
packet->Send(true);
|
||||
}
|
||||
|
||||
if (inventoryChanged != 0)
|
||||
{
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT);
|
||||
packet->setPlayer(netActor->getNetCreature());
|
||||
packet->Send(false);
|
||||
}
|
||||
|
||||
equipmentChanged = false;
|
||||
inventoryChanged = 0;*/
|
||||
}
|
||||
|
||||
|
||||
void Inventory::InitializeInventoryChanges()
|
||||
{
|
||||
netActor->getNetCreature()->inventoryChanges.items.clear();
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::SET;
|
||||
}
|
||||
|
||||
int Inventory::getChangesSize() const
|
||||
{
|
||||
return netActor->getNetCreature()->inventoryChanges.items.size();
|
||||
}
|
||||
|
||||
void Inventory::equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge)
|
||||
{
|
||||
netActor->getNetCreature()->equipmentItems[slot].refId = refId;
|
||||
netActor->getNetCreature()->equipmentItems[slot].count = count;
|
||||
netActor->getNetCreature()->equipmentItems[slot].charge = charge;
|
||||
|
||||
if (!Utils::vectorContains(&netActor->getNetCreature()->equipmentIndexChanges, slot))
|
||||
netActor->getNetCreature()->equipmentIndexChanges.push_back(slot);
|
||||
|
||||
equipmentChanged = true;
|
||||
}
|
||||
|
||||
void Inventory::unequipItem( unsigned short slot)
|
||||
{
|
||||
equipItem(slot, "", 0, -1);
|
||||
}
|
||||
|
||||
|
||||
void Inventory::addItem(const std::string &refId, unsigned int count, int charge)
|
||||
{
|
||||
if (inventoryChanged == mwmp::InventoryChanges::REMOVE)
|
||||
return;
|
||||
if (inventoryChanged == 0)
|
||||
InitializeInventoryChanges();
|
||||
|
||||
mwmp::Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
|
||||
netActor->getNetCreature()->inventoryChanges.items.push_back(item);
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::ADD;
|
||||
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action;
|
||||
}
|
||||
|
||||
void Inventory::removeItem(const std::string &refId, unsigned short count)
|
||||
{
|
||||
if (inventoryChanged == mwmp::InventoryChanges::ADD)
|
||||
return;
|
||||
if (inventoryChanged == 0)
|
||||
InitializeInventoryChanges();
|
||||
|
||||
mwmp::Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
|
||||
netActor->getNetCreature()->inventoryChanges.items.push_back(item);
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::REMOVE;
|
||||
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action;
|
||||
}
|
||||
|
||||
bool Inventory::hasItemEquipped(const std::string &refId) const
|
||||
{
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
if (Misc::StringUtils::ciEqual(netActor->getNetCreature()->equipmentItems[slot].refId, refId))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<std::string, int, int> Inventory::getEquipmentItem(unsigned short slot) const
|
||||
{
|
||||
const auto &item = netActor->getNetCreature()->equipmentItems[slot];
|
||||
return make_tuple(item.refId, item.count, item.charge);
|
||||
}
|
||||
|
||||
std::tuple<std::string, int, int> Inventory::getInventoryItem(unsigned int slot) const
|
||||
{
|
||||
const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot);
|
||||
return make_tuple(item.refId, item.count, item.charge);
|
||||
}
|
||||
|
||||
void Inventory::resetEquipmentFlag()
|
||||
{
|
||||
equipmentChanged = false;
|
||||
|
||||
netActor->getNetCreature()->equipmentIndexChanges.clear();
|
||||
}
|
||||
|
||||
bool Inventory::isEquipmentChanged()
|
||||
{
|
||||
return equipmentChanged;
|
||||
}
|
||||
|
||||
void Inventory::resetInventoryFlag()
|
||||
{
|
||||
inventoryChanged = 0;
|
||||
}
|
||||
|
||||
int Inventory::inventoryChangeType()
|
||||
{
|
||||
return inventoryChanged;
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
class LuaState;
|
||||
class NetActor;
|
||||
|
||||
class Inventory
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
bool isEquipmentChanged();
|
||||
void resetEquipmentFlag();
|
||||
int inventoryChangeType();
|
||||
void resetInventoryFlag();
|
||||
public:
|
||||
explicit Inventory(NetActor *netActor);
|
||||
~Inventory();
|
||||
void update();
|
||||
|
||||
//inventory
|
||||
int getChangesSize() const;
|
||||
void addItem(const std::string& refId, unsigned int count, int charge);
|
||||
void removeItem(const std::string& refId, unsigned short count);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param slot
|
||||
* @return refid, count, charge
|
||||
*/
|
||||
std::tuple<std::string,int, int> getInventoryItem(unsigned int slot) const;
|
||||
|
||||
|
||||
// equipment
|
||||
void equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge);
|
||||
void unequipItem(unsigned short slot);
|
||||
|
||||
bool hasItemEquipped(const std::string& refId) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param slot
|
||||
* @return refid, count, charge
|
||||
*/
|
||||
std::tuple<std::string,int, int> getEquipmentItem(unsigned short slot) const;
|
||||
|
||||
|
||||
private:
|
||||
void InitializeInventoryChanges();
|
||||
|
||||
private:
|
||||
// not controlled pointer
|
||||
NetActor *netActor;
|
||||
bool equipmentChanged;
|
||||
int inventoryChanged;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,111 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Base/BaseNetCreature.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "NetActor.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
NetActor::NetActor() : inventory(this), cellAPI(this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NetActor::resetUpdateFlags()
|
||||
{
|
||||
baseInfoChanged = false;
|
||||
levelChanged = false;
|
||||
statsChanged = false;
|
||||
positionChanged = false;
|
||||
skillsChanged = false;
|
||||
attributesChanged = false;
|
||||
}
|
||||
|
||||
std::tuple<float, float, float> NetActor::getPosition() const
|
||||
{
|
||||
return make_tuple(netCreature->position.pos[0], netCreature->position.pos[1], netCreature->position.pos[2]);
|
||||
}
|
||||
|
||||
void NetActor::setPosition(float x, float y, float z)
|
||||
{
|
||||
netCreature->position.pos[0] = x;
|
||||
netCreature->position.pos[1] = y;
|
||||
netCreature->position.pos[2] = z;
|
||||
positionChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getRotation() const
|
||||
{
|
||||
return make_tuple(netCreature->position.rot[0], netCreature->position.rot[2]);
|
||||
}
|
||||
|
||||
void NetActor::setRotation(float x, float z)
|
||||
{
|
||||
netCreature->position.rot[0] = x;
|
||||
netCreature->position.rot[2] = z;
|
||||
positionChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getHealth() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[0].mBase, netCreature->creatureStats.mDynamic[0].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setHealth(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[0].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[0].mCurrent = current;
|
||||
|
||||
if (!Utils::vectorContains(&netCreature->statsDynamicIndexChanges, 0))
|
||||
netCreature->statsDynamicIndexChanges.push_back(0);
|
||||
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getMagicka() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[1].mBase, netCreature->creatureStats.mDynamic[1].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setMagicka(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[1].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[1].mCurrent = current;
|
||||
|
||||
if (!Utils::vectorContains(&netCreature->statsDynamicIndexChanges, 1))
|
||||
netCreature->statsDynamicIndexChanges.push_back(1);
|
||||
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getFatigue() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[2].mBase, netCreature->creatureStats.mDynamic[2].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setFatigue(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[2].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[2].mCurrent = current;
|
||||
|
||||
if (!Utils::vectorContains(&netCreature->statsDynamicIndexChanges, 2))
|
||||
netCreature->statsDynamicIndexChanges.push_back(2);
|
||||
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
Inventory &NetActor::getInventory()
|
||||
{
|
||||
return inventory;
|
||||
}
|
||||
|
||||
Cells &NetActor::getCell()
|
||||
{
|
||||
return cellAPI;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <RakNetTypes.h>
|
||||
#include <tuple>
|
||||
#include "Inventory.hpp"
|
||||
#include "Cells.hpp"
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
class BasePlayer;
|
||||
class BaseNetCreature;
|
||||
class BaseActor;
|
||||
}
|
||||
|
||||
class NetActor
|
||||
{
|
||||
public:
|
||||
NetActor();
|
||||
|
||||
void resetUpdateFlags();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
|
||||
std::tuple<float, float, float> getPosition() const;
|
||||
void setPosition(float x, float y, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y
|
||||
*/
|
||||
std::tuple<float, float> getRotation() const;
|
||||
void setRotation(float x, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getHealth() const;
|
||||
void setHealth(float base, float current);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getMagicka() const;
|
||||
void setMagicka(float base, float current);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getFatigue() const;
|
||||
void setFatigue(float base, float current);
|
||||
|
||||
Inventory &getInventory();
|
||||
Cells &getCell();
|
||||
|
||||
mwmp::BaseNetCreature *getNetCreature() { return netCreature; }
|
||||
protected:
|
||||
bool baseInfoChanged, levelChanged, statsChanged, positionChanged, attributesChanged, skillsChanged;
|
||||
mwmp::BasePlayer *basePlayer;
|
||||
mwmp::BaseNetCreature *netCreature;
|
||||
|
||||
Inventory inventory;
|
||||
Cells cellAPI;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,470 @@
|
||||
//
|
||||
// Created by koncord on 26.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Object.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Object::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Object>("Object",
|
||||
"refId", sol::property(&BaseObject::getRefId, &BaseObject::setRefId),
|
||||
"refNum", sol::property(&BaseObject::getRefNum, &BaseObject::setRefNum),
|
||||
"mpNum", sol::property(&BaseObject::getMpNum, &BaseObject::setMpNum),
|
||||
"getPosition", &Object::getPosition,
|
||||
"setPosition", &Object::setPosition,
|
||||
"getRotation", &Object::getRotation,
|
||||
"setRotation", &Object::setRotation,
|
||||
"count", sol::property(&Object::getCount, &Object::setCount),
|
||||
"goldValue", sol::property(&Object::getGoldValue, &Object::setGoldValue),
|
||||
"scale", sol::property(&Object::getScale, &Object::setScale),
|
||||
"state", sol::property(&Object::getState, &Object::setState),
|
||||
"doorState", sol::property(&Object::getDoorState, &Object::setDoorState),
|
||||
"lockLevel", sol::property(&Object::getLockLevel, &Object::setLockLevel),
|
||||
"setDisarmState", &Object::setDisarmState,
|
||||
"setMasterState", &Object::setMasterState
|
||||
);
|
||||
}
|
||||
|
||||
Object::Object()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Object::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
tuple<float, float, float> Object::getPosition() const
|
||||
{
|
||||
return make_tuple(object.position.pos[0], object.position.pos[1], object.position.pos[2]);
|
||||
}
|
||||
|
||||
void Object::setPosition(float x, float y, float z)
|
||||
{
|
||||
object.position.pos[0] = x;
|
||||
object.position.pos[1] = y;
|
||||
object.position.pos[2] = z;
|
||||
changedObjectPlace = true;
|
||||
}
|
||||
|
||||
tuple<float, float, float> Object::getRotation() const
|
||||
{
|
||||
return make_tuple(object.position.rot[0], object.position.rot[1], object.position.rot[2]);
|
||||
}
|
||||
|
||||
void Object::setRotation(float x, float y, float z)
|
||||
{
|
||||
object.position.rot[0] = x;
|
||||
object.position.rot[1] = y;
|
||||
object.position.rot[2] = z;
|
||||
changedObjectPlace = true;
|
||||
}
|
||||
|
||||
BaseObject::BaseObject(): changedBase(false), copied(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
string BaseObject::getRefId() const
|
||||
{
|
||||
return object.refId;
|
||||
}
|
||||
|
||||
void BaseObject::setRefId(const string &refId)
|
||||
{
|
||||
changedBase = true;
|
||||
object.refId = refId;
|
||||
}
|
||||
|
||||
int BaseObject::getRefNum() const
|
||||
{
|
||||
return object.refNumIndex;
|
||||
}
|
||||
|
||||
void BaseObject::setRefNum(int refNum)
|
||||
{
|
||||
changedBase = true;
|
||||
object.refNumIndex = refNum;
|
||||
}
|
||||
|
||||
int BaseObject::getMpNum() const
|
||||
{
|
||||
return object.mpNum;
|
||||
}
|
||||
|
||||
void BaseObject::setMpNum(int mpNum)
|
||||
{
|
||||
changedBase = true;
|
||||
object.mpNum = mpNum;
|
||||
}
|
||||
|
||||
int Object::getCount() const
|
||||
{
|
||||
return object.count;
|
||||
}
|
||||
|
||||
void Object::setCount(int count)
|
||||
{
|
||||
changedObjectPlace = true;
|
||||
object.count = count;
|
||||
}
|
||||
|
||||
int Object::getCharge() const
|
||||
{
|
||||
return object.charge;
|
||||
}
|
||||
|
||||
void Object::setCharge(int charge)
|
||||
{
|
||||
changedObjectPlace = true;
|
||||
object.charge = charge;
|
||||
|
||||
}
|
||||
|
||||
int Object::getGoldValue() const
|
||||
{
|
||||
return object.goldValue;
|
||||
}
|
||||
|
||||
void Object::setGoldValue(int gold)
|
||||
{
|
||||
changedObjectPlace = true;
|
||||
object.goldValue = gold;
|
||||
}
|
||||
|
||||
float Object::getScale() const
|
||||
{
|
||||
return object.scale;
|
||||
}
|
||||
|
||||
void Object::setScale(float scale)
|
||||
{
|
||||
changedObjectScale = true;
|
||||
object.scale = scale;
|
||||
}
|
||||
|
||||
bool Object::getState() const
|
||||
{
|
||||
return object.objectState;
|
||||
}
|
||||
|
||||
void Object::setState(bool state)
|
||||
{
|
||||
changedObjectState = true;
|
||||
object.objectState = state;
|
||||
}
|
||||
|
||||
int Object::getDoorState() const
|
||||
{
|
||||
return object.doorState;
|
||||
}
|
||||
|
||||
void Object::setDoorState(int state)
|
||||
{
|
||||
changedDoorState = true;
|
||||
object.doorState = state;
|
||||
}
|
||||
|
||||
int Object::getLockLevel() const
|
||||
{
|
||||
return object.lockLevel;
|
||||
}
|
||||
|
||||
void Object::setLockLevel(int locklevel)
|
||||
{
|
||||
changedObjectLock = true;
|
||||
object.lockLevel = locklevel;
|
||||
}
|
||||
|
||||
void Object::setDisarmState(bool state)
|
||||
{
|
||||
changedObjectTrap = true;
|
||||
object.isDisarmed = state;
|
||||
}
|
||||
|
||||
void Object::setMasterState(bool state)
|
||||
{
|
||||
changedObjectSpawn = true;
|
||||
object.hasMaster = state;
|
||||
}
|
||||
|
||||
|
||||
void Container::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Container>("Container",
|
||||
"refId", sol::property(&BaseObject::getRefId, &BaseObject::setRefId),
|
||||
"refNum", sol::property(&BaseObject::getRefNum, &BaseObject::setRefNum),
|
||||
"mpNum", sol::property(&BaseObject::getMpNum, &BaseObject::setMpNum),
|
||||
"getItem", &Container::getItem,
|
||||
"addItem", &Container::addItem,
|
||||
"setItem", &Container::setItem,
|
||||
"getActionCount", &Container::getActionCount
|
||||
);
|
||||
}
|
||||
|
||||
Container::Container()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
tuple<string, int, int> Container::getItem(int i) const
|
||||
{
|
||||
auto &item = object.containerItems.at(i);
|
||||
return make_tuple(item.refId, item.count, item.charge);
|
||||
}
|
||||
|
||||
void Container::setItem(int i, const string &refId, int count, int charge)
|
||||
{
|
||||
auto &item = object.containerItems.at(i);
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Container::addItem(const string &refId, int count, int charge)
|
||||
{
|
||||
mwmp::ContainerItem item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
object.containerItems.push_back(item);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int Container::getActionCount(int i) const
|
||||
{
|
||||
return object.containerItems.at(i).actionCount;
|
||||
}
|
||||
|
||||
size_t Container::size() const
|
||||
{
|
||||
return object.containerItems.size();
|
||||
}
|
||||
|
||||
void ObjectController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table objectCtrl = lua.getState()->create_table("ObjectCtrl");
|
||||
|
||||
objectCtrl.set_function("sendObjects", [&lua](shared_ptr<Player> player, shared_ptr<vector<shared_ptr<Object>>> objects,
|
||||
const std::string &cellDescription) {
|
||||
return lua.getObjectCtrl().sendObjects(player, objects, Utils::getCellFromDescription(cellDescription));
|
||||
});
|
||||
|
||||
objectCtrl.set_function("sendContainers", [&lua](shared_ptr<Player> player, shared_ptr<vector<shared_ptr<Container>>> objects,
|
||||
const std::string &cellDescription) {
|
||||
return lua.getObjectCtrl().sendContainers(player, objects, Utils::getCellFromDescription(cellDescription));
|
||||
});
|
||||
|
||||
objectCtrl.set_function("requestContainers", [&lua](shared_ptr<Player> player) {
|
||||
lua.getObjectCtrl().requestContainers(player);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
shared_ptr<vector<shared_ptr<Object>>> ObjectController::copyObjects(mwmp::BaseEvent &event)
|
||||
{
|
||||
auto objects = make_shared<vector<shared_ptr<Object>>>();
|
||||
|
||||
for (auto &obj : event.worldObjects)
|
||||
{
|
||||
auto object = new Object;
|
||||
object->copied = true;
|
||||
object->object = obj;
|
||||
objects->emplace_back(object);
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
shared_ptr<vector<shared_ptr<Container>>> ObjectController::copyContainers(mwmp::BaseEvent &event)
|
||||
{
|
||||
auto containers = make_shared<vector<shared_ptr<Container>>>();
|
||||
|
||||
for (auto &obj : event.worldObjects)
|
||||
{
|
||||
auto container = new Container;
|
||||
container->copied = true;
|
||||
container->object = obj;
|
||||
containers->emplace_back(container);
|
||||
}
|
||||
return containers;
|
||||
}
|
||||
|
||||
void ObjectController::sendObjects(shared_ptr<Player> player, shared_ptr<vector<shared_ptr<Object>>> objects, const ESM::Cell &cell)
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
DOOR_STATE = 0,
|
||||
OBJECT_STATE,
|
||||
OBJECT_SCALE,
|
||||
OBJECT_TRAP,
|
||||
OBJECT_LOCK,
|
||||
OBJECT_DELETE,
|
||||
OBJECT_SPAWN,
|
||||
OBJECT_PLACE,
|
||||
LAST
|
||||
};
|
||||
mwmp::BaseEvent events[Type::LAST];
|
||||
bool changed[Type::LAST];
|
||||
|
||||
for (auto &e : events)
|
||||
{
|
||||
e.action = mwmp::BaseEvent::SET;
|
||||
e.guid = player->guid;
|
||||
e.cell = cell;
|
||||
}
|
||||
|
||||
|
||||
for (auto &object : *objects)
|
||||
{
|
||||
//sendObject(player.get(), object.get());
|
||||
|
||||
bool validNewObjOrCopy = (!object->copied && object->changedBase) || object->copied;
|
||||
|
||||
if (object->changedDoorState && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::DOOR_STATE] = true;
|
||||
events[Type::DOOR_STATE].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectState && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_STATE] = true;
|
||||
events[Type::OBJECT_STATE].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectScale && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_SCALE] = true;
|
||||
events[Type::OBJECT_SCALE].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectTrap && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_TRAP] = true;
|
||||
events[Type::OBJECT_TRAP].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectLock && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_LOCK] = true;
|
||||
events[Type::OBJECT_LOCK].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectDelete && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_DELETE] = true;
|
||||
events[Type::OBJECT_DELETE].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectSpawn && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_SPAWN] = true;
|
||||
events[Type::OBJECT_SPAWN].worldObjects.push_back(object->object);
|
||||
}
|
||||
if (object->changedObjectPlace && validNewObjOrCopy)
|
||||
{
|
||||
changed[Type::OBJECT_PLACE] = true;
|
||||
events[Type::OBJECT_PLACE].worldObjects.push_back(object->object);
|
||||
}
|
||||
}
|
||||
|
||||
auto worldCtrl = mwmp::Networking::get().getWorldPacketController();
|
||||
|
||||
if (changed[Type::DOOR_STATE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_DOOR_STATE);
|
||||
auto &event = events[Type::DOOR_STATE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_STATE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_STATE);
|
||||
auto &event = events[Type::OBJECT_STATE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_SCALE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_SCALE);
|
||||
auto &event = events[Type::OBJECT_SCALE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_TRAP])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_TRAP);
|
||||
auto &event = events[Type::OBJECT_TRAP];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_LOCK])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_LOCK);
|
||||
auto &event = events[Type::OBJECT_LOCK];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_DELETE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_DELETE);
|
||||
auto &event = events[Type::OBJECT_DELETE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_SCALE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_SPAWN);
|
||||
auto &event = events[Type::OBJECT_SCALE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
if (changed[Type::OBJECT_PLACE])
|
||||
{
|
||||
auto packet = worldCtrl->GetPacket(ID_OBJECT_PLACE);
|
||||
auto &event = events[Type::OBJECT_PLACE];
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectController::sendContainers(shared_ptr<Player> player, shared_ptr<vector<shared_ptr<Container>>> objects, const ESM::Cell &cell)
|
||||
{
|
||||
|
||||
mwmp::BaseEvent event;
|
||||
event.cell = cell;
|
||||
event.action = mwmp::BaseEvent::SET;
|
||||
event.guid = player->guid;
|
||||
|
||||
for (auto &object : *objects)
|
||||
{
|
||||
bool validNewObjOrCopy = (!object->copied && object->changedBase) || object->copied;
|
||||
if (object->changed && validNewObjOrCopy)
|
||||
event.worldObjects.push_back(object->object);
|
||||
}
|
||||
|
||||
auto packet = mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER);
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
||||
|
||||
void ObjectController::requestContainers(shared_ptr<Player> player)
|
||||
{
|
||||
mwmp::BaseEvent event;
|
||||
event.action = mwmp::BaseEvent::REQUEST;
|
||||
event.guid = player->guid;
|
||||
event.cell = player->cell;
|
||||
|
||||
auto packet = mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER);
|
||||
packet->setEvent(&event);
|
||||
packet->Send(event.guid);
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
//
|
||||
// Created by koncord on 26.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <components/openmw-mp/Base/BaseEvent.hpp>
|
||||
#include <memory>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class BaseObject
|
||||
{
|
||||
public:
|
||||
BaseObject();
|
||||
std::string getRefId() const;
|
||||
void setRefId(const std::string &refId);
|
||||
|
||||
int getRefNum() const;
|
||||
void setRefNum(int refNum);
|
||||
|
||||
int getMpNum() const;
|
||||
void setMpNum(int mpNum);
|
||||
|
||||
//void setEventCell(const std::string &cellDescription);
|
||||
|
||||
|
||||
mwmp::WorldObject object;
|
||||
bool changedBase;
|
||||
bool copied;
|
||||
};
|
||||
|
||||
class Object : public BaseObject
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Object();
|
||||
~Object();
|
||||
|
||||
void update();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
|
||||
std::tuple<float, float, float> getPosition() const;
|
||||
void setPosition(float x, float y, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
std::tuple<float, float, float> getRotation() const;
|
||||
void setRotation(float x, float y, float z);
|
||||
|
||||
int getCount() const;
|
||||
void setCount(int count);
|
||||
|
||||
int getCharge() const;
|
||||
void setCharge(int charge);
|
||||
|
||||
int getGoldValue() const;
|
||||
void setGoldValue(int gold);
|
||||
|
||||
float getScale() const;
|
||||
void setScale(float scale);
|
||||
|
||||
bool getState() const;
|
||||
void setState(bool state);
|
||||
|
||||
int getDoorState() const;
|
||||
void setDoorState(int state);
|
||||
|
||||
int getLockLevel() const;
|
||||
void setLockLevel(int locklevel);
|
||||
|
||||
void setDisarmState(bool state);
|
||||
void setMasterState(bool state);
|
||||
|
||||
bool changedDoorState, changedObjectState, changedObjectScale, changedObjectTrap, changedObjectLock,
|
||||
changedObjectDelete, changedObjectSpawn, changedObjectPlace;
|
||||
};
|
||||
|
||||
class Container : public BaseObject
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Container();
|
||||
|
||||
std::tuple<std::string, int, int> getItem(int i) const;
|
||||
void addItem(const std::string &refId, int count, int charge);
|
||||
|
||||
void setItem(int i, const std::string &refId, int count, int charge);
|
||||
int getActionCount(int i) const;
|
||||
|
||||
size_t size() const;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
||||
class ObjectController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Object>>> copyObjects(mwmp::BaseEvent &event);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Container>>> copyContainers(mwmp::BaseEvent &event);
|
||||
|
||||
void sendObjects(std::shared_ptr<Player> player, std::shared_ptr<std::vector<std::shared_ptr<Object>>> objects, const ESM::Cell &cell);
|
||||
void sendContainers(std::shared_ptr<Player> player, std::shared_ptr<std::vector<std::shared_ptr<Container>>> objects, const ESM::Cell &cell);
|
||||
|
||||
void requestContainers(std::shared_ptr<Player> player);
|
||||
};
|
@ -0,0 +1,115 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include "Players.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Players::Store Players::store;
|
||||
|
||||
void Players::Init(LuaState &lua)
|
||||
{
|
||||
sol::table playersTable = lua.getState()->create_named_table("Players");
|
||||
playersTable.set_function("getByPID", &Players::getPlayerByPID);
|
||||
playersTable.set_function("getByGUID", &Players::getPlayerByGUID);
|
||||
playersTable.set_function("for_each", [](sol::function func)
|
||||
{
|
||||
for (shared_ptr<Player> player : store)
|
||||
func(player);
|
||||
});
|
||||
|
||||
playersTable.set_function("size", &Players::size);
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Player> Players::getPlayerByPID(int pid)
|
||||
{
|
||||
const auto &ls = store.get<ByID>();
|
||||
auto it = ls.find(pid);
|
||||
if (it != ls.end())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Player> Players::getPlayerByGUID(RakNet::RakNetGUID guid)
|
||||
{
|
||||
const auto &ls = store.get<ByGUID>();
|
||||
auto it = ls.find(guid.g);
|
||||
if (it != ls.end())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Player> Players::addPlayer(RakNet::RakNetGUID guid)
|
||||
{
|
||||
const int maxConnections = 65535;
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Creating new player with guid %lu", guid.g);
|
||||
|
||||
auto player = make_shared<Player>(guid);
|
||||
|
||||
unsigned short findPid = 0;
|
||||
const auto &ls = store.get<ByID>();
|
||||
for (; findPid < maxConnections; ++findPid) // find empty slot
|
||||
{
|
||||
auto it = ls.find(findPid);
|
||||
if (it == ls.end())
|
||||
break;
|
||||
}
|
||||
|
||||
if (findPid >= maxConnections)
|
||||
return nullptr;
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Storing in slot %i", findPid);
|
||||
player->id = findPid;
|
||||
player->guid = guid;
|
||||
store.push_back(player);
|
||||
return player;
|
||||
}
|
||||
|
||||
void Players::deletePlayerByPID(int pid)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Marking player (pid %i) for deletion", pid);
|
||||
auto &ls = store.get<ByID>();
|
||||
auto it = ls.find(pid);
|
||||
if (it != ls.end())
|
||||
{
|
||||
ls.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void Players::deletePlayerByGUID(RakNet::RakNetGUID guid)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Marking player (guid %lu) for deletion", guid.g);
|
||||
auto &ls = store.get<ByGUID>();
|
||||
auto it = ls.find(guid.g);
|
||||
if (it != ls.end())
|
||||
{
|
||||
LOG_APPEND(Log::LOG_INFO, "- references: %d", it->use_count());
|
||||
ls.erase(it);
|
||||
LOG_APPEND(Log::LOG_INFO, "- references: %d", it->use_count());
|
||||
}
|
||||
}
|
||||
|
||||
void Players::for_each(std::function<void (std::shared_ptr<Player>)> func)
|
||||
{
|
||||
for (auto &player : store)
|
||||
func(player);
|
||||
}
|
||||
|
||||
Players::Store::const_iterator Players::begin()
|
||||
{
|
||||
return store.cbegin();
|
||||
}
|
||||
|
||||
Players::Store::const_iterator Players::end()
|
||||
{
|
||||
return store.cend();
|
||||
}
|
||||
|
||||
size_t Players::size()
|
||||
{
|
||||
return store.size();
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/global_fun.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include "Player.hpp"
|
||||
|
||||
class LuaState;
|
||||
|
||||
|
||||
class Players
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Players() = delete; // static class
|
||||
protected:
|
||||
|
||||
struct ByID {};
|
||||
struct ByGUID {};
|
||||
|
||||
public:
|
||||
typedef boost::multi_index_container<std::shared_ptr<Player>,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::random_access<>,
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<ByGUID>, BOOST_MULTI_INDEX_CONST_MEM_FUN(Player, uint64_t, getGUID)>,
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<ByID>, boost::multi_index::member<Player, unsigned short, &Player::id> >
|
||||
> > Store;
|
||||
|
||||
|
||||
static std::shared_ptr<Player> getPlayerByPID(int pid);
|
||||
static std::shared_ptr<Player> getPlayerByGUID(RakNet::RakNetGUID guid);
|
||||
static std::shared_ptr<Player> addPlayer(RakNet::RakNetGUID guid);
|
||||
static void deletePlayerByPID(int pid);
|
||||
static void deletePlayerByGUID(RakNet::RakNetGUID guid);
|
||||
static Store::const_iterator begin();
|
||||
static Store::const_iterator end();
|
||||
static size_t size();
|
||||
|
||||
static void for_each(std::function<void(std::shared_ptr<Player>)> func);
|
||||
|
||||
private:
|
||||
static Store store;
|
||||
};
|
||||
|
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
#include "Quests.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
void JournalItem::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<JournalItem>("JournalItem",
|
||||
"quest", sol::property(&JournalItem::getQuest, &JournalItem::setQuest),
|
||||
"index", sol::property(&JournalItem::getIndex, &JournalItem::setIndex),
|
||||
"actorRefId", sol::property(&JournalItem::getActorRefId, &JournalItem::setActorRefId),
|
||||
"type", sol::property(&JournalItem::getType, &JournalItem::setType)
|
||||
);
|
||||
}
|
||||
|
||||
JournalItem::JournalItem(mwmp::JournalItem item) : item(item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JournalItem::~JournalItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string JournalItem::getQuest() const
|
||||
{
|
||||
return item.quest;
|
||||
}
|
||||
|
||||
void JournalItem::setQuest(const std::string &quest)
|
||||
{
|
||||
item.quest = quest;
|
||||
}
|
||||
|
||||
int JournalItem::getIndex() const
|
||||
{
|
||||
return item.index;
|
||||
}
|
||||
|
||||
void JournalItem::setIndex(int index)
|
||||
{
|
||||
item.index = index;
|
||||
}
|
||||
|
||||
int JournalItem::getType() const
|
||||
{
|
||||
return item.type;
|
||||
}
|
||||
|
||||
void JournalItem::setType(int type)
|
||||
{
|
||||
item.type = type;
|
||||
}
|
||||
|
||||
std::string JournalItem::getActorRefId() const
|
||||
{
|
||||
return item.actorRefId;
|
||||
}
|
||||
|
||||
void JournalItem::setActorRefId(const std::string &refid)
|
||||
{
|
||||
item.actorRefId = refid;
|
||||
}
|
||||
|
||||
void Quests::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Quests>("Quests",
|
||||
"getJournalChangesSize", &Quests::getJournalChangesSize,
|
||||
"getKillChangesSize", &Quests::getKillChangesSize,
|
||||
|
||||
"addJournalItem", &Quests::addJournalItem,
|
||||
"setJournalItem", &Quests::setJournalItem,
|
||||
"getJournalItem", &Quests::getJournalItem,
|
||||
|
||||
"addKill", &Quests::addKill,
|
||||
"getKill", &Quests::getKill
|
||||
);
|
||||
}
|
||||
|
||||
Quests::Quests(Player *player) : player(player), changedKills(false), changedJournal(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Quests::~Quests()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Quests::update()
|
||||
{
|
||||
if (changedJournal)
|
||||
{
|
||||
changedJournal = false;
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JOURNAL);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
|
||||
if (changedKills)
|
||||
{
|
||||
changedKills = false;
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_KILL_COUNT);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Quests::getJournalChangesSize() const
|
||||
{
|
||||
return player->journalChanges.journalItems.size();
|
||||
}
|
||||
|
||||
size_t Quests::getKillChangesSize() const
|
||||
{
|
||||
return player->killChanges.kills.size();
|
||||
}
|
||||
|
||||
void Quests::addJournalItem(JournalItem item)
|
||||
{
|
||||
player->journalChanges.journalItems.push_back(item.item);
|
||||
changedJournal = true;
|
||||
|
||||
}
|
||||
|
||||
void Quests::setJournalItem(unsigned int id, JournalItem item)
|
||||
{
|
||||
player->journalChanges.journalItems.at(id) = item.item;
|
||||
changedJournal = true;
|
||||
}
|
||||
|
||||
JournalItem Quests::getJournalItem(unsigned int id)
|
||||
{
|
||||
return JournalItem(player->journalChanges.journalItems.at(id));
|
||||
}
|
||||
|
||||
void Quests::addKill(const std::string &refId, int number)
|
||||
{
|
||||
player->killChanges.kills.push_back({refId, number});
|
||||
changedKills = true;
|
||||
}
|
||||
|
||||
std::tuple<std::string, int> Quests::getKill(unsigned int i) const
|
||||
{
|
||||
auto & kill = player->killChanges.kills.at(i);
|
||||
return std::make_tuple(kill.refId, kill.number);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class JournalItem
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit JournalItem(mwmp::JournalItem item);
|
||||
~JournalItem();
|
||||
|
||||
std::string getQuest() const;
|
||||
void setQuest(const std::string &quest);
|
||||
|
||||
int getIndex() const;
|
||||
void setIndex(int index);
|
||||
|
||||
int getType() const;
|
||||
void setType(int type);
|
||||
|
||||
std::string getActorRefId() const;
|
||||
void setActorRefId(const std::string &refid);
|
||||
|
||||
|
||||
mwmp::JournalItem item;
|
||||
};
|
||||
|
||||
class Quests
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Quests(Player *player);
|
||||
~Quests();
|
||||
|
||||
void update();
|
||||
|
||||
size_t getJournalChangesSize() const;
|
||||
size_t getKillChangesSize() const;
|
||||
|
||||
void addJournalItem(JournalItem item);
|
||||
void setJournalItem(unsigned int id, JournalItem item);
|
||||
JournalItem getJournalItem(unsigned int id);
|
||||
|
||||
void addKill(const std::string &refId, int number);
|
||||
std::tuple<std::string, int> getKill(unsigned int i) const;
|
||||
|
||||
private:
|
||||
Player *player;
|
||||
bool changedKills, changedJournal;
|
||||
};
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 14.05.16.
|
||||
//
|
||||
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
#include "PublicFnAPI.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
unordered_map<string, Public *> Public::publics;
|
||||
|
||||
Public::~Public()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Public::Public(ScriptFunc _public, const std::string &name, char ret_type, const std::string &def) : ScriptFunction(_public, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
|
||||
Public::Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, char ret_type, const std::string &def) : ScriptFunction(
|
||||
_public, lua, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
Public::Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def): ScriptFunction(_public, amx, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
boost::any Public::Call(const std::string &name, const std::vector<boost::any> &args)
|
||||
{
|
||||
auto it = publics.find(name);
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->ScriptFunction::Call(args);
|
||||
}
|
||||
|
||||
|
||||
const std::string &Public::GetDefinition(const std::string &name)
|
||||
{
|
||||
auto it = publics.find(name);
|
||||
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->def;
|
||||
}
|
||||
|
||||
|
||||
bool Public::IsLua(const std::string &name)
|
||||
{
|
||||
#if !defined(ENABLE_LUA)
|
||||
return false;
|
||||
#else
|
||||
auto it = publics.find(name);
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->script_type == SCRIPT_LUA;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Public::IsPAWN(const std::string &name)
|
||||
{
|
||||
#if !defined(ENABLE_PAWN)
|
||||
return false;
|
||||
#else
|
||||
auto it = publics.find(name);
|
||||
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->script_type == SCRIPT_PAWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Public::DeleteAll()
|
||||
{
|
||||
for (auto it = publics.begin(); it != publics.end(); it++)
|
||||
{
|
||||
Public *_public = it->second;
|
||||
delete _public;
|
||||
publics.erase(it);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 14.05.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
||||
#define PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
|
||||
|
||||
class Public : public ScriptFunction
|
||||
{
|
||||
private:
|
||||
~Public();
|
||||
|
||||
static std::unordered_map<std::string, Public *> publics;
|
||||
|
||||
Public(ScriptFunc _public, const std::string &name, char ret_type, const std::string &def);
|
||||
#if defined(ENABLE_PAWN)
|
||||
Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, char ret_type, const std::string &def);
|
||||
#endif
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static void MakePublic(Args &&... args)
|
||||
{ new Public(std::forward<Args>(args)...); }
|
||||
|
||||
static boost::any Call(const std::string &name, const std::vector<boost::any> &args);
|
||||
|
||||
static const std::string& GetDefinition(const std::string& name);
|
||||
|
||||
static bool IsPAWN(const std::string &name);
|
||||
static bool IsLua(const std::string &name);
|
||||
|
||||
static void DeleteAll();
|
||||
};
|
||||
|
||||
#endif //PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
@ -1,238 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 15.03.16.
|
||||
//
|
||||
|
||||
#include "TimerAPI.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <iostream>
|
||||
using namespace mwmp;
|
||||
using namespace std;
|
||||
|
||||
Timer::Timer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args) : ScriptFunction(callback, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
Timer::Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string &def, std::vector<boost::any> args): ScriptFunction(callback, amx, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Timer::Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args): ScriptFunction(callback, lua, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Timer::Tick()
|
||||
{
|
||||
if (end)
|
||||
return;
|
||||
|
||||
const auto duration = chrono::system_clock::now().time_since_epoch();
|
||||
const auto time = chrono::duration_cast<chrono::milliseconds>(duration).count();
|
||||
|
||||
if (time - startTime >= targetMsec)
|
||||
{
|
||||
end = true;
|
||||
Call(args);
|
||||
}
|
||||
}
|
||||
|
||||
bool Timer::IsEnd()
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
void Timer::Stop()
|
||||
{
|
||||
end = true;
|
||||
}
|
||||
|
||||
void Timer::Restart(int msec)
|
||||
{
|
||||
targetMsec = msec;
|
||||
Start();
|
||||
}
|
||||
|
||||
void Timer::Start()
|
||||
{
|
||||
end = false;
|
||||
|
||||
const auto duration = chrono::system_clock::now().time_since_epoch();
|
||||
const auto msec = chrono::duration_cast<chrono::milliseconds>(duration).count();
|
||||
startTime = msec;
|
||||
}
|
||||
|
||||
int TimerAPI::pointer = 0;
|
||||
std::unordered_map<int, Timer* > TimerAPI::timers;
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
int TimerAPI::CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const string& def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(amx, callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(amx, callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_LUA)
|
||||
int TimerAPI::CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(lua, callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(lua, callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int TimerAPI::CreateTimer(ScriptFunc callback, long msec, const std::string &def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void TimerAPI::FreeTimer(int timerid)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (timers.at(timerid) != nullptr)
|
||||
{
|
||||
delete timers[timerid];
|
||||
timers[timerid] = nullptr;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::ResetTimer(int timerid, long msec)
|
||||
{
|
||||
try
|
||||
{
|
||||
timers.at(timerid)->Restart(msec);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::StartTimer(int timerid)
|
||||
{
|
||||
try
|
||||
{
|
||||
Timer *timer = timers.at(timerid);
|
||||
if (timer == nullptr)
|
||||
throw 1;
|
||||
timer->Start();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::StopTimer(int timerid)
|
||||
{
|
||||
try
|
||||
{
|
||||
timers.at(timerid)->Stop();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool TimerAPI::IsEndTimer(int timerid)
|
||||
{
|
||||
bool ret = false;
|
||||
try
|
||||
{
|
||||
ret = timers.at(timerid)->IsEnd();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TimerAPI::Terminate()
|
||||
{
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
delete timer.second;
|
||||
timer.second = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::Tick()
|
||||
{
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
timer.second->Tick();
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 15.03.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_TIMERAPI_HPP
|
||||
#define OPENMW_TIMERAPI_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Script/Script.hpp>
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
|
||||
class TimerAPI;
|
||||
|
||||
class Timer: public ScriptFunction
|
||||
{
|
||||
friend class TimerAPI;
|
||||
|
||||
public:
|
||||
|
||||
Timer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#if defined(ENABLE_PAWN)
|
||||
Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
void Tick();
|
||||
|
||||
bool IsEnd();
|
||||
void Stop();
|
||||
void Start();
|
||||
void Restart(int msec);
|
||||
private:
|
||||
double startTime, targetMsec;
|
||||
std::string publ, arg_types;
|
||||
std::vector<boost::any> args;
|
||||
Script *scr;
|
||||
bool end;
|
||||
};
|
||||
|
||||
class TimerAPI
|
||||
{
|
||||
public:
|
||||
#if defined(ENABLE_PAWN)
|
||||
static int CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
static int CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
static int CreateTimer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
static void FreeTimer(int timerid);
|
||||
static void ResetTimer(int timerid, long msec);
|
||||
static void StartTimer(int timerid);
|
||||
static void StopTimer(int timerid);
|
||||
static bool IsEndTimer(int timerid);
|
||||
|
||||
static void Terminate();
|
||||
|
||||
static void Tick();
|
||||
private:
|
||||
static std::unordered_map<int, Timer* > timers;
|
||||
static int pointer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OPENMW_TIMERAPI_HPP
|
@ -0,0 +1,102 @@
|
||||
//
|
||||
// Created by koncord on 08.08.17.
|
||||
//
|
||||
#include "CommandController.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "Player.hpp"
|
||||
#include "LuaState.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CommandController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table cmdCtrlTable = lua.getState()->create_named_table("CommandController");
|
||||
|
||||
cmdCtrlTable["registerCommand"] = [&lua](const std::string &command, sol::function func, const std::string &helpMessage) {
|
||||
return lua.getCmdCtrl().registerCommand(Misc::StringUtils::lowerCase(command), func, helpMessage);
|
||||
};
|
||||
|
||||
cmdCtrlTable["unregisterCommand"] = [&lua](const std::string &command) {
|
||||
lua.getCmdCtrl().unregisterCommand(Misc::StringUtils::lowerCase(command));
|
||||
};
|
||||
|
||||
cmdCtrlTable["hasCommand"] = [&lua](const std::string &command) {
|
||||
return lua.getCmdCtrl().hasCommand(Misc::StringUtils::lowerCase(command));
|
||||
};
|
||||
|
||||
cmdCtrlTable["getHelpStrings"] = [&lua]() {
|
||||
auto &commands = lua.getCmdCtrl().commands;
|
||||
sol::table helpTable = lua.getState()->create_table(commands.size(), 0);
|
||||
|
||||
for (const auto &cmd : commands)
|
||||
helpTable.add(cmd.first, cmd.second.helpMessage);
|
||||
|
||||
return helpTable;
|
||||
};
|
||||
}
|
||||
|
||||
bool CommandController::registerCommand(const std::string &command, sol::function func, const std::string &helpMessage)
|
||||
{
|
||||
auto iter = commands.find(command);
|
||||
if (iter == commands.end())
|
||||
{
|
||||
commands.emplace(command, Command {std::move(func), helpMessage});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandController::unregisterCommand(const std::string &command)
|
||||
{
|
||||
commands.erase(command);
|
||||
}
|
||||
|
||||
bool CommandController::hasCommand(const std::string &command)
|
||||
{
|
||||
return commands.find(command) != commands.end();
|
||||
}
|
||||
|
||||
std::pair<CommandController::ExecResult, std::string> CommandController::exec(std::shared_ptr<Player> player, const std::string &message)
|
||||
{
|
||||
char cmdChar = message[0];
|
||||
if (message.size() < 2 || (cmdChar != '/' && cmdChar != '!'))
|
||||
return make_pair(ExecResult::NOT_CMD, "");
|
||||
|
||||
auto tokens = cmdParser(message);
|
||||
|
||||
auto cmd = commands.find(Misc::StringUtils::lowerCase(&tokens[0][1]));
|
||||
if (cmd != commands.end())
|
||||
{
|
||||
tokens.pop_front();
|
||||
bool result = cmd->second.func(player, sol::as_table(tokens));
|
||||
if (result)
|
||||
return make_pair(ExecResult::SUCCESS, "");
|
||||
|
||||
return make_pair(ExecResult::FAIL, cmd->second.helpMessage);
|
||||
}
|
||||
|
||||
return make_pair(ExecResult::NOT_FOUND, "");
|
||||
}
|
||||
|
||||
std::deque<std::string> CommandController::cmdParser(const std::string &message)
|
||||
{
|
||||
deque<string> ret;
|
||||
namespace x3 = boost::spirit::x3;
|
||||
auto const sep = ' ';
|
||||
auto const quoted = '"' >> *~x3::char_('"') >> '"';
|
||||
auto const unquoted = *~x3::char_(sep);
|
||||
auto const arguments = (quoted | unquoted) % sep;
|
||||
/*auto const command = '/' >> *~x3::char_(sep) >> sep;
|
||||
|
||||
if (!x3::phrase_parse(message.cbegin(), message.cend(), arguments, command, ret))
|
||||
throw runtime_error("failed to parse message: "+ message);*/
|
||||
|
||||
if (!x3::parse(message.cbegin(), message.cend(), arguments, ret))
|
||||
throw runtime_error("failed to parse message: " + message);
|
||||
|
||||
return ret;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 08.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sol.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
class Player;
|
||||
class LuaState;
|
||||
|
||||
struct Command
|
||||
{
|
||||
sol::function func;
|
||||
std::string helpMessage;
|
||||
};
|
||||
|
||||
class CommandController
|
||||
{
|
||||
typedef std::unordered_map<std::string, Command> Container;
|
||||
typedef Container::iterator Iter;
|
||||
typedef Container::const_iterator CIter;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
enum class ExecResult : int
|
||||
{
|
||||
NOT_FOUND,
|
||||
SUCCESS,
|
||||
FAIL,
|
||||
NOT_CMD
|
||||
};
|
||||
|
||||
/**
|
||||
* Register new command. Only unique commands are allowed.
|
||||
* @param command name of command. Case sensitive. No need in command prefix ('/' or '!').
|
||||
* @param helpMessage help message. Shows in the '/help' command also appears if exec() fails.
|
||||
* @param callback Will be called when command is called.
|
||||
* @return false if the command already registered.
|
||||
*/
|
||||
bool registerCommand(const std::string &command, sol::function callback, const std::string &helpMessage);
|
||||
/**
|
||||
* Removes a registered command
|
||||
* @param command name of command.
|
||||
*/
|
||||
void unregisterCommand(const std::string &command);
|
||||
|
||||
/**
|
||||
* Check a command is exist.
|
||||
* @param command name of command
|
||||
* @return false if the command did not exist.
|
||||
*/
|
||||
bool hasCommand(const std::string &command);
|
||||
|
||||
std::pair<ExecResult, std::string> exec(std::shared_ptr<Player> player, const std::string &message);
|
||||
private:
|
||||
std::deque<std::string> cmdParser(const std::string &message);
|
||||
Container commands;
|
||||
};
|
@ -0,0 +1,152 @@
|
||||
//
|
||||
// Created by koncord on 30.07.17.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "EventController.hpp"
|
||||
|
||||
using namespace std;
|
||||
#define ADD_CORE_EVENT(event) #event, CoreEvent::event
|
||||
void EventController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table eventsTable = lua.getState()->create_named_table("Event");
|
||||
|
||||
eventsTable["register"] = [&lua](int event, sol::function func, sol::this_environment te) {
|
||||
sol::environment& env = te;
|
||||
lua.getEventCtrl().registerEvent(event, env, func);
|
||||
};
|
||||
eventsTable["stop"] = [&lua](int event) {
|
||||
lua.getEventCtrl().stop(event);
|
||||
};
|
||||
eventsTable["create"] = [&lua]() {
|
||||
return lua.getEventCtrl().createEvent();
|
||||
};
|
||||
eventsTable["raise"] = [&lua](unsigned event, sol::table data) {
|
||||
lua.getEventCtrl().raiseEvent(event, data);
|
||||
};
|
||||
eventsTable["raiseSpecified"] = [&lua](unsigned event, const std::string &moduleName, sol::table data) {
|
||||
lua.getEventCtrl().raiseEvent(event, data, moduleName);
|
||||
};
|
||||
}
|
||||
|
||||
EventController::EventController(LuaState *luaCtrl)
|
||||
{
|
||||
this->luaCtrl = luaCtrl;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
luaCtrl->getState()->new_enum<false>
|
||||
#else
|
||||
luaCtrl->getState()->new_enum
|
||||
#endif
|
||||
("Events",
|
||||
ADD_CORE_EVENT(ON_POST_INIT),
|
||||
ADD_CORE_EVENT(ON_EXIT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_CONNECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DISCONNECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DEATH),
|
||||
ADD_CORE_EVENT(ON_PLAYER_RESURRECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_CELLCHANGE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_KILLCOUNT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_ATTRIBUTE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SKILL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_LEVEL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_BOUNTY),
|
||||
ADD_CORE_EVENT(ON_PLAYER_EQUIPMENT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_INVENTORY),
|
||||
ADD_CORE_EVENT(ON_PLAYER_JOURNAL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_FACTION),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SHAPESHIFT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SPELLBOOK),
|
||||
ADD_CORE_EVENT(ON_PLAYER_TOPIC),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DISPOSITION),
|
||||
ADD_CORE_EVENT(ON_PLAYER_BOOK),
|
||||
ADD_CORE_EVENT(ON_PLAYER_MAP),
|
||||
ADD_CORE_EVENT(ON_PLAYER_REST),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SENDMESSAGE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_ENDCHARGEN),
|
||||
ADD_CORE_EVENT(ON_GUI_ACTION),
|
||||
ADD_CORE_EVENT(ON_REQUEST_PLUGIN_LIST),
|
||||
ADD_CORE_EVENT(ON_MP_REFNUM),
|
||||
ADD_CORE_EVENT(ON_ACTOR_EQUIPMENT),
|
||||
ADD_CORE_EVENT(ON_ACTOR_CELL_CHANGE),
|
||||
ADD_CORE_EVENT(ON_ACTOR_LIST),
|
||||
ADD_CORE_EVENT(ON_ACTOR_TEST),
|
||||
ADD_CORE_EVENT(ON_CELL_LOAD),
|
||||
ADD_CORE_EVENT(ON_CELL_UNLOAD),
|
||||
ADD_CORE_EVENT(ON_CELL_DELETION),
|
||||
ADD_CORE_EVENT(ON_CONTAINER),
|
||||
ADD_CORE_EVENT(ON_DOOR_STATE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_PLACE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_STATE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_SPAWN),
|
||||
ADD_CORE_EVENT(ON_OBJECT_DELETE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_LOCK),
|
||||
ADD_CORE_EVENT(ON_OBJECT_SCALE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_TRAP)
|
||||
);
|
||||
|
||||
sol::state &state = *luaCtrl->getState();
|
||||
sol::table eventsEnum = state["Events"];
|
||||
for (int i = CoreEvent::FIRST; i < CoreEvent::LAST; ++i)
|
||||
{
|
||||
#ifdef SERVER_DEBUG
|
||||
bool found = false;
|
||||
eventsEnum.for_each([&found, &i](sol::object key, sol::object value){
|
||||
if (value.as<int>() == i)
|
||||
{
|
||||
found = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found)
|
||||
throw runtime_error("Event " + to_string(i) + " is not registered. Dear developer, please fix me :D");
|
||||
#endif
|
||||
events[i]; // create core event
|
||||
}
|
||||
}
|
||||
|
||||
void EventController::registerEvent(int event, sol::environment &env, sol::function& func)
|
||||
{
|
||||
auto iter = events.find(event);
|
||||
if (iter != events.end())
|
||||
iter->second.push(env, func);
|
||||
}
|
||||
|
||||
void EventController::stop(int event)
|
||||
{
|
||||
printf("EventController::stop\n");
|
||||
auto iter = events.find(event);
|
||||
if (iter != events.end())
|
||||
iter->second.stop();
|
||||
}
|
||||
|
||||
CallbackCollection &EventController::GetEvents(Event event)
|
||||
{
|
||||
return events.at(event);
|
||||
}
|
||||
|
||||
Event EventController::createEvent()
|
||||
{
|
||||
events[lastEvent];
|
||||
return lastEvent++;
|
||||
}
|
||||
|
||||
void EventController::raiseEvent(Event id, sol::table data, const string &moduleName)
|
||||
{
|
||||
auto iter = events.find(id);
|
||||
if (iter != events.end())
|
||||
{
|
||||
if (!moduleName.empty())
|
||||
{
|
||||
auto f = std::find_if (iter->second.begin(), iter->second.end(), [&moduleName](const auto &item){
|
||||
return item.first["ModuleName"]["name"] == moduleName;
|
||||
});
|
||||
if (f != iter->second.end())
|
||||
f->second.call(data); // call only specified mod
|
||||
}
|
||||
iter->second.call(CallbackCollection::type_tag<void>(), data); // call all registered events with this id
|
||||
}
|
||||
else
|
||||
cerr << "Event with id: " << id << " is not registered" << endl;
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
//
|
||||
// Created by koncord on 30.07.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sol.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "LuaState.hpp"
|
||||
|
||||
typedef unsigned Event;
|
||||
|
||||
namespace CoreEvent
|
||||
{
|
||||
enum
|
||||
{
|
||||
ON_EXIT = 0,
|
||||
ON_POST_INIT,
|
||||
ON_REQUEST_PLUGIN_LIST,
|
||||
ON_PLAYER_CONNECT,
|
||||
ON_PLAYER_DISCONNECT,
|
||||
ON_PLAYER_DEATH,
|
||||
ON_PLAYER_RESURRECT,
|
||||
ON_PLAYER_CELLCHANGE,
|
||||
ON_PLAYER_KILLCOUNT,
|
||||
ON_PLAYER_ATTRIBUTE,
|
||||
ON_PLAYER_SKILL,
|
||||
ON_PLAYER_LEVEL,
|
||||
ON_PLAYER_BOUNTY,
|
||||
ON_PLAYER_EQUIPMENT,
|
||||
ON_PLAYER_INVENTORY,
|
||||
ON_PLAYER_JOURNAL,
|
||||
ON_PLAYER_FACTION,
|
||||
ON_PLAYER_SHAPESHIFT,
|
||||
ON_PLAYER_SPELLBOOK,
|
||||
ON_PLAYER_TOPIC,
|
||||
ON_PLAYER_DISPOSITION,
|
||||
ON_PLAYER_BOOK,
|
||||
ON_PLAYER_MAP,
|
||||
ON_PLAYER_REST,
|
||||
ON_PLAYER_SENDMESSAGE,
|
||||
ON_PLAYER_ENDCHARGEN,
|
||||
|
||||
ON_GUI_ACTION,
|
||||
ON_MP_REFNUM,
|
||||
|
||||
ON_ACTOR_EQUIPMENT,
|
||||
ON_ACTOR_CELL_CHANGE,
|
||||
ON_ACTOR_LIST,
|
||||
ON_ACTOR_TEST,
|
||||
|
||||
ON_CELL_LOAD,
|
||||
ON_CELL_UNLOAD,
|
||||
ON_CELL_DELETION,
|
||||
|
||||
ON_CONTAINER,
|
||||
ON_DOOR_STATE,
|
||||
ON_OBJECT_PLACE,
|
||||
ON_OBJECT_STATE,
|
||||
ON_OBJECT_SPAWN,
|
||||
ON_OBJECT_DELETE,
|
||||
ON_OBJECT_LOCK,
|
||||
ON_OBJECT_SCALE,
|
||||
ON_OBJECT_TRAP,
|
||||
|
||||
LAST,
|
||||
};
|
||||
const int FIRST = ON_EXIT;
|
||||
}
|
||||
|
||||
class CallbackCollection // todo: add sort by dependencies
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<sol::environment, sol::function>> Container;
|
||||
typedef Container::iterator Iterator;
|
||||
typedef Container::const_iterator CIterator;
|
||||
|
||||
template<typename> struct type_tag {};
|
||||
|
||||
void push(sol::environment &env, sol::function &func) { functions.emplace_back(env, func); }
|
||||
CIterator begin() const { return functions.begin(); }
|
||||
CIterator end() const { return functions.end(); }
|
||||
|
||||
void stop() {_stop = true;}
|
||||
bool isStoped() const {return _stop;}
|
||||
CIterator stopedAt() const { return lastCalled; }
|
||||
|
||||
template<typename... Args>
|
||||
void call(type_tag<void>, Args&&... args)
|
||||
{
|
||||
lastCalled = functions.end();
|
||||
_stop = false;
|
||||
for (CIterator iter = functions.begin(); iter != functions.end(); ++iter)
|
||||
{
|
||||
if (!_stop)
|
||||
iter->second.call(std::forward<Args>(args)...);
|
||||
else
|
||||
{
|
||||
lastCalled = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename R, typename... Args>
|
||||
decltype(auto) call(type_tag<R>, Args&&... args)
|
||||
{
|
||||
R ret;
|
||||
|
||||
lastCalled = functions.end();
|
||||
_stop = false;
|
||||
for (CIterator iter = functions.begin(); iter != functions.end(); ++iter)
|
||||
{
|
||||
if (!_stop)
|
||||
ret = iter->second.call(std::forward<Args>(args)...);
|
||||
else
|
||||
{
|
||||
lastCalled = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
Container functions;
|
||||
CIterator lastCalled;
|
||||
bool _stop = false;
|
||||
};
|
||||
|
||||
class EventController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit EventController(LuaState *luaCtrl);
|
||||
typedef std::unordered_map<int, CallbackCollection> Container;
|
||||
|
||||
void registerEvent(int event, sol::environment &env, sol::function& func);
|
||||
CallbackCollection& GetEvents(Event event);
|
||||
Event createEvent();
|
||||
void raiseEvent(Event id, sol::table data, const std::string &moduleName = "");
|
||||
void stop(int event);
|
||||
|
||||
template<Event event, typename R = void, typename... Args>
|
||||
R Call(Args&&... args)
|
||||
{
|
||||
return events.at(event).call(CallbackCollection::type_tag<R>{}, std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
Container events;
|
||||
Event lastEvent = CoreEvent::LAST;
|
||||
LuaState *luaCtrl;
|
||||
};
|
@ -1,330 +0,0 @@
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Base/BaseActor.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Utils.hpp>
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
|
||||
#include <components/esm/creaturestats.hpp>
|
||||
|
||||
#include "Actors.hpp"
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
BaseActorList *readActorList;
|
||||
BaseActorList writeActorList;
|
||||
|
||||
BaseActor tempActor;
|
||||
const BaseActor emptyActor = {};
|
||||
|
||||
static std::string tempCellDescription;
|
||||
|
||||
void ActorFunctions::ReadLastActorList() noexcept
|
||||
{
|
||||
readActorList = mwmp::Networking::getPtr()->getLastActorList();
|
||||
}
|
||||
|
||||
void ActorFunctions::ReadCellActorList(const char* cellDescription) noexcept
|
||||
{
|
||||
ESM::Cell esmCell = Utils::getCellFromDescription(cellDescription);
|
||||
Cell *serverCell = CellController::get()->getCell(&esmCell);
|
||||
readActorList = serverCell->getActorList();
|
||||
}
|
||||
|
||||
void ActorFunctions::InitializeActorList(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
writeActorList.cell.blank();
|
||||
writeActorList.baseActors.clear();
|
||||
writeActorList.guid = player->guid;
|
||||
}
|
||||
|
||||
unsigned int ActorFunctions::GetActorListSize() noexcept
|
||||
{
|
||||
return readActorList->count;
|
||||
}
|
||||
|
||||
unsigned char ActorFunctions::GetActorListAction() noexcept
|
||||
{
|
||||
return readActorList->action;
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorCell(unsigned int i) noexcept
|
||||
{
|
||||
tempCellDescription = readActorList->baseActors.at(i).cell.getDescription();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorRefId(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorRefNumIndex(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).refNumIndex;
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorMpNum(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).mpNum;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosX(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[0];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosY(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[1];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosZ(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[2];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotX(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[0];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotY(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[1];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotZ(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[2];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mMod;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mMod;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mMod;
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorEquipmentItemRefId(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].refId.c_str();
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorEquipmentItemCount(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].count;
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorEquipmentItemCharge(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].charge;
|
||||
}
|
||||
|
||||
bool ActorFunctions::DoesActorHavePosition(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).hasPositionData;
|
||||
}
|
||||
|
||||
bool ActorFunctions::DoesActorHaveStatsDynamic(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).hasStatsDynamicData;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorListCell(const char* cellDescription) noexcept
|
||||
{
|
||||
writeActorList.cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorListAction(unsigned char action) noexcept
|
||||
{
|
||||
writeActorList.action = action;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorCell(const char* cellDescription) noexcept
|
||||
{
|
||||
tempActor.cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRefId(const char* refId) noexcept
|
||||
{
|
||||
tempActor.refId = refId;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRefNumIndex(int refNumIndex) noexcept
|
||||
{
|
||||
tempActor.refNumIndex = refNumIndex;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMpNum(int mpNum) noexcept
|
||||
{
|
||||
tempActor.mpNum = mpNum;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorPosition(double x, double y, double z) noexcept
|
||||
{
|
||||
tempActor.position.pos[0] = x;
|
||||
tempActor.position.pos[1] = y;
|
||||
tempActor.position.pos[2] = z;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRotation(double x, double y, double z) noexcept
|
||||
{
|
||||
tempActor.position.rot[0] = x;
|
||||
tempActor.position.rot[1] = y;
|
||||
tempActor.position.rot[2] = z;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::EquipActorItem(unsigned short slot, const char *refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
tempActor.equipedItems[slot].refId = refId;
|
||||
tempActor.equipedItems[slot].count = count;
|
||||
tempActor.equipedItems[slot].charge = charge;
|
||||
}
|
||||
|
||||
void ActorFunctions::UnequipActorItem(unsigned short slot) noexcept
|
||||
{
|
||||
ActorFunctions::EquipActorItem(slot, "", 0, -1);
|
||||
}
|
||||
|
||||
void ActorFunctions::AddActor() noexcept
|
||||
{
|
||||
writeActorList.baseActors.push_back(tempActor);
|
||||
|
||||
tempActor = emptyActor;
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorList() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorAuthority() noexcept
|
||||
{
|
||||
Cell *serverCell = CellController::get()->getCell(&writeActorList.cell);
|
||||
|
||||
if (serverCell != nullptr)
|
||||
{
|
||||
serverCell->setAuthority(writeActorList.guid);
|
||||
|
||||
mwmp::ActorPacket *authorityPacket = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_AUTHORITY);
|
||||
authorityPacket->setActorList(&writeActorList);
|
||||
authorityPacket->Send(writeActorList.guid);
|
||||
|
||||
// Also send this to everyone else who has the cell loaded
|
||||
serverCell->sendToLoaded(authorityPacket, &writeActorList);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorPosition() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_POSITION)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_POSITION)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorStatsDynamic() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_STATS_DYNAMIC)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_STATS_DYNAMIC)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorEquipment() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_EQUIPMENT)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_EQUIPMENT)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorCellChange() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_CELL_CHANGE)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_CELL_CHANGE)->Send(writeActorList.guid);
|
||||
}
|
||||
|
@ -1,563 +0,0 @@
|
||||
#ifndef OPENMW_ACTORAPI_HPP
|
||||
#define OPENMW_ACTORAPI_HPP
|
||||
|
||||
#define ACTORAPI \
|
||||
{"ReadLastActorList", ActorFunctions::ReadLastActorList},\
|
||||
{"ReadCellActorList", ActorFunctions::ReadCellActorList},\
|
||||
{"InitializeActorList", ActorFunctions::InitializeActorList},\
|
||||
\
|
||||
{"GetActorListSize", ActorFunctions::GetActorListSize},\
|
||||
{"GetActorListAction", ActorFunctions::GetActorListAction},\
|
||||
\
|
||||
{"GetActorCell", ActorFunctions::GetActorCell},\
|
||||
{"GetActorRefId", ActorFunctions::GetActorRefId},\
|
||||
{"GetActorRefNumIndex", ActorFunctions::GetActorRefNumIndex},\
|
||||
{"GetActorMpNum", ActorFunctions::GetActorMpNum},\
|
||||
\
|
||||
{"GetActorPosX", ActorFunctions::GetActorPosX},\
|
||||
{"GetActorPosY", ActorFunctions::GetActorPosY},\
|
||||
{"GetActorPosZ", ActorFunctions::GetActorPosZ},\
|
||||
{"GetActorRotX", ActorFunctions::GetActorRotX},\
|
||||
{"GetActorRotY", ActorFunctions::GetActorRotY},\
|
||||
{"GetActorRotZ", ActorFunctions::GetActorRotZ},\
|
||||
\
|
||||
{"GetActorHealthBase", ActorFunctions::GetActorHealthBase},\
|
||||
{"GetActorHealthCurrent", ActorFunctions::GetActorHealthCurrent},\
|
||||
{"GetActorHealthModified", ActorFunctions::GetActorHealthModified},\
|
||||
{"GetActorMagickaBase", ActorFunctions::GetActorMagickaBase},\
|
||||
{"GetActorMagickaCurrent", ActorFunctions::GetActorMagickaCurrent},\
|
||||
{"GetActorMagickaModified", ActorFunctions::GetActorMagickaModified},\
|
||||
{"GetActorFatigueBase", ActorFunctions::GetActorFatigueBase},\
|
||||
{"GetActorFatigueCurrent", ActorFunctions::GetActorFatigueCurrent},\
|
||||
{"GetActorFatigueModified", ActorFunctions::GetActorFatigueModified},\
|
||||
\
|
||||
{"GetActorEquipmentItemRefId", ActorFunctions::GetActorEquipmentItemRefId},\
|
||||
{"GetActorEquipmentItemCount", ActorFunctions::GetActorEquipmentItemCount},\
|
||||
{"GetActorEquipmentItemCharge", ActorFunctions::GetActorEquipmentItemCharge},\
|
||||
\
|
||||
{"DoesActorHavePosition", ActorFunctions::DoesActorHavePosition},\
|
||||
{"DoesActorHaveStatsDynamic", ActorFunctions::DoesActorHaveStatsDynamic},\
|
||||
\
|
||||
{"SetActorListCell", ActorFunctions::SetActorListCell},\
|
||||
{"SetActorListAction", ActorFunctions::SetActorListAction},\
|
||||
\
|
||||
{"SetActorCell", ActorFunctions::SetActorCell},\
|
||||
{"SetActorRefId", ActorFunctions::SetActorRefId},\
|
||||
{"SetActorRefNumIndex", ActorFunctions::SetActorRefNumIndex},\
|
||||
{"SetActorMpNum", ActorFunctions::SetActorMpNum},\
|
||||
\
|
||||
{"SetActorPosition", ActorFunctions::SetActorPosition},\
|
||||
{"SetActorRotation", ActorFunctions::SetActorRotation},\
|
||||
\
|
||||
{"SetActorHealthBase", ActorFunctions::SetActorHealthBase},\
|
||||
{"SetActorHealthCurrent", ActorFunctions::SetActorHealthCurrent},\
|
||||
{"SetActorHealthModified", ActorFunctions::SetActorHealthModified},\
|
||||
{"SetActorMagickaBase", ActorFunctions::SetActorMagickaBase},\
|
||||
{"SetActorMagickaCurrent", ActorFunctions::SetActorMagickaCurrent},\
|
||||
{"SetActorMagickaModified", ActorFunctions::SetActorMagickaModified},\
|
||||
{"SetActorFatigueBase", ActorFunctions::SetActorFatigueBase},\
|
||||
{"SetActorFatigueCurrent", ActorFunctions::SetActorFatigueCurrent},\
|
||||
{"SetActorFatigueModified", ActorFunctions::SetActorFatigueModified},\
|
||||
\
|
||||
{"EquipActorItem", ActorFunctions::EquipActorItem},\
|
||||
{"UnequipActorItem", ActorFunctions::UnequipActorItem},\
|
||||
\
|
||||
{"AddActor", ActorFunctions::AddActor},\
|
||||
\
|
||||
{"SendActorList", ActorFunctions::SendActorList},\
|
||||
{"SendActorAuthority", ActorFunctions::SendActorAuthority},\
|
||||
{"SendActorPosition", ActorFunctions::SendActorPosition},\
|
||||
{"SendActorStatsDynamic", ActorFunctions::SendActorStatsDynamic},\
|
||||
{"SendActorEquipment", ActorFunctions::SendActorEquipment},\
|
||||
{"SendActorCellChange", ActorFunctions::SendActorCellChange}
|
||||
|
||||
class ActorFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Use the last actor list received by the server as the one being read.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void ReadLastActorList() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Use the temporary actor list stored for a cell as the one being read.
|
||||
*
|
||||
* This type of actor list is used to store actor positions and dynamic stats and is deleted
|
||||
* when the cell is unloaded.
|
||||
*
|
||||
* \param cellDescription The description of the cell whose actor list should be read.
|
||||
* \return void
|
||||
*/
|
||||
static void ReadCellActorList(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Clear the data from the last actor list sent by the server.
|
||||
*
|
||||
* This is used to initialize the sending of new Actor packets.
|
||||
*
|
||||
* \param pid The player ID to whom the actor list should be attached.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeActorList(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in the read actor list.
|
||||
*
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetActorListSize() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in the read actor list.
|
||||
*
|
||||
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
*/
|
||||
static unsigned char GetActorListAction() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetActorCell(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetActorRefId(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refNumIndex of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The refNumIndex.
|
||||
*/
|
||||
static int GetActorRefNumIndex(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the mpNum of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The mpNum.
|
||||
*/
|
||||
static int GetActorMpNum(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The X position.
|
||||
*/
|
||||
static double GetActorPosX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Y position.
|
||||
*/
|
||||
static double GetActorPosY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Z position.
|
||||
*/
|
||||
static double GetActorPosZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The X rotation.
|
||||
*/
|
||||
static double GetActorRotX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Y rotation.
|
||||
*/
|
||||
static double GetActorRotY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Z rotation.
|
||||
*/
|
||||
static double GetActorRotZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base health.
|
||||
*/
|
||||
static double GetActorHealthBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current health.
|
||||
*/
|
||||
static double GetActorHealthCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified health.
|
||||
*/
|
||||
static double GetActorHealthModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base magicka.
|
||||
*/
|
||||
static double GetActorMagickaBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current magicka.
|
||||
*/
|
||||
static double GetActorMagickaCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified magicka.
|
||||
*/
|
||||
static double GetActorMagickaModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base fatigue.
|
||||
*/
|
||||
static double GetActorFatigueBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current fatigue.
|
||||
*/
|
||||
static double GetActorFatigueCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified fatigue.
|
||||
*/
|
||||
static double GetActorFatigueModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetActorEquipmentItemRefId(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the count of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The item count.
|
||||
*/
|
||||
static int GetActorEquipmentItemCount(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the charge of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The charge.
|
||||
*/
|
||||
static int GetActorEquipmentItemCharge(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether there is any positional data for the actor at a certain index in
|
||||
* the read actor list.
|
||||
*
|
||||
* This is only useful when reading the actor list data recorded for a particular cell.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return Whether the read actor list contains positional data.
|
||||
*/
|
||||
static bool DoesActorHavePosition(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether there is any dynamic stats data for the actor at a certain index in
|
||||
* the read actor list.
|
||||
*
|
||||
* This is only useful when reading the actor list data recorded for a particular cell.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return Whether the read actor list contains dynamic stats data.
|
||||
*/
|
||||
static bool DoesActorHaveStatsDynamic(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of the temporary actor list stored on the server.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param cellDescription The description of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorListCell(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type of the temporary actor list stored on the server.
|
||||
*
|
||||
* \param action The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorListAction(unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of the temporary actor stored on the server.
|
||||
*
|
||||
* Used for ActorCellChange packets, where a specific actor's cell now differs from that of the
|
||||
* actor list.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param cellDescription The description of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorCell(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refId of the temporary actor stored on the server.
|
||||
*
|
||||
* \param refId The refId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRefId(const char* refId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refNumIndex of the temporary actor stored on the server.
|
||||
*
|
||||
* \param refNumIndex The refNumIndex.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRefNumIndex(int refNumIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the mpNum of the temporary actor stored on the server.
|
||||
*
|
||||
* \param mpNum The mpNum.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMpNum(int mpNum) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the position of the temporary actor stored on the server.
|
||||
*
|
||||
* \param x The X position.
|
||||
* \param y The Y position.
|
||||
* \param z The Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorPosition(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rotation of the temporary actor stored on the server.
|
||||
*
|
||||
* \param x The X rotation.
|
||||
* \param y The Y rotation.
|
||||
* \param z The Z rotation.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRotation(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Equip an item in a certain slot of the equipment of the temporary actor stored
|
||||
* on the server.
|
||||
*
|
||||
* \param slot The equipment slot.
|
||||
* \param refId The refId of the item.
|
||||
* \param count The count of the item.
|
||||
* \param charge The charge of the item.
|
||||
* \return void
|
||||
*/
|
||||
static void EquipActorItem(unsigned short slot, const char* refId, unsigned int count, int charge) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Unequip the item in a certain slot of the equipment of the temporary actor stored
|
||||
* on the server.
|
||||
*
|
||||
* \param slot The equipment slot.
|
||||
* \return void
|
||||
*/
|
||||
static void UnequipActorItem(unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a copy of the server's temporary actor to the server's temporary actor list.
|
||||
*
|
||||
* In the process, the server's temporary actor will automatically be cleared so a new
|
||||
* one can be set up.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void AddActor() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorList packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorList() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorAuthority packet.
|
||||
*
|
||||
* The player for whom the current actor list was initialized is recorded in the server memory
|
||||
* as the new actor authority for the actor list's cell.
|
||||
*
|
||||
* The packet is sent to that player as well as all other players who have the cell loaded.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorAuthority() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorPosition packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorPosition() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorStatsDynamic packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorStatsDynamic() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorEquipment packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorEquipment() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorCellChange packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorCellChange() noexcept;
|
||||
};
|
||||
|
||||
|
||||
#endif //OPENMW_ACTORAPI_HPP
|
@ -1,55 +0,0 @@
|
||||
#include "Books.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void BookFunctions::InitializeBookChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
return player->bookChanges.books.clear();
|
||||
}
|
||||
|
||||
unsigned int BookFunctions::GetBookChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->bookChanges.count;
|
||||
}
|
||||
|
||||
void BookFunctions::AddBook(unsigned short pid, const char* bookId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Book book;
|
||||
book.bookId = bookId;
|
||||
|
||||
player->bookChanges.books.push_back(book);
|
||||
}
|
||||
|
||||
const char *BookFunctions::GetBookId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->bookChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->bookChanges.books.at(i).bookId.c_str();
|
||||
}
|
||||
|
||||
void BookFunctions::SendBookChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->Send(toOthers);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
#ifndef OPENMW_BOOKAPI_HPP
|
||||
#define OPENMW_BOOKAPI_HPP
|
||||
|
||||
#define BOOKAPI \
|
||||
{"InitializeBookChanges", BookFunctions::InitializeBookChanges},\
|
||||
\
|
||||
{"GetBookChangesSize", BookFunctions::GetBookChangesSize},\
|
||||
\
|
||||
{"AddBook", BookFunctions::AddBook},\
|
||||
\
|
||||
{"GetBookId", BookFunctions::GetBookId},\
|
||||
\
|
||||
{"SendBookChanges", BookFunctions::SendBookChanges}
|
||||
|
||||
class BookFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded book changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerBook packets.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeBookChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetBookChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new book to the book changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param bookId The bookId of the book.
|
||||
* \return void
|
||||
*/
|
||||
static void AddBook(unsigned short pid, const char* bookId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the bookId at a certain index in a player's latest book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param i The index of the book.
|
||||
* \return The bookId.
|
||||
*/
|
||||
static const char *GetBookId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerBook packet with a player's recorded book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendBookChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_BOOKAPI_HPP
|
@ -1,151 +0,0 @@
|
||||
#include "Cells.hpp"
|
||||
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
static std::string tempCellDescription;
|
||||
|
||||
void CellFunctions::InitializeMapChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->mapChanges.cellsExplored.clear();
|
||||
}
|
||||
|
||||
unsigned int CellFunctions::GetCellStateChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cellStateChanges.count;
|
||||
}
|
||||
|
||||
unsigned int CellFunctions::GetCellStateType(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cellStateChanges.cellStates.at(i).type;
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->cellStateChanges.count)
|
||||
return "invalid";
|
||||
|
||||
tempCellDescription = player->cellStateChanges.cellStates.at(i).cell.getDescription();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetCell(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
tempCellDescription = player->cell.getDescription().c_str();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
int CellFunctions::GetExteriorX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->cell.mData.mX;
|
||||
}
|
||||
|
||||
int CellFunctions::GetExteriorY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->cell.mData.mY;
|
||||
}
|
||||
|
||||
bool CellFunctions::IsInExterior(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->cell.isExterior();
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetRegion(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cell.mRegion.c_str();
|
||||
}
|
||||
|
||||
bool CellFunctions::IsChangingRegion(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->isChangingRegion;
|
||||
}
|
||||
|
||||
void CellFunctions::SetCell(unsigned short pid, const char *cellDescription) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %s", player->npc.mName.c_str(),
|
||||
player->cell.getDescription().c_str(), cellDescription);
|
||||
|
||||
player->cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void CellFunctions::SetExteriorCell(unsigned short pid, int x, int y) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %i,%i", player->npc.mName.c_str(),
|
||||
player->cell.getDescription().c_str(), x, y);
|
||||
|
||||
// If the player is currently in an interior, turn off the interior flag
|
||||
// from the cell
|
||||
if (!player->cell.isExterior())
|
||||
player->cell.mData.mFlags &= ~ESM::Cell::Interior;
|
||||
|
||||
player->cell.mData.mX = x;
|
||||
player->cell.mData.mY = y;
|
||||
}
|
||||
|
||||
void CellFunctions::AddCellExplored(unsigned short pid, const char* cellDescription) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ESM::Cell cellExplored = Utils::getCellFromDescription(cellDescription);
|
||||
player->mapChanges.cellsExplored.push_back(cellExplored);
|
||||
}
|
||||
|
||||
void CellFunctions::SendCell(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CELL_CHANGE)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CELL_CHANGE)->Send(false);
|
||||
}
|
||||
|
||||
void CellFunctions::SendMapChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP)->Send(toOthers);
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
#ifndef OPENMW_CELLAPI_HPP
|
||||
#define OPENMW_CELLAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define CELLAPI \
|
||||
{"InitializeMapChanges", CellFunctions::InitializeMapChanges},\
|
||||
\
|
||||
{"GetCellStateChangesSize", CellFunctions::GetCellStateChangesSize},\
|
||||
\
|
||||
{"GetCellStateType", CellFunctions::GetCellStateType},\
|
||||
{"GetCellStateDescription", CellFunctions::GetCellStateDescription},\
|
||||
\
|
||||
{"GetCell", CellFunctions::GetCell},\
|
||||
{"GetExteriorX", CellFunctions::GetExteriorX},\
|
||||
{"GetExteriorY", CellFunctions::GetExteriorY},\
|
||||
{"IsInExterior", CellFunctions::IsInExterior},\
|
||||
\
|
||||
{"GetRegion", CellFunctions::GetRegion},\
|
||||
{"IsChangingRegion", CellFunctions::IsChangingRegion},\
|
||||
\
|
||||
{"SetCell", CellFunctions::SetCell},\
|
||||
{"SetExteriorCell", CellFunctions::SetExteriorCell},\
|
||||
\
|
||||
{"AddCellExplored", CellFunctions::AddCellExplored},\
|
||||
\
|
||||
{"SendCell", CellFunctions::SendCell},\
|
||||
{"SendMapChanges", CellFunctions::SendMapChanges}
|
||||
|
||||
|
||||
class CellFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded map changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerMap packets.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeMapChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetCellStateChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell state type at a certain index in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \param i The index of the cell state.
|
||||
* \return The cell state type (0 for LOAD, 1 for UNLOAD).
|
||||
*/
|
||||
static unsigned int GetCellStateType(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description at a certain index in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \param i The index of the cell state.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetCellStateDescription(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description of a player's cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetCell(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X coordinate of the player's exterior cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The X coordinate of the cell.
|
||||
*/
|
||||
static int GetExteriorX(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y coordinate of the player's exterior cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Y coordinate of the cell.
|
||||
*/
|
||||
static int GetExteriorY(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player is in an exterior cell or not.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player is in an exterior cell.
|
||||
*/
|
||||
static bool IsInExterior(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the region of the player's exterior cell.
|
||||
*
|
||||
* A blank value will be returned if the player is in an interior.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The region.
|
||||
*/
|
||||
static const char *GetRegion(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player's last cell change has involved a region change.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player has changed their region.
|
||||
*/
|
||||
static bool IsChangingRegion(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of a player.
|
||||
*
|
||||
* This changes the cell recorded for that player in the server memory, but does not by itself
|
||||
* send a packet.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param cellDescription The cell description.
|
||||
* \return void
|
||||
*/
|
||||
static void SetCell(unsigned short pid, const char *cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of a player to an exterior cell.
|
||||
*
|
||||
* This changes the cell recorded for that player in the server memory, but does not by itself
|
||||
* send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The X coordinate of the cell.
|
||||
* \param y The Y coordinate of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetExteriorCell(unsigned short pid, int x, int y) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new explored cell to the map changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \param cellDescription The cell description of the explored cell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddCellExplored(unsigned short pid, const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerCellChange packet about a player.
|
||||
*
|
||||
* It is only sent to the affected player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendCell(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerMap packet with a player's recorded map changes.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendMapChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_CELLAPI_HPP
|
@ -1,137 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.08.16.
|
||||
//
|
||||
|
||||
#include "CharClass.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ESM;
|
||||
|
||||
const char *CharClassFunctions::GetDefaultClass(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mId.c_str();
|
||||
}
|
||||
|
||||
const char *CharClassFunctions::GetClassName(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mName.c_str();
|
||||
}
|
||||
|
||||
const char *CharClassFunctions::GetClassDesc(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mDescription.c_str();
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMajorAttribute(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 1)
|
||||
throw invalid_argument("Incorrect attribute slot id");
|
||||
return player->charClass.mData.mAttribute[slot];
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassSpecialization(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->charClass.mData.mSpecialization;
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMajorSkill(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
return player->charClass.mData.mSkills[slot][1];
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMinorSkill(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
return player->charClass.mData.mSkills[slot][0];
|
||||
}
|
||||
|
||||
int CharClassFunctions::IsClassDefault(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return !player->charClass.mId.empty(); // true if default
|
||||
}
|
||||
|
||||
void CharClassFunctions::SetDefaultClass(unsigned short pid, const char *id) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mId = id;
|
||||
}
|
||||
void CharClassFunctions::SetClassName(unsigned short pid, const char *name) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mName = name;
|
||||
player->charClass.mId = "";
|
||||
}
|
||||
void CharClassFunctions::SetClassDesc(unsigned short pid, const char *desc) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mDescription = desc;
|
||||
}
|
||||
void CharClassFunctions::SetClassMajorAttribute(unsigned short pid, unsigned char slot, int attrId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (slot > 1)
|
||||
throw invalid_argument("Incorrect attribute slot id");
|
||||
|
||||
player->charClass.mData.mAttribute[slot] = attrId;
|
||||
|
||||
}
|
||||
void CharClassFunctions::SetClassSpecialization(unsigned short pid, int spec) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mData.mSpecialization = spec;
|
||||
}
|
||||
void CharClassFunctions::SetClassMajorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
player->charClass.mData.mSkills[slot][1] = skillId;
|
||||
}
|
||||
void CharClassFunctions::SetClassMinorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
player->charClass.mData.mSkills[slot][0] = skillId;
|
||||
}
|
||||
|
||||
void CharClassFunctions::SendClass(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS)->Send(false);
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_CHARCLASSAPI_HPP
|
||||
#define OPENMW_CHARCLASSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define CHARCLASSAPI \
|
||||
{"GetDefaultClass", CharClassFunctions::GetDefaultClass},\
|
||||
{"GetClassName", CharClassFunctions::GetClassName},\
|
||||
{"GetClassDesc", CharClassFunctions::GetClassDesc},\
|
||||
{"GetClassMajorAttribute", CharClassFunctions::GetClassMajorAttribute},\
|
||||
{"GetClassSpecialization", CharClassFunctions::GetClassSpecialization},\
|
||||
{"GetClassMajorSkill", CharClassFunctions::GetClassMajorSkill},\
|
||||
{"GetClassMinorSkill", CharClassFunctions::GetClassMinorSkill},\
|
||||
{"IsClassDefault", CharClassFunctions::IsClassDefault},\
|
||||
\
|
||||
{"SetDefaultClass", CharClassFunctions::SetDefaultClass},\
|
||||
{"SetClassName", CharClassFunctions::SetClassName},\
|
||||
{"SetClassDesc", CharClassFunctions::SetClassDesc},\
|
||||
{"SetClassMajorAttribute", CharClassFunctions::SetClassMajorAttribute},\
|
||||
{"SetClassSpecialization", CharClassFunctions::SetClassSpecialization},\
|
||||
{"SetClassMajorSkill", CharClassFunctions::SetClassMajorSkill},\
|
||||
{"SetClassMinorSkill", CharClassFunctions::SetClassMinorSkill},\
|
||||
\
|
||||
{"SendClass", CharClassFunctions::SendClass}
|
||||
|
||||
|
||||
class CharClassFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Get the default class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The ID of the default class.
|
||||
*/
|
||||
static const char *GetDefaultClass(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the name of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The name of the custom class.
|
||||
*/
|
||||
static const char *GetClassName(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the description of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The description of the custom class.
|
||||
*/
|
||||
static const char *GetClassDesc(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the two major attributes of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major attribute (0 or 1).
|
||||
* \return The ID of the major attribute.
|
||||
*/
|
||||
static int GetClassMajorAttribute(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the specialization ID of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The specialization ID of the custom class (0 for Combat, 1 for Magic, 2 for Stealth).
|
||||
*/
|
||||
static int GetClassSpecialization(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the five major skills of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major skill (0 to 4).
|
||||
* \return The ID of the major skill.
|
||||
*/
|
||||
static int GetClassMajorSkill(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the five minor skills of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the minor skill (0 to 4).
|
||||
* \return The ID of the minor skill.
|
||||
*/
|
||||
static int GetClassMinorSkill(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player is using a default class instead of a custom one.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player is using a default class.
|
||||
*/
|
||||
static int IsClassDefault(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the default class used by a player.
|
||||
*
|
||||
* If this is left blank, the custom class data set for the player will be used instead.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param id The ID of the default class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetDefaultClass(unsigned short pid, const char *id) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the name of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param name The name of the custom class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassName(unsigned short pid, const char *name) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the description of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param desc The description of the custom class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassDesc(unsigned short pid, const char *desc) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the two major attributes of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major attribute (0 or 1).
|
||||
* \param attrId The ID to use for the attribute.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMajorAttribute(unsigned short pid, unsigned char slot, int attrId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the specialization of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param spec The specialization ID to use (0 for Combat, 1 for Magic, 2 for Stealth).
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassSpecialization(unsigned short pid, int spec) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the five major skills of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major skill (0 to 4).
|
||||
* \param skillId The ID to use for the skill.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMajorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the five minor skills of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the minor skill (0 to 4).
|
||||
* \param skillId The ID to use for the skill.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMinorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerCharClass packet about a player.
|
||||
*
|
||||
* It is only sent to the affected player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendClass(unsigned short pid) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_CHARCLASSAPI_HPP
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.04.16.
|
||||
//
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
void ScriptFunctions::SendMessage(unsigned short pid, const char *message, bool broadcast) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->chatMessage = message;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "System: %s", message);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
if (broadcast)
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(true);
|
||||
}
|
||||
|
||||
void ScriptFunctions::CleanChatByPid(unsigned short pid)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->chatMessage.clear();
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
}
|
||||
|
||||
void ScriptFunctions::CleanChat()
|
||||
{
|
||||
for (auto player : *Players::getPlayers())
|
||||
{
|
||||
player.second->chatMessage.clear();
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player.second);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
#include "Dialogue.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void DialogueFunctions::InitializeTopicChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->topicChanges.topics.clear();
|
||||
}
|
||||
|
||||
unsigned int DialogueFunctions::GetTopicChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->topicChanges.count;
|
||||
}
|
||||
|
||||
void DialogueFunctions::AddTopic(unsigned short pid, const char* topicId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Topic topic;
|
||||
topic.topicId = topicId;
|
||||
|
||||
player->topicChanges.topics.push_back(topic);
|
||||
}
|
||||
|
||||
const char *DialogueFunctions::GetTopicId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->topicChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->topicChanges.topics.at(i).topicId.c_str();
|
||||
}
|
||||
|
||||
void DialogueFunctions::SendTopicChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC)->Send(toOthers);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#ifndef OPENMW_DIALOGUEAPI_HPP
|
||||
#define OPENMW_DIALOGUEAPI_HPP
|
||||
|
||||
#define DIALOGUEAPI \
|
||||
{"InitializeTopicChanges", DialogueFunctions::InitializeTopicChanges},\
|
||||
\
|
||||
{"GetTopicChangesSize", DialogueFunctions::GetTopicChangesSize},\
|
||||
\
|
||||
{"AddTopic", DialogueFunctions::AddTopic},\
|
||||
\
|
||||
{"GetTopicId", DialogueFunctions::GetTopicId},\
|
||||
\
|
||||
{"SendTopicChanges", DialogueFunctions::SendTopicChanges}
|
||||
|
||||
class DialogueFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded topic changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerTopic packets.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeTopicChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetTopicChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new topic to the topic changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param topicId The topicId of the topic.
|
||||
* \return void
|
||||
*/
|
||||
static void AddTopic(unsigned short pid, const char* topicId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the topicId at a certain index in a player's latest topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param i The index of the topic.
|
||||
* \return The topicId.
|
||||
*/
|
||||
static const char *GetTopicId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerTopic packet with a player's recorded topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendTopicChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_DIALOGUEAPI_HPP
|
@ -1,118 +0,0 @@
|
||||
#include "Factions.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
Faction tempFaction;
|
||||
const Faction emptyFaction = {};
|
||||
|
||||
void FactionFunctions::InitializeFactionChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.factions.clear();
|
||||
}
|
||||
|
||||
unsigned int FactionFunctions::GetFactionChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.count;
|
||||
}
|
||||
|
||||
unsigned char FactionFunctions::GetFactionChangesAction(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.action;
|
||||
}
|
||||
|
||||
const char *FactionFunctions::GetFactionId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->factionChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->factionChanges.factions.at(i).factionId.c_str();
|
||||
}
|
||||
|
||||
int FactionFunctions::GetFactionRank(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.factions.at(i).rank;
|
||||
}
|
||||
|
||||
bool FactionFunctions::GetFactionExpulsionState(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->factionChanges.factions.at(i).isExpelled;
|
||||
}
|
||||
|
||||
int FactionFunctions::GetFactionReputation(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.factions.at(i).reputation;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionChangesAction(unsigned short pid, unsigned char action) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.action = action;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionId(const char* factionId) noexcept
|
||||
{
|
||||
tempFaction.factionId = factionId;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionRank(unsigned int rank) noexcept
|
||||
{
|
||||
tempFaction.rank = rank;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionExpulsionState(bool expulsionState) noexcept
|
||||
{
|
||||
tempFaction.isExpelled = expulsionState;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionReputation(int reputation) noexcept
|
||||
{
|
||||
tempFaction.reputation = reputation;
|
||||
}
|
||||
|
||||
void FactionFunctions::AddFaction(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.factions.push_back(tempFaction);
|
||||
|
||||
tempFaction = emptyFaction;
|
||||
}
|
||||
|
||||
void FactionFunctions::SendFactionChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION)->Send(toOthers);
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
#ifndef OPENMW_FACTIONAPI_HPP
|
||||
#define OPENMW_FACTIONAPI_HPP
|
||||
|
||||
#define FACTIONAPI \
|
||||
{"InitializeFactionChanges", FactionFunctions::InitializeFactionChanges},\
|
||||
\
|
||||
{"GetFactionChangesSize", FactionFunctions::GetFactionChangesSize},\
|
||||
{"GetFactionChangesAction", FactionFunctions::GetFactionChangesAction},\
|
||||
\
|
||||
{"GetFactionId", FactionFunctions::GetFactionId},\
|
||||
{"GetFactionRank", FactionFunctions::GetFactionRank},\
|
||||
{"GetFactionExpulsionState", FactionFunctions::GetFactionExpulsionState},\
|
||||
{"GetFactionReputation", FactionFunctions::GetFactionReputation},\
|
||||
\
|
||||
{"SetFactionChangesAction", FactionFunctions::SetFactionChangesAction},\
|
||||
{"SetFactionId", FactionFunctions::SetFactionId},\
|
||||
{"SetFactionRank", FactionFunctions::SetFactionRank},\
|
||||
{"SetFactionExpulsionState", FactionFunctions::SetFactionExpulsionState},\
|
||||
{"SetFactionReputation", FactionFunctions::SetFactionReputation},\
|
||||
\
|
||||
{"AddFaction", FactionFunctions::AddFaction},\
|
||||
\
|
||||
{"SendFactionChanges", FactionFunctions::SendFactionChanges}
|
||||
|
||||
class FactionFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded faction changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerFaction packets.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeFactionChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetFactionChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return The action type (0 for RANK, 1 for EXPULSION, 2 for REPUTATION).
|
||||
*/
|
||||
static unsigned char GetFactionChangesAction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the factionId at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The factionId.
|
||||
*/
|
||||
static const char *GetFactionId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the rank at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The rank.
|
||||
*/
|
||||
static int GetFactionRank(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the expulsion state at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The expulsion state.
|
||||
*/
|
||||
static bool GetFactionExpulsionState(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the reputation at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The reputation.
|
||||
*/
|
||||
static int GetFactionReputation(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type in a player's faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param action The action (0 for RANK, 1 for EXPULSION, 2 for REPUTATION).
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionChangesAction(unsigned short pid, unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the factionId of the temporary faction stored on the server.
|
||||
*
|
||||
* \param factionId The factionId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionId(const char* factionId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rank of the temporary faction stored on the server.
|
||||
*
|
||||
* \param rank The rank.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionRank(unsigned int rank) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the expulsion state of the temporary faction stored on the server.
|
||||
*
|
||||
* \param expulsionState The expulsion state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionExpulsionState(bool expulsionState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the reputation of the temporary faction stored on the server.
|
||||
*
|
||||
* \param reputation The reputation.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionReputation(int reputation) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add the server's temporary faction to the faction changes for a player.
|
||||
*
|
||||
* In the process, the server's temporary faction will automatically be cleared so a new one
|
||||
* can be set up.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void AddFaction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerFaction packet with a player's recorded faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendFactionChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_FACTIONAPI_HPP
|
@ -1,88 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.07.16.
|
||||
//
|
||||
|
||||
#include "GUI.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
void GUIFunctions::_MessageBox(unsigned short pid, int id, const char *label) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::MessageBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::CustomMessageBox(unsigned short pid, int id, const char *label, const char *buttons) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.buttons = buttons;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::CustomMessageBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::InputDialog(unsigned short pid, int id, const char *label) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::InputDialog;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::PasswordDialog(unsigned short pid, int id, const char *label, const char *note) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.note = note;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::PasswordDialog;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::ListBox(unsigned short pid, int id, const char *label, const char *items)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.data = items;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::ListBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::SetMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state) noexcept
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
||||
|
||||
void GUIFunctions::SetMapVisibilityAll(unsigned short targetPID, unsigned short state) noexcept
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 30.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_GUIAPI_HPP
|
||||
#define OPENMW_GUIAPI_HPP
|
||||
|
||||
#define GUIAPI \
|
||||
{"MessageBox", GUIFunctions::_MessageBox},\
|
||||
{"CustomMessageBox", GUIFunctions::CustomMessageBox},\
|
||||
{"InputDialog", GUIFunctions::InputDialog},\
|
||||
{"PasswordDialog", GUIFunctions::PasswordDialog},\
|
||||
{"ListBox", GUIFunctions::ListBox},\
|
||||
{"SetMapVisibility", GUIFunctions::SetMapVisibility},\
|
||||
{"SetMapVisibilityAll", GUIFunctions::SetMapVisibilityAll}
|
||||
|
||||
class GUIFunctions
|
||||
{
|
||||
public:
|
||||
/* Do not rename into MessageBox to not conflict with WINAPI's MessageBox */
|
||||
static void _MessageBox(unsigned short pid, int id, const char *label) noexcept;
|
||||
|
||||
static void CustomMessageBox(unsigned short pid, int id, const char *label, const char *buttons) noexcept;
|
||||
static void InputDialog(unsigned short pid, int id, const char *label) noexcept;
|
||||
static void PasswordDialog(unsigned short pid, int id, const char *label, const char *note) noexcept;
|
||||
|
||||
static void ListBox(unsigned short pid, int id, const char *label, const char *items);
|
||||
|
||||
//state 0 - disallow, 1 - allow
|
||||
static void SetMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state) noexcept;
|
||||
static void SetMapVisibilityAll(unsigned short targetPID, unsigned short state) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_GUIAPI_HPP
|
@ -1,162 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 02.03.16.
|
||||
//
|
||||
|
||||
#include "Items.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw/mwworld/inventorystore.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void ItemFunctions::InitializeInventoryChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->inventoryChanges.items.clear();
|
||||
player->inventoryChanges.action = InventoryChanges::SET;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentSize() noexcept
|
||||
{
|
||||
return MWWorld::InventoryStore::Slots;
|
||||
}
|
||||
|
||||
unsigned int ItemFunctions::GetInventoryChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.count;
|
||||
}
|
||||
|
||||
void ItemFunctions::EquipItem(unsigned short pid, unsigned short slot, const char *refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->equipedItems[slot].refId = refId;
|
||||
player->equipedItems[slot].count = count;
|
||||
player->equipedItems[slot].charge = charge;
|
||||
}
|
||||
|
||||
void ItemFunctions::UnequipItem(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ItemFunctions::EquipItem(pid, slot, "", 0, -1);
|
||||
}
|
||||
|
||||
void ItemFunctions::AddItem(unsigned short pid, const char* refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
|
||||
player->inventoryChanges.items.push_back(item);
|
||||
player->inventoryChanges.action = InventoryChanges::ADD;
|
||||
}
|
||||
|
||||
void ItemFunctions::RemoveItem(unsigned short pid, const char* refId, unsigned short count) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
|
||||
player->inventoryChanges.items.push_back(item);
|
||||
player->inventoryChanges.action = InventoryChanges::REMOVE;
|
||||
}
|
||||
|
||||
bool ItemFunctions::HasItemEquipped(unsigned short pid, const char* refId)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
if (Misc::StringUtils::ciEqual(player->equipedItems[slot].refId, refId))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *ItemFunctions::GetEquipmentItemRefId(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].refId.c_str();
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentItemCount(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].count;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentItemCharge(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].charge;
|
||||
}
|
||||
|
||||
const char *ItemFunctions::GetInventoryItemRefId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->inventoryChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->inventoryChanges.items.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int ItemFunctions::GetInventoryItemCount(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.items.at(i).count;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetInventoryItemCharge(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.items.at(i).charge;
|
||||
}
|
||||
|
||||
void ItemFunctions::SendEquipment(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->Send(true);
|
||||
}
|
||||
|
||||
void ItemFunctions::SendInventoryChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_INVENTORY)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_INVENTORY)->Send(toOthers);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 30.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_ITEMAPI_HPP
|
||||
#define OPENMW_ITEMAPI_HPP
|
||||
|
||||
#define ITEMAPI \
|
||||
{"InitializeInventoryChanges", ItemFunctions::InitializeInventoryChanges},\
|
||||
\
|
||||
{"GetEquipmentSize", ItemFunctions::GetEquipmentSize},\
|
||||
{"GetInventoryChangesSize", ItemFunctions::GetInventoryChangesSize},\
|
||||
\
|
||||
{"EquipItem", ItemFunctions::EquipItem},\
|
||||
{"UnequipItem", ItemFunctions::UnequipItem},\
|
||||
\
|
||||
{"AddItem", ItemFunctions::AddItem},\
|
||||
{"RemoveItem", ItemFunctions::RemoveItem},\
|
||||
\
|
||||
{"HasItemEquipped", ItemFunctions::HasItemEquipped},\
|
||||
\
|
||||
{"GetEquipmentItemRefId", ItemFunctions::GetEquipmentItemRefId},\
|
||||
{"GetEquipmentItemCount", ItemFunctions::GetEquipmentItemCount},\
|
||||
{"GetEquipmentItemCharge", ItemFunctions::GetEquipmentItemCharge},\
|
||||
\
|
||||
{"GetInventoryItemRefId", ItemFunctions::GetInventoryItemRefId},\
|
||||
{"GetInventoryItemCount", ItemFunctions::GetInventoryItemCount},\
|
||||
{"GetInventoryItemCharge", ItemFunctions::GetInventoryItemCharge},\
|
||||
\
|
||||
{"SendEquipment", ItemFunctions::SendEquipment},\
|
||||
{"SendInventoryChanges", ItemFunctions::SendInventoryChanges}
|
||||
|
||||
class ItemFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
static void InitializeInventoryChanges(unsigned short pid) noexcept;
|
||||
|
||||
static int GetEquipmentSize() noexcept;
|
||||
static unsigned int GetInventoryChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
static void EquipItem(unsigned short pid, unsigned short slot, const char* refId, unsigned int count, int charge) noexcept;
|
||||
static void UnequipItem(unsigned short pid, unsigned short slot) noexcept;
|
||||
|
||||
static void AddItem(unsigned short pid, const char* refId, unsigned int count, int charge) noexcept;
|
||||
static void RemoveItem(unsigned short pid, const char* refId, unsigned short count) noexcept;
|
||||
|
||||
static bool HasItemEquipped(unsigned short pid, const char* refId);
|
||||
|
||||
static const char *GetEquipmentItemRefId(unsigned short pid, unsigned short slot) noexcept;
|
||||
static int GetEquipmentItemCount(unsigned short pid, unsigned short slot) noexcept;
|
||||
static int GetEquipmentItemCharge(unsigned short pid, unsigned short slot) noexcept;
|
||||
|
||||
static const char *GetInventoryItemRefId(unsigned short pid, unsigned int i) noexcept;
|
||||
static int GetInventoryItemCount(unsigned short pid, unsigned int i) noexcept;
|
||||
static int GetInventoryItemCharge(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
static void SendEquipment(unsigned short pid) noexcept;
|
||||
static void SendInventoryChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_ITEMAPI_HPP
|
@ -1,64 +0,0 @@
|
||||
#include "Mechanics.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool MechanicsFunctions::IsWerewolf(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->isWerewolf;
|
||||
}
|
||||
|
||||
void MechanicsFunctions::SetWerewolfState(unsigned short pid, bool isWerewolf)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->isWerewolf = isWerewolf;
|
||||
}
|
||||
|
||||
void MechanicsFunctions::SendShapeshift(unsigned short pid)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->Send(true);
|
||||
}
|
||||
|
||||
void MechanicsFunctions::Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation, bool ignoreJailSkillIncreases,
|
||||
const char* jailProgressText, const char* jailEndText) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->jailDays = jailDays;
|
||||
player->ignoreJailTeleportation = ignoreJailTeleportation;
|
||||
player->ignoreJailSkillIncreases = ignoreJailSkillIncreases;
|
||||
player->jailProgressText = jailProgressText;
|
||||
player->jailEndText = jailEndText;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JAIL)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JAIL)->Send(false);
|
||||
}
|
||||
|
||||
void MechanicsFunctions::Resurrect(unsigned short pid, unsigned int type) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->resurrectType = type;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->Send(true);
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
#ifndef OPENMW_MECHANICSAPI_HPP
|
||||
#define OPENMW_MECHANICSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define MECHANICSAPI \
|
||||
{"IsWerewolf", MechanicsFunctions::IsWerewolf},\
|
||||
\
|
||||
{"SetWerewolfState", MechanicsFunctions::SetWerewolfState},\
|
||||
\
|
||||
{"SendShapeshift", MechanicsFunctions::SendShapeshift},\
|
||||
\
|
||||
{"Jail", MechanicsFunctions::Jail},\
|
||||
{"Resurrect", MechanicsFunctions::Resurrect}
|
||||
|
||||
class MechanicsFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Check whether a player is a werewolf.
|
||||
*
|
||||
* This is based on the last PlayerShapeshift packet received or sent for that player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The werewolf state.
|
||||
*/
|
||||
static bool IsWerewolf(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the werewolf state of a player.
|
||||
*
|
||||
* This changes the werewolf state recorded for that player in the server memory, but
|
||||
* does not by itself send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param bool The new werewolf state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetWerewolfState(unsigned short pid, bool isWerewolf);
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerShapeshift packet about a player.
|
||||
*
|
||||
* This sends the packet to all players connected to the server. It is currently used
|
||||
* only to communicate werewolf states.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendShapeshift(unsigned short pid);
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerJail packet about a player.
|
||||
*
|
||||
* This is similar to the player being jailed by a guard, but provides extra parameters for
|
||||
* increased flexibility.
|
||||
*
|
||||
* It is only sent to the player being jailed, as the other players will be informed of the
|
||||
* jailing's actual consequences via other packets sent by the affected client.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param jailDays The number of days to spend jailed, where each day affects one skill point.
|
||||
* \param ignoreJailTeleportation Whether the player being teleported to the nearest jail
|
||||
* marker should be overridden.
|
||||
* \param ignoreJailSkillIncrease Whether the player's Sneak and Security skills should be
|
||||
* prevented from increasing as a result of the jailing,
|
||||
* overriding default behavior.
|
||||
* \param jailProgressText The text that should be displayed while jailed.
|
||||
* \param jailEndText The text that should be displayed once the jailing period is over.
|
||||
* \return void
|
||||
*/
|
||||
static void Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation = false, bool ignoreJailSkillIncreases = false,
|
||||
const char* jailProgressText = "", const char* jailEndText = "") noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerResurrect packet about a player.
|
||||
*
|
||||
* This sends the packet to all players connected to the server.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param type The type of resurrection (0 for REGULAR, 1 for IMPERIAL_SHRINE,
|
||||
* 2 for TRIBUNAL_TEMPLE).
|
||||
* \return void
|
||||
*/
|
||||
static void Resurrect(unsigned short pid, unsigned int type) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_MECHANICSAPI_HPP
|
@ -1,54 +0,0 @@
|
||||
#include "Miscellaneous.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
static std::string tempFilename;
|
||||
|
||||
const char *MiscellaneousFunctions::GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept
|
||||
{
|
||||
if (!boost::filesystem::exists(folderPath)) return "invalid";
|
||||
|
||||
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
|
||||
|
||||
for (boost::filesystem::directory_iterator itr(folderPath); itr != end_itr; ++itr)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(itr->path().filename().string(), filename))
|
||||
{
|
||||
tempFilename = itr->path().filename().string();
|
||||
return tempFilename.c_str();
|
||||
}
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
unsigned int MiscellaneousFunctions::GetLastPlayerId() noexcept
|
||||
{
|
||||
return Players::getLastPlayerId();
|
||||
}
|
||||
|
||||
int MiscellaneousFunctions::GetCurrentMpNum() noexcept
|
||||
{
|
||||
return mwmp::Networking::getPtr()->getCurrentMpNum();
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::SetCurrentMpNum(int mpNum) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->setCurrentMpNum(mpNum);
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::LogMessage(unsigned short level, const char *message) noexcept
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(level, "[Script]: %s", message);
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::LogAppend(unsigned short level, const char *message) noexcept
|
||||
{
|
||||
LOG_APPEND(level, "[Script]: %s", message);
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
#ifndef OPENMW_MISCELLANEOUSAPI_HPP
|
||||
#define OPENMW_MISCELLANEOUSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define MISCELLANEOUSAPI \
|
||||
{"GetCaseInsensitiveFilename", MiscellaneousFunctions::GetCaseInsensitiveFilename},\
|
||||
\
|
||||
{"GetLastPlayerId", MiscellaneousFunctions::GetLastPlayerId},\
|
||||
\
|
||||
{"GetCurrentMpNum", MiscellaneousFunctions::GetCurrentMpNum},\
|
||||
{"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum},\
|
||||
\
|
||||
{"LogMessage", MiscellaneousFunctions::LogMessage},\
|
||||
{"LogAppend", MiscellaneousFunctions::LogAppend}
|
||||
|
||||
class MiscellaneousFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Get the first filename in a folder that has a case insensitive match with the filename
|
||||
* argument.
|
||||
*
|
||||
* This is used to retain case insensitivity when opening data files on Linux.
|
||||
*
|
||||
* \return The filename that matches.
|
||||
*/
|
||||
static const char *GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the last player ID currently connected to the server.
|
||||
*
|
||||
* Every player receives a unique numerical index known as their player ID upon joining the
|
||||
* server.
|
||||
*
|
||||
* \return The player ID.
|
||||
*/
|
||||
static unsigned int GetLastPlayerId() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current (latest) mpNum generated by the server.
|
||||
*
|
||||
* Every object that did not exist in an .ESM or .ESP data file and has instead been placed or
|
||||
* spawned through a server-sent packet has a numerical index known as its mpNum.
|
||||
*
|
||||
* When ObjectPlace and ObjectSpawn packets are received from players, their objects lack mpNums,
|
||||
* so the server assigns them some based on incrementing the server's current mpNum, with the
|
||||
* operation's final mpNum becoming the server's new current mpNum.
|
||||
*
|
||||
* \return The mpNum.
|
||||
*/
|
||||
static int GetCurrentMpNum() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current (latest) mpNum generated by the server.
|
||||
*
|
||||
* When restarting a server, it is important to revert to the previous current (latest) mpNum
|
||||
* as stored in the server's data, so as to avoid starting over from 0 and ending up assigning
|
||||
* duplicate mpNums to objects.
|
||||
*
|
||||
* \param mpNum The number that should be used as the new current mpNum.
|
||||
* \return void
|
||||
*/
|
||||
static void SetCurrentMpNum(int mpNum) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Write a log message with its own timestamp.
|
||||
*
|
||||
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
|
||||
*
|
||||
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
|
||||
* 3 for LOG_ERROR, 4 for LOG_FATAL).
|
||||
* \param message The message logged.
|
||||
* \return void
|
||||
*/
|
||||
static void LogMessage(unsigned short level, const char *message) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Write a log message without its own timestamp.
|
||||
*
|
||||
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
|
||||
*
|
||||
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
|
||||
* 3 for LOG_ERROR, 4 for LOG_FATAL).
|
||||
* \param message The message logged.
|
||||
* \return void
|
||||
*/
|
||||
static void LogAppend(unsigned short level, const char *message) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_MISCELLANEOUSAPI_HPP
|
@ -1,128 +0,0 @@
|
||||
#include "Positions.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void PositionFunctions::GetPos(unsigned short pid, float *x, float *y, float *z) noexcept
|
||||
{
|
||||
*x = 0.00;
|
||||
*y = 0.00;
|
||||
*z = 0.00;
|
||||
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
*x = player->position.pos[0];
|
||||
*y = player->position.pos[1];
|
||||
*z = player->position.pos[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[1];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[1];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[2];
|
||||
}
|
||||
|
||||
void PositionFunctions::GetRot(unsigned short pid, float *x, float *y, float *z) noexcept
|
||||
{
|
||||
*x = 0.00;
|
||||
*y = 0.00;
|
||||
*z = 0.00;
|
||||
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
*x = player->position.rot[0];
|
||||
*y = player->position.rot[1];
|
||||
*z = player->position.rot[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetRotX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.rot[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetRotZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.rot[2];
|
||||
}
|
||||
|
||||
void PositionFunctions::SetPos(unsigned short pid, double x, double y, double z) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->position.pos[0] = x;
|
||||
player->position.pos[1] = y;
|
||||
player->position.pos[2] = z;
|
||||
}
|
||||
|
||||
void PositionFunctions::SetRot(unsigned short pid, double x, double z) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->position.rot[0] = x;
|
||||
player->position.rot[2] = z;
|
||||
}
|
||||
|
||||
void PositionFunctions::SendPos(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_POSITION)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_POSITION)->Send(false);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue