mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-01 04:03:17 +08:00
Exposing more C++ sources
This commit is contained in:
parent
517abc9112
commit
e8a4e249dc
@ -3932,24 +3932,24 @@
|
|||||||
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
|
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
|
||||||
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
|
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
|
||||||
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
|
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
|
||||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/19/53/2a9c168ffd8bc53475e8c9e139ed",
|
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/50/39/970b2b3f334bdbfd72469cd27f8c",
|
||||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/20/79/28f2821d36d20be52eebee1475fa",
|
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/bd/46/92d63ccc123d646df92cd1545d0a",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6e/4e/1f59b95892fdd6ebf55159c0fb69",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d0/8e/be85a2a57eaeb26f9d09899e6811",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3c/64/8790eac167ed9cb6ced1b4e43a34",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ee/f8/28c1f4606f3d2234dbbe79990c61",
|
||||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/06/6c/1ffc0a07960c3272304b1b5f858a",
|
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2d/02/5843eaa3f9118883523042379292",
|
||||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/6c/fd/193b81fcda6c6716e3dcaa7f7cb8",
|
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/89/dc/8b965051d0c27d5812d80ecac1d3",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0f/30/8ac58a8ebc1b73dc335d82d7cecb",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/16/89/34ea43bcd3901c8e5157460c37d6",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/a7/dc477a2297d27eb7fbb14a662619",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ae/72/30fe5cbfa936477b4f61e861a7ae",
|
||||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/70/07/1e15c6fcdbf35ceda17a5d324394",
|
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e6/5d/4402c2e9193641ee78d20c85ff3d",
|
||||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/9b/2b/59a36a36dd90410b4a94726a3e4b",
|
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/02/0b/dcdc0dd9147dd9a56992572aeb60",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/fc/36/6bafb410c3ad3d458545fc495cfd",
|
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/02/87/645ddc08b2bdb90fcc69430a7b0b",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/f3/29/0e5332b1ab93ea7c564fea7ce980",
|
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/3f/ce/60d6f026d3f22d800538ffd69da8",
|
||||||
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4d/01/29abecb0b2bd764ad3c261f1727e",
|
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/15/54/bfba7d740c7221a5d46e8e21c756",
|
||||||
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/68/c6/61c27c594a5b67abb7cd0a2a0f51",
|
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/1f/ca36bea671a5b88a7e2ccf2e4c4a",
|
||||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/79/a9/480cd7947a83b5e52359945c450e",
|
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/57/2d/e4b9a67cb21131cdcdfb8287f9e7",
|
||||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/53/96/32edc65468aa4546f245192238c3",
|
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/59/b6/6ffc20f2c0253180496d2dae968c",
|
||||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/18/34/0c7bc3754d9dc5a796133484a891",
|
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b9/0a/dc300391e73286380eab87f6e742",
|
||||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0a/69/49203680f51913705a4f6263ef01",
|
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/97/76/7e35dd32e4507a4521a74d8c1b03",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/08/ea/3732982a8df8b9510b9ae4bb3ace",
|
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9d/60/716cde2b1ec5efb8eedfa1a978f1",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/31/60fcef7fd4e08d4ebb1859f4c9a3"
|
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a2/a2/70a0bda587c2405a67c6709a5d0a"
|
||||||
}
|
}
|
||||||
@ -22,7 +22,6 @@ class AdvancedSettingsWindow(ba.Window):
|
|||||||
origin_widget: ba.Widget = None):
|
origin_widget: ba.Widget = None):
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
from ba.internal import master_server_get
|
from ba.internal import master_server_get
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
# Preload some modules we use in a background thread so we won't
|
# Preload some modules we use in a background thread so we won't
|
||||||
@ -65,7 +64,8 @@ class AdvancedSettingsWindow(ba.Window):
|
|||||||
|
|
||||||
# In vr-mode, the internal keyboard is currently the *only* option,
|
# In vr-mode, the internal keyboard is currently the *only* option,
|
||||||
# so no need to show this.
|
# so no need to show this.
|
||||||
self._show_always_use_internal_keyboard = (not app.vr_mode)
|
self._show_always_use_internal_keyboard = (not app.vr_mode
|
||||||
|
and not app.iircade_mode)
|
||||||
|
|
||||||
self._scroll_width = self._width - (100 + 2 * x_inset)
|
self._scroll_width = self._width - (100 + 2 * x_inset)
|
||||||
self._scroll_height = self._height - 115.0
|
self._scroll_height = self._height - 115.0
|
||||||
|
|||||||
@ -12,8 +12,8 @@
|
|||||||
<w>ack'ed</w>
|
<w>ack'ed</w>
|
||||||
<w>acked</w>
|
<w>acked</w>
|
||||||
<w>acks</w>
|
<w>acks</w>
|
||||||
<w>aclass</w>
|
|
||||||
<w>aclass's</w>
|
<w>aclass's</w>
|
||||||
|
<w>aclass</w>
|
||||||
<w>activityplayer</w>
|
<w>activityplayer</w>
|
||||||
<w>addrs</w>
|
<w>addrs</w>
|
||||||
<w>adjoint</w>
|
<w>adjoint</w>
|
||||||
@ -41,6 +41,7 @@
|
|||||||
<w>appconfig</w>
|
<w>appconfig</w>
|
||||||
<w>appname</w>
|
<w>appname</w>
|
||||||
<w>appnameupper</w>
|
<w>appnameupper</w>
|
||||||
|
<w>appstate</w>
|
||||||
<w>asci</w>
|
<w>asci</w>
|
||||||
<w>assigninput</w>
|
<w>assigninput</w>
|
||||||
<w>athome</w>
|
<w>athome</w>
|
||||||
@ -144,8 +145,8 @@
|
|||||||
<w>cmath</w>
|
<w>cmath</w>
|
||||||
<w>cmds</w>
|
<w>cmds</w>
|
||||||
<w>cmdvals</w>
|
<w>cmdvals</w>
|
||||||
<w>codewarrior</w>
|
|
||||||
<w>codewarrior's</w>
|
<w>codewarrior's</w>
|
||||||
|
<w>codewarrior</w>
|
||||||
<w>cofnodes</w>
|
<w>cofnodes</w>
|
||||||
<w>collapseable</w>
|
<w>collapseable</w>
|
||||||
<w>collidable</w>
|
<w>collidable</w>
|
||||||
@ -399,6 +400,7 @@
|
|||||||
<w>ifaddrs</w>
|
<w>ifaddrs</w>
|
||||||
<w>ifdebug</w>
|
<w>ifdebug</w>
|
||||||
<w>iiiiisss</w>
|
<w>iiiiisss</w>
|
||||||
|
<w>iircade</w>
|
||||||
<w>illum</w>
|
<w>illum</w>
|
||||||
<w>ilock</w>
|
<w>ilock</w>
|
||||||
<w>imagewidget</w>
|
<w>imagewidget</w>
|
||||||
|
|||||||
@ -274,11 +274,13 @@ add_executable(ballisticacore
|
|||||||
${BA_SRC_ROOT}/ballistica/game/account.h
|
${BA_SRC_ROOT}/ballistica/game/account.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/client_controller_interface.h
|
${BA_SRC_ROOT}/ballistica/game/client_controller_interface.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/connection/connection.h
|
${BA_SRC_ROOT}/ballistica/game/connection/connection.h
|
||||||
|
${BA_SRC_ROOT}/ballistica/game/connection/connection_set.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client.h
|
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client_udp.h
|
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client_udp.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host.h
|
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host_udp.h
|
${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host_udp.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/friend_score_set.h
|
${BA_SRC_ROOT}/ballistica/game/friend_score_set.h
|
||||||
|
${BA_SRC_ROOT}/ballistica/game/game.cc
|
||||||
${BA_SRC_ROOT}/ballistica/game/game.h
|
${BA_SRC_ROOT}/ballistica/game/game.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/game_stream.h
|
${BA_SRC_ROOT}/ballistica/game/game_stream.h
|
||||||
${BA_SRC_ROOT}/ballistica/game/host_activity.h
|
${BA_SRC_ROOT}/ballistica/game/host_activity.h
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
||||||
<h4><em>last updated on 2020-10-13 for Ballistica version 1.5.26 build 20205</em></h4>
|
<h4><em>last updated on 2020-10-15 for Ballistica version 1.5.26 build 20213</em></h4>
|
||||||
<p>This page documents the Python classes and functions in the 'ba' module,
|
<p>This page documents the Python classes and functions in the 'ba' module,
|
||||||
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
namespace ballistica {
|
namespace ballistica {
|
||||||
|
|
||||||
// These are set automatically via script; don't change here.
|
// These are set automatically via script; don't change here.
|
||||||
const int kAppBuildNumber = 20210;
|
const int kAppBuildNumber = 20215;
|
||||||
const char* kAppVersion = "1.5.26";
|
const char* kAppVersion = "1.5.26";
|
||||||
|
|
||||||
// Our standalone globals.
|
// Our standalone globals.
|
||||||
|
|||||||
@ -68,6 +68,7 @@ class CollideModelData;
|
|||||||
class Collision;
|
class Collision;
|
||||||
class CollisionCache;
|
class CollisionCache;
|
||||||
class Connection;
|
class Connection;
|
||||||
|
class ConnectionSet;
|
||||||
class ConnectionToClient;
|
class ConnectionToClient;
|
||||||
class Context;
|
class Context;
|
||||||
class ContextTarget;
|
class ContextTarget;
|
||||||
|
|||||||
136
src/ballistica/game/connection/connection_set.h
Normal file
136
src/ballistica/game/connection/connection_set.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Released under the MIT License. See LICENSE for details.
|
||||||
|
|
||||||
|
#ifndef BALLISTICA_GAME_CONNECTION_CONNECTION_SET_H_
|
||||||
|
#define BALLISTICA_GAME_CONNECTION_CONNECTION_SET_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ballistica/core/object.h"
|
||||||
|
|
||||||
|
namespace ballistica {
|
||||||
|
|
||||||
|
class ConnectionSet {
|
||||||
|
public:
|
||||||
|
ConnectionSet();
|
||||||
|
|
||||||
|
// Whoever wants to wrangle current client connections should call this
|
||||||
|
// to register itself. Note that it must explicitly call unregister when
|
||||||
|
// unregistering itself.
|
||||||
|
auto RegisterClientController(ClientControllerInterface* c) -> void;
|
||||||
|
auto UnregisterClientController(ClientControllerInterface* c) -> void;
|
||||||
|
|
||||||
|
// Quick test as to whether there are clients. Does not check if they are
|
||||||
|
// fully connected.
|
||||||
|
auto has_connection_to_clients() const -> bool {
|
||||||
|
assert(InGameThread());
|
||||||
|
return (!connections_to_clients_.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns our host-connection or nullptr if there is none.
|
||||||
|
auto connection_to_host() -> ConnectionToHost* {
|
||||||
|
return connection_to_host_.get();
|
||||||
|
}
|
||||||
|
auto GetConnectionToHostUDP() -> ConnectionToHostUDP*;
|
||||||
|
|
||||||
|
auto connections_to_clients()
|
||||||
|
-> const std::map<int, Object::Ref<ConnectionToClient> >& {
|
||||||
|
return connections_to_clients_;
|
||||||
|
}
|
||||||
|
auto client_controller() -> ClientControllerInterface* {
|
||||||
|
return client_controller_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple thread safe query.
|
||||||
|
auto has_connection_to_host() const -> bool {
|
||||||
|
return has_connection_to_host_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Update() -> void;
|
||||||
|
auto Shutdown() -> void;
|
||||||
|
auto PrepareForLaunchHostSession() -> void;
|
||||||
|
auto HandleClientDisconnected(int id) -> void;
|
||||||
|
// Returns true if disconnect attempts are supported.
|
||||||
|
auto DisconnectClient(int client_id, int ban_seconds) -> bool;
|
||||||
|
auto ForceDisconnectClients() -> void;
|
||||||
|
auto PushHostConnectedUDPCall(const SockAddr& addr,
|
||||||
|
bool print_connect_progress) -> void;
|
||||||
|
auto PushDisconnectFromHostCall() -> void;
|
||||||
|
auto PushDisconnectedFromHostCall() -> void;
|
||||||
|
auto GetPrintUDPConnectProgress() const -> bool {
|
||||||
|
return print_udp_connect_progress_;
|
||||||
|
}
|
||||||
|
auto PushUDPConnectionPacketCall(const std::vector<uint8_t>& data,
|
||||||
|
const SockAddr& addr) -> void;
|
||||||
|
// Return our client connections (if any).
|
||||||
|
// FIXME: this prunes invalid connections, but it is necessary?
|
||||||
|
// Can we just use connections_to_clients() for direct access?
|
||||||
|
auto GetConnectionsToClients() -> std::vector<ConnectionToClient*>;
|
||||||
|
|
||||||
|
// Return the number of connections-to-client with "connected" status true.
|
||||||
|
auto GetConnectedClientCount() const -> int;
|
||||||
|
|
||||||
|
// For applying player-profiles data from the master-server.
|
||||||
|
auto SetClientInfoFromMasterServer(const std::string& client_token,
|
||||||
|
PyObject* info) -> void;
|
||||||
|
|
||||||
|
auto SendChatMessage(const std::string& message,
|
||||||
|
const std::vector<int>* clients = nullptr,
|
||||||
|
const std::string* sender_override = nullptr) -> void;
|
||||||
|
|
||||||
|
// Send a screen message to all connected clients AND print it on the host.
|
||||||
|
auto SendScreenMessageToAll(const std::string& s, float r, float g, float b)
|
||||||
|
-> void;
|
||||||
|
|
||||||
|
// send a screen message to all connected clients
|
||||||
|
auto SendScreenMessageToClients(const std::string& s, float r, float g,
|
||||||
|
float b) -> void;
|
||||||
|
|
||||||
|
// Send a screen message to specific connected clients (those matching the IDs
|
||||||
|
// specified) the id -1 can be used to specify the host.
|
||||||
|
auto SendScreenMessageToSpecificClients(const std::string& s, float r,
|
||||||
|
float g, float b,
|
||||||
|
const std::vector<int>& clients)
|
||||||
|
-> void;
|
||||||
|
|
||||||
|
#if BA_GOOGLE_BUILD
|
||||||
|
auto PushClientDisconnectedGooglePlayCall(int id) -> void;
|
||||||
|
int GetGooglePlayClientCount() const;
|
||||||
|
auto PushHostConnectedGooglePlayCall() -> void;
|
||||||
|
auto PushClientConnectedGooglePlayCall(int id) -> void;
|
||||||
|
auto PushCompressedGamePacketFromHostGooglePlayCall(
|
||||||
|
const std::vector<uint8_t>& data) -> void;
|
||||||
|
auto PushCompressedGamePacketFromClientGooglePlayCall(
|
||||||
|
int google_client_id, const std::vector<uint8_t>& data) -> void;
|
||||||
|
auto ClientIDFromGooglePlayClientID(int google_id) -> int;
|
||||||
|
auto GooglePlayClientIDFromClientID(int client_id) -> int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto UDPConnectionPacket(const std::vector<uint8_t>& data,
|
||||||
|
const SockAddr& addr) -> void;
|
||||||
|
auto PushClientDisconnectedCall(int id) -> void;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Try to minimize the chance a garbage packet will have this id.
|
||||||
|
int next_connection_to_client_id_{113};
|
||||||
|
std::map<int, Object::Ref<ConnectionToClient> > connections_to_clients_;
|
||||||
|
Object::Ref<ConnectionToHost> connection_to_host_;
|
||||||
|
ClientControllerInterface* client_controller_{};
|
||||||
|
|
||||||
|
// Simple flag for thread-safe access.
|
||||||
|
bool has_connection_to_host_{};
|
||||||
|
bool print_udp_connect_progress_{true};
|
||||||
|
|
||||||
|
// Prevents us from printing multiple 'you got disconnected' messages.
|
||||||
|
bool printed_host_disconnect_{};
|
||||||
|
|
||||||
|
#if BA_GOOGLE_BUILD
|
||||||
|
std::map<int, int> google_play_id_to_client_id_map_;
|
||||||
|
std::map<int, int> client_id_to_google_play_id_map_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ballistica
|
||||||
|
|
||||||
|
#endif // BALLISTICA_GAME_CONNECTION_CONNECTION_SET_H_
|
||||||
@ -34,7 +34,7 @@ class ConnectionToHostUDP : public ConnectionToHost {
|
|||||||
bool did_die_{};
|
bool did_die_{};
|
||||||
void Die();
|
void Die();
|
||||||
void SendDisconnectRequest();
|
void SendDisconnectRequest();
|
||||||
millisecs_t last_client_i_d_request_time_{};
|
millisecs_t last_client_id_request_time_{};
|
||||||
millisecs_t last_disconnect_request_time_{};
|
millisecs_t last_disconnect_request_time_{};
|
||||||
int client_id_{};
|
int client_id_{};
|
||||||
millisecs_t last_host_response_time_{};
|
millisecs_t last_host_response_time_{};
|
||||||
|
|||||||
2212
src/ballistica/game/game.cc
Normal file
2212
src/ballistica/game/game.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -38,8 +38,6 @@ class Game : public Module {
|
|||||||
const std::string& token) -> void;
|
const std::string& token) -> void;
|
||||||
auto PushAwardAdTicketsCall() -> void;
|
auto PushAwardAdTicketsCall() -> void;
|
||||||
auto PushAwardAdTournamentEntryCall() -> void;
|
auto PushAwardAdTournamentEntryCall() -> void;
|
||||||
auto PushUDPConnectionPacketCall(const std::vector<uint8_t>& data,
|
|
||||||
const SockAddr& addr) -> void;
|
|
||||||
auto PushPartyInviteCall(const std::string& name,
|
auto PushPartyInviteCall(const std::string& name,
|
||||||
const std::string& invite_id) -> void;
|
const std::string& invite_id) -> void;
|
||||||
auto PushPartyInviteRevokeCall(const std::string& invite_id) -> void;
|
auto PushPartyInviteRevokeCall(const std::string& invite_id) -> void;
|
||||||
@ -106,27 +104,11 @@ class Game : public Module {
|
|||||||
auto PushBackButtonCall(InputDevice* input_device) -> void;
|
auto PushBackButtonCall(InputDevice* input_device) -> void;
|
||||||
auto PushOnAppResumeCall() -> void;
|
auto PushOnAppResumeCall() -> void;
|
||||||
auto PushFrameDefRequest() -> void;
|
auto PushFrameDefRequest() -> void;
|
||||||
auto PushDisconnectFromHostCall() -> void;
|
|
||||||
auto PushClientDisconnectedCall(int id) -> void;
|
|
||||||
auto PushHostConnectedUDPCall(const SockAddr& addr,
|
|
||||||
bool print_connect_progress) -> void;
|
|
||||||
auto PushDisconnectedFromHostCall() -> void;
|
|
||||||
auto ChangeGameSpeed(int offs) -> void;
|
auto ChangeGameSpeed(int offs) -> void;
|
||||||
auto ResetInput() -> void;
|
auto ResetInput() -> void;
|
||||||
auto RunMainMenu() -> void;
|
auto RunMainMenu() -> void;
|
||||||
auto HandleThreadPause() -> void override;
|
auto HandleThreadPause() -> void override;
|
||||||
|
|
||||||
#if BA_GOOGLE_BUILD
|
|
||||||
auto PushClientDisconnectedGooglePlayCall(int id) -> void;
|
|
||||||
int GetGooglePlayClientCount() const;
|
|
||||||
auto PushHostConnectedGooglePlayCall() -> void;
|
|
||||||
auto PushClientConnectedGooglePlayCall(int id) -> void;
|
|
||||||
auto PushCompressedGamePacketFromHostGooglePlayCall(
|
|
||||||
const std::vector<uint8_t>& data) -> void;
|
|
||||||
auto PushCompressedGamePacketFromClientGooglePlayCall(
|
|
||||||
int google_client_id, const std::vector<uint8_t>& data) -> void;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BA_VR_BUILD
|
#if BA_VR_BUILD
|
||||||
auto PushVRHandsState(const VRHandsState& state) -> void;
|
auto PushVRHandsState(const VRHandsState& state) -> void;
|
||||||
const VRHandsState& vr_hands_state() const { return vr_hands_state_; }
|
const VRHandsState& vr_hands_state() const { return vr_hands_state_; }
|
||||||
@ -179,35 +161,6 @@ class Game : public Module {
|
|||||||
auto replay_speed_exponent() const -> int { return replay_speed_exponent_; }
|
auto replay_speed_exponent() const -> int { return replay_speed_exponent_; }
|
||||||
auto replay_speed_mult() const -> float { return replay_speed_mult_; }
|
auto replay_speed_mult() const -> float { return replay_speed_mult_; }
|
||||||
|
|
||||||
// Returns our host-connection or nullptr if there is none.
|
|
||||||
auto connection_to_host() -> ConnectionToHost* {
|
|
||||||
return connection_to_host_.get();
|
|
||||||
}
|
|
||||||
auto GetConnectionToHostUDP() -> ConnectionToHostUDP*;
|
|
||||||
|
|
||||||
// Send a screen message to all connected clients AND print it on the host.
|
|
||||||
auto SendScreenMessageToAll(const std::string& s, float r, float g, float b)
|
|
||||||
-> void;
|
|
||||||
|
|
||||||
// send a screen message to all connected clients
|
|
||||||
auto SendScreenMessageToClients(const std::string& s, float r, float g,
|
|
||||||
float b) -> void;
|
|
||||||
|
|
||||||
// Send a screen message to specific connected clients (those matching the IDs
|
|
||||||
// specified) the id -1 can be used to specify the host.
|
|
||||||
auto SendScreenMessageToSpecificClients(const std::string& s, float r,
|
|
||||||
float g, float b,
|
|
||||||
const std::vector<int>& clients)
|
|
||||||
-> void;
|
|
||||||
|
|
||||||
// Return our client connections (if any).
|
|
||||||
// FIXME: this prunes invalid connections, but it is necessary?
|
|
||||||
// Can we just use connections_to_clients() for direct access?
|
|
||||||
auto GetConnectionsToClients() -> std::vector<ConnectionToClient*>;
|
|
||||||
|
|
||||||
// Return the number of connections-to-client with "connected" status true.
|
|
||||||
auto GetConnectedClientCount() const -> int;
|
|
||||||
|
|
||||||
auto GetPartySize() const -> int;
|
auto GetPartySize() const -> int;
|
||||||
auto last_connection_to_client_join_time() const -> millisecs_t {
|
auto last_connection_to_client_join_time() const -> millisecs_t {
|
||||||
return last_connection_to_client_join_time_;
|
return last_connection_to_client_join_time_;
|
||||||
@ -216,34 +169,12 @@ class Game : public Module {
|
|||||||
last_connection_to_client_join_time_ = val;
|
last_connection_to_client_join_time_ = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple thread safe query.
|
|
||||||
auto has_connection_to_host() const -> bool {
|
|
||||||
return has_connection_to_host_;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto game_roster() const -> cJSON* { return game_roster_; }
|
auto game_roster() const -> cJSON* { return game_roster_; }
|
||||||
|
|
||||||
auto SendChatMessage(const std::string& message,
|
|
||||||
const std::vector<int>* clients = nullptr,
|
|
||||||
const std::string* sender_override = nullptr) -> void;
|
|
||||||
|
|
||||||
// Quick test as to whether there are clients. Does not check if they are
|
|
||||||
// fully connected.
|
|
||||||
auto has_connection_to_clients() const -> bool {
|
|
||||||
assert(InGameThread());
|
|
||||||
return (!connections_to_clients_.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto chat_messages() const -> const std::list<std::string>& {
|
auto chat_messages() const -> const std::list<std::string>& {
|
||||||
return chat_messages_;
|
return chat_messages_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whoever wants to wrangle current client connections should call this
|
|
||||||
// to register itself. Note that it must explicitly call unregister when
|
|
||||||
// unregistering itself.
|
|
||||||
auto RegisterClientController(ClientControllerInterface* c) -> void;
|
|
||||||
auto UnregisterClientController(ClientControllerInterface* c) -> void;
|
|
||||||
|
|
||||||
// Used to know which globals is in control currently/etc.
|
// Used to know which globals is in control currently/etc.
|
||||||
auto GetForegroundScene() const -> Scene* {
|
auto GetForegroundScene() const -> Scene* {
|
||||||
assert(InGameThread());
|
assert(InGameThread());
|
||||||
@ -251,19 +182,10 @@ class Game : public Module {
|
|||||||
}
|
}
|
||||||
auto SetForegroundScene(Scene* sg) -> void;
|
auto SetForegroundScene(Scene* sg) -> void;
|
||||||
|
|
||||||
// Returns true if disconnect attempts are supported.
|
|
||||||
auto DisconnectClient(int client_id, int ban_seconds) -> bool;
|
|
||||||
auto UpdateGameRoster() -> void;
|
auto UpdateGameRoster() -> void;
|
||||||
auto IsPlayerBanned(const PlayerSpec& spec) -> bool;
|
auto IsPlayerBanned(const PlayerSpec& spec) -> bool;
|
||||||
auto BanPlayer(const PlayerSpec& spec, millisecs_t duration) -> void;
|
auto BanPlayer(const PlayerSpec& spec, millisecs_t duration) -> void;
|
||||||
|
|
||||||
// For applying player-profiles data from the master-server.
|
|
||||||
auto SetClientInfoFromMasterServer(const std::string& client_token,
|
|
||||||
PyObject* info) -> void;
|
|
||||||
auto GetPrintUDPConnectProgress() const -> bool {
|
|
||||||
return print_udp_connect_progress_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For cheat detection. Returns the largest amount of time that has passed
|
// For cheat detection. Returns the largest amount of time that has passed
|
||||||
// between frames since our last reset (for detecting memory modification
|
// between frames since our last reset (for detecting memory modification
|
||||||
// UIs/etc).
|
// UIs/etc).
|
||||||
@ -298,20 +220,8 @@ class Game : public Module {
|
|||||||
return admin_public_ids_;
|
return admin_public_ids_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto connections_to_clients()
|
|
||||||
-> const std::map<int, Object::Ref<ConnectionToClient> >& {
|
|
||||||
return connections_to_clients_;
|
|
||||||
}
|
|
||||||
auto client_controller() -> ClientControllerInterface* {
|
|
||||||
return client_controller_;
|
|
||||||
}
|
|
||||||
auto kick_vote_in_progress() const -> bool { return kick_vote_in_progress_; }
|
auto kick_vote_in_progress() const -> bool { return kick_vote_in_progress_; }
|
||||||
|
|
||||||
#if BA_GOOGLE_BUILD
|
|
||||||
auto ClientIDFromGooglePlayClientID(int google_id) -> int;
|
|
||||||
auto GooglePlayClientIDFromClientID(int client_id) -> int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto SetPublicPartyEnabled(bool val) -> void;
|
auto SetPublicPartyEnabled(bool val) -> void;
|
||||||
auto public_party_enabled() const { return public_party_enabled_; }
|
auto public_party_enabled() const { return public_party_enabled_; }
|
||||||
auto public_party_size() const { return public_party_size_; }
|
auto public_party_size() const { return public_party_size_; }
|
||||||
@ -333,12 +243,16 @@ class Game : public Module {
|
|||||||
auto public_party_player_count() const { return public_party_player_count_; }
|
auto public_party_player_count() const { return public_party_player_count_; }
|
||||||
auto SetPublicPartyPlayerCount(int count) -> void;
|
auto SetPublicPartyPlayerCount(int count) -> void;
|
||||||
auto ran_app_launch_commands() const { return ran_app_launch_commands_; }
|
auto ran_app_launch_commands() const { return ran_app_launch_commands_; }
|
||||||
|
auto CleanUpBeforeConnectingToHost() -> void;
|
||||||
|
auto connections() -> ConnectionSet* {
|
||||||
|
assert(connections_.get());
|
||||||
|
return connections_.get();
|
||||||
|
}
|
||||||
|
auto mark_game_roster_dirty() -> void { game_roster_dirty_ = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto InitSpecialChars() -> void;
|
auto InitSpecialChars() -> void;
|
||||||
auto Draw() -> void;
|
auto Draw() -> void;
|
||||||
auto UDPConnectionPacket(const std::vector<uint8_t>& data,
|
|
||||||
const SockAddr& addr) -> void;
|
|
||||||
auto PartyInvite(const std::string& name, const std::string& invite_id)
|
auto PartyInvite(const std::string& name, const std::string& invite_id)
|
||||||
-> void;
|
-> void;
|
||||||
auto PartyInviteRevoke(const std::string& invite_id) -> void;
|
auto PartyInviteRevoke(const std::string& invite_id) -> void;
|
||||||
@ -358,8 +272,6 @@ class Game : public Module {
|
|||||||
int rift_step_index_{};
|
int rift_step_index_{};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto HandleClientDisconnected(int id) -> void;
|
|
||||||
auto ForceDisconnectClients() -> void;
|
|
||||||
auto Prune() -> void; // Periodic pruning of dead stuff.
|
auto Prune() -> void; // Periodic pruning of dead stuff.
|
||||||
auto Update() -> void;
|
auto Update() -> void;
|
||||||
auto Process() -> void;
|
auto Process() -> void;
|
||||||
@ -370,21 +282,11 @@ class Game : public Module {
|
|||||||
auto UpdateProcessTimer() -> void;
|
auto UpdateProcessTimer() -> void;
|
||||||
auto Reset() -> void;
|
auto Reset() -> void;
|
||||||
auto GetGameRosterMessage() -> std::vector<uint8_t>;
|
auto GetGameRosterMessage() -> std::vector<uint8_t>;
|
||||||
auto CleanUpBeforeConnectingToHost() -> void;
|
|
||||||
auto Shutdown(bool soft) -> void;
|
auto Shutdown(bool soft) -> void;
|
||||||
|
|
||||||
std::map<int, int> google_play_id_to_client_id_map_;
|
std::unique_ptr<ConnectionSet> connections_;
|
||||||
std::map<int, int> client_id_to_google_play_id_map_;
|
|
||||||
bool print_udp_connect_progress_{true};
|
|
||||||
std::list<std::pair<millisecs_t, PlayerSpec> > banned_players_;
|
std::list<std::pair<millisecs_t, PlayerSpec> > banned_players_;
|
||||||
ClientControllerInterface* client_controller_{};
|
|
||||||
std::list<std::string> chat_messages_;
|
std::list<std::string> chat_messages_;
|
||||||
|
|
||||||
// Simple flag for thread-safe access.
|
|
||||||
bool has_connection_to_host_{};
|
|
||||||
|
|
||||||
// Prevents us from printing multiple 'you got disconnected' messages.
|
|
||||||
bool printed_host_disconnect_{};
|
|
||||||
bool chat_muted_{};
|
bool chat_muted_{};
|
||||||
bool first_update_{true};
|
bool first_update_{true};
|
||||||
bool game_roster_dirty_{};
|
bool game_roster_dirty_{};
|
||||||
@ -423,10 +325,6 @@ class Game : public Module {
|
|||||||
bool kick_voting_enabled_{true};
|
bool kick_voting_enabled_{true};
|
||||||
std::set<std::string> admin_public_ids_;
|
std::set<std::string> admin_public_ids_;
|
||||||
|
|
||||||
// Try to minimize the chance a garbage packet will have this id.
|
|
||||||
int next_connection_to_client_id_{113};
|
|
||||||
std::map<int, Object::Ref<ConnectionToClient> > connections_to_clients_;
|
|
||||||
Object::Ref<ConnectionToHost> connection_to_host_;
|
|
||||||
cJSON* game_roster_{};
|
cJSON* game_roster_{};
|
||||||
millisecs_t kick_vote_end_time_{};
|
millisecs_t kick_vote_end_time_{};
|
||||||
bool kick_vote_in_progress_{};
|
bool kick_vote_in_progress_{};
|
||||||
|
|||||||
@ -17,70 +17,75 @@ class GameStream : public Object, public ClientControllerInterface {
|
|||||||
public:
|
public:
|
||||||
GameStream(HostSession* host_session, bool saveReplay);
|
GameStream(HostSession* host_session, bool saveReplay);
|
||||||
~GameStream() override;
|
~GameStream() override;
|
||||||
void SetTime(millisecs_t t);
|
auto SetTime(millisecs_t t) -> void;
|
||||||
void AddScene(Scene* s);
|
auto AddScene(Scene* s) -> void;
|
||||||
void RemoveScene(Scene* s);
|
auto RemoveScene(Scene* s) -> void;
|
||||||
void StepScene(Scene* s);
|
auto StepScene(Scene* s) -> void;
|
||||||
void AddNode(Node* n);
|
auto AddNode(Node* n) -> void;
|
||||||
void NodeOnCreate(Node* n);
|
auto NodeOnCreate(Node* n) -> void;
|
||||||
void RemoveNode(Node* n);
|
auto RemoveNode(Node* n) -> void;
|
||||||
void SetForegroundScene(Scene* sg);
|
auto SetForegroundScene(Scene* sg) -> void;
|
||||||
void AddMaterial(Material* m);
|
auto AddMaterial(Material* m) -> void;
|
||||||
void RemoveMaterial(Material* m);
|
auto RemoveMaterial(Material* m) -> void;
|
||||||
void AddMaterialComponent(Material* m, MaterialComponent* c);
|
auto AddMaterialComponent(Material* m, MaterialComponent* c) -> void;
|
||||||
void AddTexture(Texture* t);
|
auto AddTexture(Texture* t) -> void;
|
||||||
void RemoveTexture(Texture* t);
|
auto RemoveTexture(Texture* t) -> void;
|
||||||
void AddModel(Model* t);
|
auto AddModel(Model* t) -> void;
|
||||||
void RemoveModel(Model* t);
|
auto RemoveModel(Model* t) -> void;
|
||||||
void AddSound(Sound* t);
|
auto AddSound(Sound* t) -> void;
|
||||||
void RemoveSound(Sound* t);
|
auto RemoveSound(Sound* t) -> void;
|
||||||
void AddData(Data* d);
|
auto AddData(Data* d) -> void;
|
||||||
void RemoveData(Data* d);
|
auto RemoveData(Data* d) -> void;
|
||||||
void AddCollideModel(CollideModel* t);
|
auto AddCollideModel(CollideModel* t) -> void;
|
||||||
void RemoveCollideModel(CollideModel* t);
|
auto RemoveCollideModel(CollideModel* t) -> void;
|
||||||
void ConnectNodeAttribute(Node* src_node, NodeAttributeUnbound* src_attr,
|
auto ConnectNodeAttribute(Node* src_node, NodeAttributeUnbound* src_attr,
|
||||||
Node* dst_node, NodeAttributeUnbound* dst_attr);
|
Node* dst_node, NodeAttributeUnbound* dst_attr)
|
||||||
void NodeMessage(Node* node, const char* buffer, size_t size);
|
-> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, float val);
|
auto NodeMessage(Node* node, const char* buffer, size_t size) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, int64_t val);
|
auto SetNodeAttr(const NodeAttribute& attr, float val) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, bool val);
|
auto SetNodeAttr(const NodeAttribute& attr, int64_t val) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::vector<float>& vals);
|
auto SetNodeAttr(const NodeAttribute& attr, bool val) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::vector<int64_t>& vals);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<float>& vals)
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::string& val);
|
-> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, Node* n);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<int64_t>& vals)
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::vector<Node*>& vals);
|
-> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, Player* n);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::string& val) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr,
|
auto SetNodeAttr(const NodeAttribute& attr, Node* n) -> void;
|
||||||
const std::vector<Material*>& vals);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<Node*>& vals)
|
||||||
void SetNodeAttr(const NodeAttribute& attr, Texture* n);
|
-> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr,
|
auto SetNodeAttr(const NodeAttribute& attr, Player* n) -> void;
|
||||||
const std::vector<Texture*>& vals);
|
auto SetNodeAttr(const NodeAttribute& attr,
|
||||||
void SetNodeAttr(const NodeAttribute& attr, Sound* n);
|
const std::vector<Material*>& vals) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::vector<Sound*>& vals);
|
auto SetNodeAttr(const NodeAttribute& attr, Texture* n) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, Model* n);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<Texture*>& vals)
|
||||||
void SetNodeAttr(const NodeAttribute& attr, const std::vector<Model*>& vals);
|
-> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr, CollideModel* n);
|
auto SetNodeAttr(const NodeAttribute& attr, Sound* n) -> void;
|
||||||
void SetNodeAttr(const NodeAttribute& attr,
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<Sound*>& vals)
|
||||||
const std::vector<CollideModel*>& vals);
|
-> void;
|
||||||
void PlaySoundAtPosition(Sound* sound, float volume, float x, float y,
|
auto SetNodeAttr(const NodeAttribute& attr, Model* n) -> void;
|
||||||
float z);
|
auto SetNodeAttr(const NodeAttribute& attr, const std::vector<Model*>& vals)
|
||||||
void PlaySound(Sound* sound, float volume);
|
-> void;
|
||||||
void EmitBGDynamics(const BGDynamicsEmission& e);
|
auto SetNodeAttr(const NodeAttribute& attr, CollideModel* n) -> void;
|
||||||
|
auto SetNodeAttr(const NodeAttribute& attr,
|
||||||
|
const std::vector<CollideModel*>& vals) -> void;
|
||||||
|
auto PlaySoundAtPosition(Sound* sound, float volume, float x, float y,
|
||||||
|
float z) -> void;
|
||||||
|
auto PlaySound(Sound* sound, float volume) -> void;
|
||||||
|
auto EmitBGDynamics(const BGDynamicsEmission& e) -> void;
|
||||||
auto GetSoundID(Sound* s) -> int64_t;
|
auto GetSoundID(Sound* s) -> int64_t;
|
||||||
auto GetMaterialID(Material* m) -> int64_t;
|
auto GetMaterialID(Material* m) -> int64_t;
|
||||||
void ScreenMessageBottom(const std::string& val, float r, float g, float b);
|
auto ScreenMessageBottom(const std::string& val, float r, float g, float b)
|
||||||
void ScreenMessageTop(const std::string& val, float r, float g, float b,
|
-> void;
|
||||||
|
auto ScreenMessageTop(const std::string& val, float r, float g, float b,
|
||||||
Texture* texture, Texture* tint_texture, float tint_r,
|
Texture* texture, Texture* tint_texture, float tint_r,
|
||||||
float tint_g, float tint_b, float tint2_r,
|
float tint_g, float tint_b, float tint2_r,
|
||||||
float tint2_g, float tint2_b);
|
float tint2_g, float tint2_b) -> void;
|
||||||
void OnClientConnected(ConnectionToClient* c) override;
|
auto OnClientConnected(ConnectionToClient* c) -> void override;
|
||||||
void OnClientDisconnected(ConnectionToClient* c) override;
|
auto OnClientDisconnected(ConnectionToClient* c) -> void override;
|
||||||
auto GetOutMessage() const -> std::vector<uint8_t>;
|
auto GetOutMessage() const -> std::vector<uint8_t>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HostSession* host_session_;
|
// Make sure various components are part of our stream.
|
||||||
|
|
||||||
// Make sure the scene is in our stream.
|
|
||||||
auto IsValidScene(Scene* val) -> bool;
|
auto IsValidScene(Scene* val) -> bool;
|
||||||
auto IsValidNode(Node* val) -> bool;
|
auto IsValidNode(Node* val) -> bool;
|
||||||
auto IsValidTexture(Texture* val) -> bool;
|
auto IsValidTexture(Texture* val) -> bool;
|
||||||
@ -89,9 +94,49 @@ class GameStream : public Object, public ClientControllerInterface {
|
|||||||
auto IsValidData(Data* val) -> bool;
|
auto IsValidData(Data* val) -> bool;
|
||||||
auto IsValidCollideModel(CollideModel* val) -> bool;
|
auto IsValidCollideModel(CollideModel* val) -> bool;
|
||||||
auto IsValidMaterial(Material* val) -> bool;
|
auto IsValidMaterial(Material* val) -> bool;
|
||||||
|
|
||||||
|
auto Flush() -> void;
|
||||||
|
auto AddMessageToReplay(const std::vector<uint8_t>& message) -> void;
|
||||||
|
auto Fail() -> void;
|
||||||
|
|
||||||
|
auto ShipSessionCommandsMessage() -> void;
|
||||||
|
auto SendPhysicsCorrection(bool blend) -> void;
|
||||||
|
auto EndCommand(bool is_time_set = false) -> void;
|
||||||
|
auto WriteString(const std::string& s) -> void;
|
||||||
|
auto WriteFloat(float val) -> void;
|
||||||
|
auto WriteFloats(size_t count, const float* vals) -> void;
|
||||||
|
auto WriteInts32(size_t count, const int32_t* vals) -> void;
|
||||||
|
auto WriteInts64(size_t count, const int64_t* vals) -> void;
|
||||||
|
auto WriteChars(size_t count, const char* vals) -> void;
|
||||||
|
auto WriteCommand(SessionCommand cmd) -> void;
|
||||||
|
auto WriteCommandInt32(SessionCommand cmd, int32_t value) -> void;
|
||||||
|
auto WriteCommandInt64(SessionCommand cmd, int64_t value) -> void;
|
||||||
|
auto WriteCommandInt32_2(SessionCommand cmd, int32_t value1, int32_t value2)
|
||||||
|
-> void;
|
||||||
|
auto WriteCommandInt64_2(SessionCommand cmd, int64_t value1, int64_t value2)
|
||||||
|
-> void;
|
||||||
|
auto WriteCommandInt32_3(SessionCommand cmd, int32_t value1, int32_t value2,
|
||||||
|
int32_t value3) -> void;
|
||||||
|
auto WriteCommandInt64_3(SessionCommand cmd, int64_t value1, int64_t value2,
|
||||||
|
int64_t value3) -> void;
|
||||||
|
auto WriteCommandInt32_4(SessionCommand cmd, int32_t value1, int32_t value2,
|
||||||
|
int32_t value3, int32_t value4) -> void;
|
||||||
|
auto WriteCommandInt64_4(SessionCommand cmd, int64_t value1, int64_t value2,
|
||||||
|
int64_t value3, int64_t value4) -> void;
|
||||||
|
template <typename T>
|
||||||
|
auto GetPointerCount(const std::vector<T*>& vec) -> size_t;
|
||||||
|
template <typename T>
|
||||||
|
auto GetFreeIndex(std::vector<T*>* vec, std::vector<size_t>* free_indices)
|
||||||
|
-> size_t;
|
||||||
|
template <typename T>
|
||||||
|
auto Add(T* val, std::vector<T*>* vec, std::vector<size_t>* free_indices)
|
||||||
|
-> void;
|
||||||
|
template <typename T>
|
||||||
|
auto Remove(T* val, std::vector<T*>* vec, std::vector<size_t>* free_indices)
|
||||||
|
-> void;
|
||||||
|
|
||||||
|
HostSession* host_session_;
|
||||||
millisecs_t next_flush_time_;
|
millisecs_t next_flush_time_;
|
||||||
void Flush();
|
|
||||||
void AddMessageToReplay(const std::vector<uint8_t>& message);
|
|
||||||
|
|
||||||
// Individual command going into the commands-messages.
|
// Individual command going into the commands-messages.
|
||||||
std::vector<uint8_t> out_command_;
|
std::vector<uint8_t> out_command_;
|
||||||
@ -101,40 +146,8 @@ class GameStream : public Object, public ClientControllerInterface {
|
|||||||
std::vector<ConnectionToClient*> connections_to_clients_;
|
std::vector<ConnectionToClient*> connections_to_clients_;
|
||||||
std::vector<ConnectionToClient*> connections_to_clients_ignored_;
|
std::vector<ConnectionToClient*> connections_to_clients_ignored_;
|
||||||
bool writing_replay_;
|
bool writing_replay_;
|
||||||
void Fail();
|
|
||||||
millisecs_t last_physics_correction_time_;
|
millisecs_t last_physics_correction_time_;
|
||||||
millisecs_t last_send_time_;
|
millisecs_t last_send_time_;
|
||||||
void ShipSessionCommandsMessage();
|
|
||||||
void SendPhysicsCorrection(bool blend);
|
|
||||||
void EndCommand(bool is_time_set = false);
|
|
||||||
void WriteString(const std::string& s);
|
|
||||||
void WriteFloat(float val);
|
|
||||||
void WriteFloats(size_t count, const float* vals);
|
|
||||||
void WriteInts32(size_t count, const int32_t* vals);
|
|
||||||
void WriteInts64(size_t count, const int64_t* vals);
|
|
||||||
void WriteChars(size_t count, const char* vals);
|
|
||||||
void WriteCommand(SessionCommand cmd);
|
|
||||||
void WriteCommandInt32(SessionCommand cmd, int32_t value);
|
|
||||||
void WriteCommandInt64(SessionCommand cmd, int64_t value);
|
|
||||||
void WriteCommandInt32_2(SessionCommand cmd, int32_t value1, int32_t value2);
|
|
||||||
void WriteCommandInt64_2(SessionCommand cmd, int64_t value1, int64_t value2);
|
|
||||||
void WriteCommandInt32_3(SessionCommand cmd, int32_t value1, int32_t value2,
|
|
||||||
int32_t value3);
|
|
||||||
void WriteCommandInt64_3(SessionCommand cmd, int64_t value1, int64_t value2,
|
|
||||||
int64_t value3);
|
|
||||||
void WriteCommandInt32_4(SessionCommand cmd, int32_t value1, int32_t value2,
|
|
||||||
int32_t value3, int32_t value4);
|
|
||||||
void WriteCommandInt64_4(SessionCommand cmd, int64_t value1, int64_t value2,
|
|
||||||
int64_t value3, int64_t value4);
|
|
||||||
template <typename T>
|
|
||||||
auto GetPointerCount(const std::vector<T*>& vec) -> size_t;
|
|
||||||
template <typename T>
|
|
||||||
auto GetFreeIndex(std::vector<T*>* vec, std::vector<size_t>* free_indices)
|
|
||||||
-> size_t;
|
|
||||||
template <typename T>
|
|
||||||
void Add(T* val, std::vector<T*>* vec, std::vector<size_t>* free_indices);
|
|
||||||
template <typename T>
|
|
||||||
void Remove(T* val, std::vector<T*>* vec, std::vector<size_t>* free_indices);
|
|
||||||
millisecs_t time_;
|
millisecs_t time_;
|
||||||
std::vector<Scene*> scenes_;
|
std::vector<Scene*> scenes_;
|
||||||
std::vector<size_t> free_indices_scene_graphs_;
|
std::vector<size_t> free_indices_scene_graphs_;
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "ballistica/app/app.h"
|
#include "ballistica/app/app.h"
|
||||||
#include "ballistica/app/app_globals.h"
|
#include "ballistica/app/app_globals.h"
|
||||||
#include "ballistica/dynamics/bg/bg_dynamics.h"
|
#include "ballistica/dynamics/bg/bg_dynamics.h"
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/connection/connection_to_client.h"
|
#include "ballistica/game/connection/connection_to_client.h"
|
||||||
#include "ballistica/game/connection/connection_to_host.h"
|
#include "ballistica/game/connection/connection_to_host.h"
|
||||||
#include "ballistica/game/session/session.h"
|
#include "ballistica/game/session/session.h"
|
||||||
@ -295,7 +296,8 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
|||||||
bool show = false;
|
bool show = false;
|
||||||
|
|
||||||
// Add in/out data for any host connection.
|
// Add in/out data for any host connection.
|
||||||
if (ConnectionToHost* connection_to_host = g_game->connection_to_host()) {
|
if (ConnectionToHost* connection_to_host =
|
||||||
|
g_game->connections()->connection_to_host()) {
|
||||||
if (connection_to_host->can_communicate()) show = true;
|
if (connection_to_host->can_communicate()) show = true;
|
||||||
in_size += connection_to_host->GetBytesInPerSecond();
|
in_size += connection_to_host->GetBytesInPerSecond();
|
||||||
in_size_compressed += connection_to_host->GetBytesInPerSecondCompressed();
|
in_size_compressed += connection_to_host->GetBytesInPerSecondCompressed();
|
||||||
@ -309,7 +311,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
|||||||
ping = connection_to_host->average_ping();
|
ping = connection_to_host->average_ping();
|
||||||
} else {
|
} else {
|
||||||
int connected_count = 0;
|
int connected_count = 0;
|
||||||
for (auto&& i : g_game->connections_to_clients()) {
|
for (auto&& i : g_game->connections()->connections_to_clients()) {
|
||||||
ConnectionToClient* client = i.second.get();
|
ConnectionToClient* client = i.second.get();
|
||||||
if (client->can_communicate()) {
|
if (client->can_communicate()) {
|
||||||
show = true;
|
show = true;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "ballistica/app/app.h"
|
#include "ballistica/app/app.h"
|
||||||
#include "ballistica/app/app_globals.h"
|
#include "ballistica/app/app_globals.h"
|
||||||
#include "ballistica/audio/audio.h"
|
#include "ballistica/audio/audio.h"
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/player.h"
|
#include "ballistica/game/player.h"
|
||||||
#include "ballistica/graphics/renderer.h"
|
#include "ballistica/graphics/renderer.h"
|
||||||
#include "ballistica/python/python.h"
|
#include "ballistica/python/python.h"
|
||||||
@ -1024,7 +1025,7 @@ void Joystick::HandleSDLEvent(const SDL_Event* e) {
|
|||||||
// FIXME: Need a call we can make for this.
|
// FIXME: Need a call we can make for this.
|
||||||
bool do_party_button = false;
|
bool do_party_button = false;
|
||||||
int party_size = g_game->GetPartySize();
|
int party_size = g_game->GetPartySize();
|
||||||
if (party_size > 1 || g_game->connection_to_host()
|
if (party_size > 1 || g_game->connections()->connection_to_host()
|
||||||
|| g_ui->root_ui()->always_draw_party_icon()) {
|
|| g_ui->root_ui()->always_draw_party_icon()) {
|
||||||
do_party_button = true;
|
do_party_button = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -137,22 +137,6 @@ class Networking {
|
|||||||
};
|
};
|
||||||
auto GetScanResults() -> std::vector<ScanResultsEntry>;
|
auto GetScanResults() -> std::vector<ScanResultsEntry>;
|
||||||
|
|
||||||
/// Sends a POST request to the master server and returns the response.
|
|
||||||
/// path should be something like "/mystatspage".
|
|
||||||
/// Throws std::exceptions (NOT ballistica Exceptions) if something goes
|
|
||||||
/// wrong.
|
|
||||||
static auto MasterServerPost(
|
|
||||||
const std::string& path,
|
|
||||||
const std::map<std::string, std::string>& parameters,
|
|
||||||
bool use_fallback_addr = false) -> std::string;
|
|
||||||
|
|
||||||
/// Sends a GET request to the master server and returns the response.
|
|
||||||
/// path should be something like "/mystatspage".
|
|
||||||
/// Throws std::exceptions (NOT ballistica Exceptions) if something goes
|
|
||||||
/// wrong.
|
|
||||||
static auto MasterServerGet(const std::string& path,
|
|
||||||
bool use_fallback_addr = false) -> std::string;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PruneScanResults();
|
void PruneScanResults();
|
||||||
struct ScanResultsEntryPriv;
|
struct ScanResultsEntryPriv;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "ballistica/app/app.h"
|
#include "ballistica/app/app.h"
|
||||||
#include "ballistica/app/app_globals.h"
|
#include "ballistica/app/app_globals.h"
|
||||||
#include "ballistica/core/logging.h"
|
#include "ballistica/core/logging.h"
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/game_stream.h"
|
#include "ballistica/game/game_stream.h"
|
||||||
#include "ballistica/game/host_activity.h"
|
#include "ballistica/game/host_activity.h"
|
||||||
#include "ballistica/game/session/host_session.h"
|
#include "ballistica/game/session/host_session.h"
|
||||||
@ -501,10 +502,11 @@ auto PyScreenMessage(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
std::vector<int32_t> client_ids;
|
std::vector<int32_t> client_ids;
|
||||||
if (clients_obj != Py_None) {
|
if (clients_obj != Py_None) {
|
||||||
std::vector<int> client_ids2 = Python::GetPyInts(clients_obj);
|
std::vector<int> client_ids2 = Python::GetPyInts(clients_obj);
|
||||||
g_game->SendScreenMessageToSpecificClients(message, color.x, color.y,
|
g_game->connections()->SendScreenMessageToSpecificClients(
|
||||||
color.z, client_ids2);
|
message, color.x, color.y, color.z, client_ids2);
|
||||||
} else {
|
} else {
|
||||||
g_game->SendScreenMessageToAll(message, color.x, color.y, color.z);
|
g_game->connections()->SendScreenMessageToAll(message, color.x, color.y,
|
||||||
|
color.z);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Currently specifying client_ids only works for transient messages; we'd
|
// Currently specifying client_ids only works for transient messages; we'd
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "ballistica/dynamics/collision.h"
|
#include "ballistica/dynamics/collision.h"
|
||||||
#include "ballistica/dynamics/dynamics.h"
|
#include "ballistica/dynamics/dynamics.h"
|
||||||
#include "ballistica/dynamics/material/material_action.h"
|
#include "ballistica/dynamics/material/material_action.h"
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/connection/connection_to_client.h"
|
#include "ballistica/game/connection/connection_to_client.h"
|
||||||
#include "ballistica/game/game_stream.h"
|
#include "ballistica/game/game_stream.h"
|
||||||
#include "ballistica/game/host_activity.h"
|
#include "ballistica/game/host_activity.h"
|
||||||
@ -467,8 +468,9 @@ auto PyGetGameRoster(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
if (clientid == -1) {
|
if (clientid == -1) {
|
||||||
account_id = AppInternalGetPublicAccountID();
|
account_id = AppInternalGetPublicAccountID();
|
||||||
} else {
|
} else {
|
||||||
auto client2 = g_game->connections_to_clients().find(clientid);
|
auto client2 =
|
||||||
if (client2 != g_game->connections_to_clients().end()) {
|
g_game->connections()->connections_to_clients().find(clientid);
|
||||||
|
if (client2 != g_game->connections()->connections_to_clients().end()) {
|
||||||
account_id = client2->second->peer_public_account_id();
|
account_id = client2->second->peer_public_account_id();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "ballistica/app/app.h"
|
#include "ballistica/app/app.h"
|
||||||
#include "ballistica/app/app_globals.h"
|
#include "ballistica/app/app_globals.h"
|
||||||
#include "ballistica/game/account.h"
|
#include "ballistica/game/account.h"
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/game.h"
|
#include "ballistica/game/game.h"
|
||||||
#include "ballistica/input/input.h"
|
#include "ballistica/input/input.h"
|
||||||
#include "ballistica/python/python.h"
|
#include "ballistica/python/python.h"
|
||||||
@ -2053,7 +2054,7 @@ auto PyChatMessage(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
std::vector<int> clients = Python::GetPyInts(clients_obj);
|
std::vector<int> clients = Python::GetPyInts(clients_obj);
|
||||||
clients_p = &clients;
|
clients_p = &clients;
|
||||||
}
|
}
|
||||||
g_game->SendChatMessage(message, clients_p, sender_override_p);
|
g_game->connections()->SendChatMessage(message, clients_p, sender_override_p);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
BA_PYTHON_CATCH;
|
BA_PYTHON_CATCH;
|
||||||
}
|
}
|
||||||
@ -2150,7 +2151,8 @@ auto PyCanShowAd(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
// them or whatnot) also disallow ads if remote apps are connected; at least
|
// them or whatnot) also disallow ads if remote apps are connected; at least
|
||||||
// on android ads pause our activity which disconnects the remote app.. (could
|
// on android ads pause our activity which disconnects the remote app.. (could
|
||||||
// potentially still allow on other platforms; should verify..)
|
// potentially still allow on other platforms; should verify..)
|
||||||
if (g_game->connection_to_host() || g_game->has_connection_to_clients()
|
if (g_game->connections()->connection_to_host()
|
||||||
|
|| g_game->connections()->has_connection_to_clients()
|
||||||
|| g_input->HaveRemoteAppController()) {
|
|| g_input->HaveRemoteAppController()) {
|
||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
@ -2262,7 +2264,8 @@ auto PyIsPartyIconVisible(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
Platform::SetLastPyCall("is_party_icon_visible");
|
Platform::SetLastPyCall("is_party_icon_visible");
|
||||||
BA_PYTHON_TRY;
|
BA_PYTHON_TRY;
|
||||||
bool party_button_active =
|
bool party_button_active =
|
||||||
(g_game->GetConnectedClientCount() > 0 || g_game->connection_to_host()
|
(g_game->connections()->GetConnectedClientCount() > 0
|
||||||
|
|| g_game->connections()->connection_to_host()
|
||||||
|| g_ui->root_ui()->always_draw_party_icon());
|
|| g_ui->root_ui()->always_draw_party_icon());
|
||||||
if (party_button_active) {
|
if (party_button_active) {
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "ballistica/game/connection/connection_set.h"
|
||||||
#include "ballistica/game/game.h"
|
#include "ballistica/game/game.h"
|
||||||
#include "ballistica/game/session/host_session.h"
|
#include "ballistica/game/session/host_session.h"
|
||||||
#include "ballistica/graphics/component/simple_component.h"
|
#include "ballistica/graphics/component/simple_component.h"
|
||||||
@ -46,7 +47,7 @@ RootUI::~RootUI() = default;
|
|||||||
|
|
||||||
void RootUI::TogglePartyWindowKeyPress() {
|
void RootUI::TogglePartyWindowKeyPress() {
|
||||||
assert(InGameThread());
|
assert(InGameThread());
|
||||||
if (g_game->GetPartySize() > 1 || g_game->connection_to_host()
|
if (g_game->GetPartySize() > 1 || g_game->connections()->connection_to_host()
|
||||||
|| always_draw_party_icon()) {
|
|| always_draw_party_icon()) {
|
||||||
ActivatePartyIcon();
|
ActivatePartyIcon();
|
||||||
}
|
}
|
||||||
@ -81,8 +82,9 @@ auto RootUI::HandleMouseButtonDown(float x, float y) -> bool {
|
|||||||
if (explicit_bool(DO_OLD_MENU_PARTY_BUTTONS)) {
|
if (explicit_bool(DO_OLD_MENU_PARTY_BUTTONS)) {
|
||||||
bool party_button_active =
|
bool party_button_active =
|
||||||
(!party_window_open_
|
(!party_window_open_
|
||||||
&& (g_game->GetConnectedClientCount() > 0
|
&& (g_game->connections()->GetConnectedClientCount() > 0
|
||||||
|| g_game->connection_to_host() || always_draw_party_icon()));
|
|| g_game->connections()->connection_to_host()
|
||||||
|
|| always_draw_party_icon()));
|
||||||
float party_button_left =
|
float party_button_left =
|
||||||
menu_active ? 2 * menu_button_size_ : menu_button_size_;
|
menu_active ? 2 * menu_button_size_ : menu_button_size_;
|
||||||
float party_button_right = menu_active ? menu_button_size_ : 0;
|
float party_button_right = menu_active ? menu_button_size_ : 0;
|
||||||
@ -202,7 +204,7 @@ void RootUI::Draw(FrameDef* frame_def) {
|
|||||||
// (this probably shouldn't live here).
|
// (this probably shouldn't live here).
|
||||||
bool draw_connected_players_icon = false;
|
bool draw_connected_players_icon = false;
|
||||||
int party_size = g_game->GetPartySize();
|
int party_size = g_game->GetPartySize();
|
||||||
bool is_host = (g_game->connection_to_host() == nullptr);
|
bool is_host = (g_game->connections()->connection_to_host() == nullptr);
|
||||||
millisecs_t last_connection_to_client_join_time =
|
millisecs_t last_connection_to_client_join_time =
|
||||||
g_game->last_connection_to_client_join_time();
|
g_game->last_connection_to_client_join_time();
|
||||||
|
|
||||||
@ -211,7 +213,7 @@ void RootUI::Draw(FrameDef* frame_def) {
|
|||||||
&& real_time - last_connection_to_client_join_time < 5000);
|
&& real_time - last_connection_to_client_join_time < 5000);
|
||||||
|
|
||||||
if (!party_window_open_
|
if (!party_window_open_
|
||||||
&& (party_size != 0 || g_game->connection_to_host()
|
&& (party_size != 0 || g_game->connections()->connection_to_host()
|
||||||
|| always_draw_party_icon_)) {
|
|| always_draw_party_icon_)) {
|
||||||
draw_connected_players_icon = true;
|
draw_connected_players_icon = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,23 +116,30 @@ def _trim_docstring(docstring: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _spelling(words: List[str]) -> None:
|
def _spelling(words: List[str]) -> None:
|
||||||
fname = '.idea/dictionaries/ericf.xml'
|
import os
|
||||||
with open(fname) as infile:
|
for fname in [
|
||||||
lines = infile.read().splitlines()
|
'.idea/dictionaries/ericf.xml',
|
||||||
if lines[2] != ' <words>':
|
'ballisticacore-cmake/.idea/dictionaries/ericf.xml'
|
||||||
raise RuntimeError('Unexpected dictionary format.')
|
]:
|
||||||
added_count = 0
|
if not os.path.exists(fname):
|
||||||
for word in words:
|
continue
|
||||||
line = f' <w>{word.lower()}</w>'
|
with open(fname) as infile:
|
||||||
if line not in lines:
|
lines = infile.read().splitlines()
|
||||||
lines.insert(3, line)
|
if lines[2] != ' <words>':
|
||||||
added_count += 1
|
raise RuntimeError('Unexpected dictionary format.')
|
||||||
|
added_count = 0
|
||||||
|
for word in words:
|
||||||
|
line = f' <w>{word.lower()}</w>'
|
||||||
|
if line not in lines:
|
||||||
|
lines.insert(3, line)
|
||||||
|
added_count += 1
|
||||||
|
|
||||||
with open(fname, 'w') as outfile:
|
with open(fname, 'w') as outfile:
|
||||||
# Sort lines in the words section.
|
# Sort lines in the words section.
|
||||||
assert all(l.startswith(' <w>') for l in lines[3:-3])
|
assert all(l.startswith(' <w>') for l in lines[3:-3])
|
||||||
outfile.write('\n'.join(lines[:3] + sorted(lines[3:-3]) + lines[-3:]))
|
outfile.write('\n'.join(lines[:3] + sorted(lines[3:-3]) +
|
||||||
print('Added', added_count, 'words to the dictionary.')
|
lines[-3:]))
|
||||||
|
print(f'Added {added_count} words to {fname}.')
|
||||||
|
|
||||||
|
|
||||||
def spelling_all() -> None:
|
def spelling_all() -> None:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user