From 7d2dc047b828ff5a0d84f4f0f781b04ef2ae77c6 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 5 Dec 2021 17:07:06 -0600 Subject: [PATCH 01/32] cleaning up the mumble link code --- burrito_link/gw2mumbleudp.c | 284 +++++++++++++++++++++--------------- 1 file changed, 169 insertions(+), 115 deletions(-) diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index 1181cfd1..2dafc435 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -6,26 +6,25 @@ // Do a rolling average on the player position because that seems to be // Roughly what the camera position is doing and doing this will remove // some weird jitter I hope -struct rolling_average_5 -{ +struct rolling_average_5 { UINT8 index; float points[5]; }; -float get_rolling_average(struct rolling_average_5 *points) -{ + + +float get_rolling_average(struct rolling_average_5 *points) { float sum = 0; - for (int i = 0; i < 5; i++) - { + for (int i = 0; i < 5; i++) { sum += points->points[i]; } return sum / 5.0; } -void replace_point_in_rolling_average(struct rolling_average_5 *points, float newvalue) -{ + + +void replace_point_in_rolling_average(struct rolling_average_5 *points, float newvalue) { points->points[points->index] = newvalue; points->index = points->index + 1; - if (points->index > 4) - { + if (points->index > 4) { points->index = 0; } } @@ -35,43 +34,115 @@ struct rolling_average_5 playerz_avg; float fAvatarAveragePosition[3]; +//////////////////////////////////////////////////////////////////////////////// +// LinkedMem struct +// +// This struct represents the Mumble Link shared memory datum that Guild Wars 2 +// uses to communicate live player and camera data, as well as some other +// bits of information that are useful for tools like burrito. +// // https://wiki.guildwars2.com/wiki/API:MumbleLink -struct LinkedMem -{ +// https://www.mumble.info/documentation/developer/positional-audio/link-plugin/ +//////////////////////////////////////////////////////////////////////////////// +struct LinkedMem { UINT32 uiVersion; + + // The current update tick DWORD uiTick; - float fAvatarPosition[3]; // The XYZ location of the player + + // The XYZ location of the player + float fAvatarPosition[3]; + + // A 3D unit vector representing the forward direction of the player character float fAvatarFront[3]; + + // A 3D unit vector representing the up direction of the player character float fAvatarTop[3]; - wchar_t name[256]; // The string "Guild Wars 2" [Ignored] - float fCameraPosition[3]; // The XYZ position of the camera - float fCameraFront[3]; // A unit vector extending out the front of the camera - float fCameraTop[3]; // A perpendicular vector to fCameraFront, used for calculating roll [Ignored] - wchar_t identity[256]; // A json string containing json data - UINT32 context_len; // A value that is always 48 [Ignored] - unsigned char context[256]; // See MumbleContext struct - wchar_t description[2048]; // Empty [Ignored] + + // The string "Guild Wars 2" + wchar_t name[256]; + + // The XYZ Position of the camera + float fCameraPosition[3]; + + // A 3D unit vector representing the forward direction of the camera + float fCameraFront[3]; + + // A 3D unit vector representing the up direction of the camera + float fCameraTop[3]; + + // A json string containing json data. See https://wiki.guildwars2.com/wiki/API:MumbleLink#identity + wchar_t identity[256]; + + // A value that is always 48 + UINT32 context_len; + + // A binary chunk containing another struct. See the MumbleContext struct below + unsigned char context[256]; + + // An Empty Array, this field is not used by guild wars 2 + wchar_t description[2048]; }; -struct MumbleContext -{ - unsigned char serverAddress[28]; // contains sockaddr_in or sockaddr_in6 // IGNORED + +//////////////////////////////////////////////////////////////////////////////// +// MumbleContext struct +// +// This struct represents the LinkedMem.context datum that is passed in +// LinkedMem. It is a struct that is entirely specific to Guild Wars 2 which +// is why it is seperated out from the more mumble-generic LinkedMem struct. +// +// https://wiki.guildwars2.com/wiki/API:MumbleLink#context +//////////////////////////////////////////////////////////////////////////////// +struct MumbleContext { + // The current address of the guild wars 2 server the player is connected to + // can be a ipv4 `sockaddr_in` or a ipv6 `sockaddr_in6` + unsigned char serverAddress[28]; + + // The Guild Wars 2 id for the map the player is currently in UINT32 mapId; + UINT32 mapType; UINT32 shardId; UINT32 instance; UINT32 buildId; - // Additional data beyond the 48 bytes Mumble uses for identification - UINT32 uiState; // Bitmask: Bit 1 = IsMapOpen, Bit 2 = IsCompassTopRight, Bit 3 = DoesCompassHaveRotationEnabled, Bit 4 = Game has focus, Bit 5 = Is in Competitive game mode, Bit 6 = Textbox has focus, Bit 7 = Is in Combat - UINT16 compassWidth; // pixels - UINT16 compassHeight; // pixels - float compassRotation; // radians - float playerX; // continentCoords - float playerY; // continentCoords - float mapCenterX; // continentCoords - float mapCenterY; // continentCoords + + // A bitmask of various boolean element of the UI state + // Bit 1 = IsMapOpen + // Bit 2 = IsCompassTopRight + // Bit 3 = DoesCompassHaveRotationEnabled + // Bit 4 = Game has focus + // Bit 5 = Is in Competitive game mode + // Bit 6 = Textbox has focus + // Bit 7 = Is in Combat + UINT32 uiState; + + // The width of the minimap in pixels + UINT16 compassWidth; + + // The height of the minimap in pixels + UINT16 compassHeight; + + // The rotation of the minimap contents in radians + float compassRotation; + + // The X location of the player in continentCoords + float playerX; + // The Y location of the player in continentCoords + float playerY; + + // The center X of the current map in continentCoords + float mapCenterX; + // The center Y of the current map in continentCoords + float mapCenterY; + + // The scale of how zoomed in the visible map or minimap is float mapScale; - UINT32 processId; // Windows process id + + // The windows process id of the Guild Wars 2 process + UINT32 processId; + + // An enum representing which mount is currenty being used by the player UINT8 mountIndex; }; @@ -89,9 +160,7 @@ HANDLE handle_lm; LPCTSTR mapped_lm; #endif -void initMumble() -{ - +void initMumble() { #ifdef _WIN32 // creates a shared memory IF it doesn't exist. otherwise, it returns the existing shared memory handle. // reference: https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory @@ -99,29 +168,28 @@ void initMumble() size_t BUF_SIZE = sizeof(struct LinkedMem); handle_lm = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // maximum object size (high-order DWORD) - BUF_SIZE, // maximum object size (low-order DWORD) - "MumbleLink"); // name of mapping object - // createfilemapping returns NULL when it fails, we print the error code for debugging purposes. - - if (handle_lm == NULL) - { + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + BUF_SIZE, // maximum object size (low-order DWORD) + "MumbleLink"); // name of mapping object + // createfilemapping returns NULL when it fails, we print the error code for debugging purposes. + + if (handle_lm == NULL) { printf("Could not create file mapping object (%lu).\n", GetLastError()); return; } - mapped_lm = (LPTSTR)MapViewOfFile(handle_lm, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - BUF_SIZE); + mapped_lm = (LPTSTR)MapViewOfFile( + handle_lm, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + BUF_SIZE); - if (mapped_lm == NULL) - { + if (mapped_lm == NULL) { printf("Could not map view of file (%lu).\n", GetLastError()); @@ -135,19 +203,17 @@ void initMumble() printf("successfully opened mumble link shared memory..\n"); #else char memname[256]; - snprintf(memname, 256, "/MumbleLink.%d", getuid()); + snprintf(memname, sizeof(memname), "/MumbleLink.%d", getuid()); int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); - if (shmfd < 0) - { + if (shmfd < 0) { return; } lm = (struct LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)); - if (lm == (void *)(-1)) - { + if (lm == (void *)(-1)) { lm = NULL; return; } @@ -156,9 +222,16 @@ void initMumble() int last_map_id = 0; +// The max buffer size for data that is being sent to burriot over the UDP socket #define MaxBufferSize 1024 -int connect_and_or_send() -{ + +//////////////////////////////////////////////////////////////////////////////// +// connect_and_or_send() +// +// This function loops until termination, grabbing information from the shared +// memory block and sending the memory over to burrito over a UDP socket. +//////////////////////////////////////////////////////////////////////////////// +int connect_and_or_send() { WSADATA wsaData; SOCKET SendingSocket; SOCKADDR_IN ReceiverAddr, SrcInfo; @@ -168,9 +241,7 @@ int connect_and_or_send() int len; int TotalByteSent; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) - { - + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("Client: WSAStartup failed with error %d\n", WSAGetLastError()); // Clean up @@ -178,18 +249,14 @@ int connect_and_or_send() // Exit with error return -1; - } - else - { + } else { printf("Client: The Winsock DLL status is %s.\n", wsaData.szSystemStatus); } // Create a new socket to receive datagrams on. SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (SendingSocket == INVALID_SOCKET) - { - + if (SendingSocket == INVALID_SOCKET) { // Print error message printf("Client: Error at socket(): %d\n", WSAGetLastError()); @@ -198,9 +265,7 @@ int connect_and_or_send() // Exit with error return -1; - } - else - { + } else { printf("Client: socket() is OK!\n"); } @@ -218,16 +283,12 @@ int connect_and_or_send() int count = 0; DWORD lastuitick = 0; // Send data packages to the receiver(Server). - do - { - - if (lm->uiTick == lastuitick) - { + do { + if (lm->uiTick == lastuitick) { Sleep(1); continue; } lastuitick = lm->uiTick; - //printf("%ld\n", lm->uiTick); replace_point_in_rolling_average(&playerx_avg, lm->fAvatarPosition[0]); replace_point_in_rolling_average(&playery_avg, lm->fAvatarPosition[1]); @@ -239,7 +300,8 @@ int connect_and_or_send() fAvatarAveragePosition[2] = get_rolling_average(&playerz_avg); BufLength = 1; - SendBuf[0] = 1; // Per Frame Updater + // Set the first byte of the packet to indicate this packet is a `Per Frame Updater` packet + SendBuf[0] = 1; memcpy(SendBuf + BufLength, lm->fCameraPosition, sizeof(lm->fCameraPosition)); BufLength += sizeof(lm->fCameraPosition); @@ -280,11 +342,15 @@ int connect_and_or_send() TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); - if (count == 0 || lc->mapId != last_map_id) - { + + // After so many iterations have passed or under specific conditions + // we will send a larger packet that contains more information about + // the current state of the game. + if (count == 0 || lc->mapId != last_map_id) { last_map_id = lc->mapId; BufLength = 1; - SendBuf[0] = 2; // Heaver Context Updater + // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet + SendBuf[0] = 2; // printf("hello world\n"); // printf("%ls\n", lm->description); @@ -330,14 +396,12 @@ int connect_and_or_send() // Get and send the linux x server window id UINT32 x11_window_id = 0; - HWND window_handle=NULL; - BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) - { + HWND window_handle = NULL; + BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) { DWORD processId; GetWindowThreadProcessId(hwnd, &processId); - if(processId == lParam) - { - window_handle=hwnd; + if (processId == lParam) { + window_handle = hwnd; return FALSE; } return TRUE; @@ -384,11 +448,11 @@ int connect_and_or_send() // break; } - // Sleep(16); // Slightly faster then 60fps which would be 16.6666666...ms + // Update the count for the `Heaver Context Updater` packet and reset + // it to 0 when it hits a threshold value. count += 1; - if (count > 500) - { + if (count > 500) { count = 0; } @@ -423,13 +487,9 @@ int connect_and_or_send() printf("Client: Finished sending. Closing the sending socket...\n"); - if (closesocket(SendingSocket) != 0) - { - + if (closesocket(SendingSocket) != 0) { printf("Client: closesocket() failed! Error code: %d\n", WSAGetLastError()); - } - else - { + } else { printf("Server: closesocket() is OK\n"); } @@ -437,40 +497,34 @@ int connect_and_or_send() printf("Client: Cleaning up...\n"); - if (WSACleanup() != 0) - { + if (WSACleanup() != 0) { printf("Client: WSACleanup() failed! Error code: %d\n", WSAGetLastError()); - } - - else - { + } else { printf("Client: WSACleanup() is OK\n"); } + #ifdef _WIN32 // unmap the shared memory from our process address space. UnmapViewOfFile(mapped_lm); // close LinkedMemory handle CloseHandle(handle_lm); - #endif + // Back to the system return 0; } -int main(int argc, char **argv) -{ + +//////////////////////////////////////////////////////////////////////////////// +// The main function initializes some global variables and shared memory. Then +// calls the connect_and_or_send process which loops until termination. +//////////////////////////////////////////////////////////////////////////////// +int main(int argc, char **argv) { playerx_avg.index = 0; playery_avg.index = 0; playerz_avg.index = 0; - printf("hello world\n"); initMumble(); - // sockmain(argc, argv); - // initMumble(); - // for (int i = 0; i < 100; i++) { - // printf("%f\n", lm->fAvatarPosition[0]); - // Sleep(16); // Slightly faster then 60fps which would be 16.6666666...ms - // } connect_and_or_send(); -} \ No newline at end of file +} From 42b484b25b6b19859a7506d16bca9b74aae3d8b2 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 5 Dec 2021 22:38:44 -0600 Subject: [PATCH 02/32] adding a timeout for burrito link to allow it to exit if it is orphaned --- burrito_link/gw2mumbleudp.c | 80 +++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index 2dafc435..e2fd78b0 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -2,6 +2,12 @@ #include #include #include +#include + +// Enumerations of the different packet types that can be sent +#define PACKET_FRAME 1 +#define PACKET_METADATA 2 +#define PACKET_LINK_TIMEOUT 3 // Do a rolling average on the player position because that seems to be // Roughly what the camera position is doing and doing this will remove @@ -151,6 +157,14 @@ struct MumbleContext { struct LinkedMem *lm = NULL; // mumble context pointer into the `lm` variable above. struct MumbleContext *lc = NULL; + +long program_timeout = 0; +long program_startime = 0; + + +time_t rawtime; + + #ifdef _WIN32 // handle to the shared memory of Mumble link . close at the end of program. windows will only release the shared memory once ALL handles are closed, @@ -234,11 +248,10 @@ int last_map_id = 0; int connect_and_or_send() { WSADATA wsaData; SOCKET SendingSocket; - SOCKADDR_IN ReceiverAddr, SrcInfo; + SOCKADDR_IN ReceiverAddr; int Port = 4242; int BufLength = 1024; char SendBuf[MaxBufferSize]; - int len; int TotalByteSent; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { @@ -284,6 +297,18 @@ int connect_and_or_send() { DWORD lastuitick = 0; // Send data packages to the receiver(Server). do { + if (program_timeout != 0 && clock()-program_startime > program_timeout) { + BufLength = 1; + // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet + SendBuf[0] = PACKET_LINK_TIMEOUT; + TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } + + printf("Breaking out due to timeout"); + break; + } if (lm->uiTick == lastuitick) { Sleep(1); continue; @@ -301,7 +326,7 @@ int connect_and_or_send() { BufLength = 1; // Set the first byte of the packet to indicate this packet is a `Per Frame Updater` packet - SendBuf[0] = 1; + SendBuf[0] = PACKET_FRAME; memcpy(SendBuf + BufLength, lm->fCameraPosition, sizeof(lm->fCameraPosition)); BufLength += sizeof(lm->fCameraPosition); @@ -341,7 +366,9 @@ int connect_and_or_send() { // printf("UI State: %i\n", lc->uiState); // Bitmask: Bit 1 = IsMapOpen, Bit 2 = IsCompassTopRight, Bit 3 = DoesCompassHaveRotationEnabled, Bit 4 = Game has focus, Bit 5 = Is in Competitive game mode, Bit 6 = Textbox has focus, Bit 7 = Is in Combat TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); - + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } // After so many iterations have passed or under specific conditions // we will send a larger packet that contains more information about @@ -350,7 +377,7 @@ int connect_and_or_send() { last_map_id = lc->mapId; BufLength = 1; // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet - SendBuf[0] = 2; + SendBuf[0] = PACKET_METADATA; // printf("hello world\n"); // printf("%ls\n", lm->description); @@ -444,7 +471,9 @@ int connect_and_or_send() { BufLength += converted_size; TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); - + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } // break; } @@ -455,37 +484,8 @@ int connect_and_or_send() { if (count > 500) { count = 0; } - - // TODO: Maybe make a way to break out of this loop beyond program termination } while (TRUE); - // Print some info on the receiver(Server) side... - - // Allocate the required resources - - memset(&SrcInfo, 0, sizeof(SrcInfo)); - - len = sizeof(SrcInfo); - - getsockname(SendingSocket, (SOCKADDR *)&SrcInfo, &len); - - printf("Client: Sending IP(s) used: %s\n", inet_ntoa(SrcInfo.sin_addr)); - - printf("Client: Sending port used: %d\n", htons(SrcInfo.sin_port)); - - // Print some info on the sender(Client) side... - - getpeername(SendingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr)); - - printf("Client: Receiving IP used: %s\n", inet_ntoa(ReceiverAddr.sin_addr)); - - printf("Client: Receiving port used: %d\n", htons(ReceiverAddr.sin_port)); - - printf("Client: Total byte sent: %d\n", TotalByteSent); - - // When your application is finished receiving datagrams close the socket. - - printf("Client: Finished sending. Closing the sending socket...\n"); if (closesocket(SendingSocket) != 0) { printf("Client: closesocket() failed! Error code: %d\n", WSAGetLastError()); @@ -520,6 +520,16 @@ int connect_and_or_send() { // calls the connect_and_or_send process which loops until termination. //////////////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { + + for (int i = 0; i < argc; i++) { + // If a timeout flag is passed in then set the timeout value + if (strcmp(argv[i], "--timeout") == 0) { + i = i+1; + program_timeout = atol(argv[i]) * CLOCKS_PER_SEC; + program_startime = clock(); + } + } + playerx_avg.index = 0; playery_avg.index = 0; playerz_avg.index = 0; From c01f8461530f5eb458f41ca48ac005342bf25963 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 5 Dec 2021 22:42:04 -0600 Subject: [PATCH 03/32] adding a method to allow for burrito link to be launched automatically --- Spatial.gd | 152 +++++++++++++++++++++++++++++++++++--------------- Spatial.tscn | 77 +++++++++++++++---------- project.godot | 4 +- 3 files changed, 155 insertions(+), 78 deletions(-) diff --git a/Spatial.gd b/Spatial.gd index 738b4d67..1de7f13c 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -27,7 +27,7 @@ var map_was_open = false var player_position := Vector3(0,0,0) # Player Position as accurate to Godot (z value sign is flipped) -var correct_player_position := Vector3(0,0,0) +var correct_player_position := Vector3(0,0,0) var compass_height: int = 0; var compass_width: int = 0; @@ -35,7 +35,7 @@ var compass_width: int = 0; # A temporary setting able to be configured by the user. It is used to allow # for faster trail mesh generation. The higher the value the fewer samples are -# taken for the MeshCSG leading to an overall lower number of polygons. +# taken for the MeshCSG leading to an overall lower number of polygons. var path_resolution = 1 # Variables that store opposit corners of the compass @@ -61,14 +61,67 @@ func _ready(): set_minimal_mouse_block() server.listen(4242) + if (Settings.burrito_link_auto_launch_enabled): + launch_burrito_link() + + +################################################################################ +# show_error +# +# This function prints a user error out. Currently it prints to stdout but may +# one day be shown to the user. +################################################################################ +func show_user_error(error_string: String): + print(error_string) + + +# The process id of burrito link if it is launched automatically by burrito +var burrito_link_process_id = 0 + +################################################################################ +# launch_burrito_link +# +# This function launches the burrito link binary using the values for it that +# are saved in "settings". +################################################################################ +func launch_burrito_link(): + for env_arg in Settings.burrito_link_env_args.split("\n"): + env_arg = env_arg.trim_prefix("export ") + var key_values = env_arg.split('=', true, 1) + + if len(key_values) != 2: + show_user_error("Invalid burrito_link environment arg: " + env_arg) + return + + var key = key_values[0] + var value = key_values[1].trim_prefix('"').trim_suffix('"') + OS.set_environment(key, value) + + # Launch burrito link with a 2 hour timeout + # If burrito crashes then burrito_link will automatically exit at the timeout. + # If burrito does not crash and the timeout expires then burrito will relaunch burrito_link automatically + burrito_link_process_id = OS.execute(Settings.burrito_link_wine_path, ["burrito_link/burrito_link.exe", "--timeout", "7200"], false) + +func close_burrito_link(): + if (burrito_link_process_id != 0): + OS.kill(burrito_link_process_id) + burrito_link_process_id = 0 + + +func exit_burrito(): + if Settings.burrito_link_auto_launch_enabled: + close_burrito_link() + get_tree().quit() + + func set_minimal_mouse_block(): var top_corner := Vector2(287, 0) var bottom_corner := Vector2(314, 32) - + if self.edit_panel_open: bottom_corner.y = 49 bottom_corner.x = 314+377 - + var clickthrough: PoolVector2Array = [ Vector2(top_corner.x ,top_corner.y), Vector2(bottom_corner.x, top_corner.y), @@ -84,7 +137,7 @@ func set_maximal_mouse_block(): # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): - #OS.window_position = Vector2(1920, 0) # TODO: This does not seem to work + #OS.window_position = Vector2(1920, 0) # TODO: This does not seem to work #OS.set_window_position(Vector2(1920,0)) #print(OS.window_position) server.poll() # Important @@ -105,7 +158,9 @@ func _process(delta): if packet_type == 1: decode_frame_packet(spb) elif packet_type == 2: - decode_context_packet(spb) + decode_context_packet(spb) + elif packet_type == 3: + decode_timeout_packet(spb) return @@ -116,14 +171,14 @@ func decode_frame_packet(spb: StreamPeerBuffer): spb.get_float(), spb.get_float() ) - + # Extract the rotation of the camera in the form of a normal vector var camera_facing = Vector3( spb.get_float(), spb.get_float(), spb.get_float() ) - + # Extract the position of the player's foot self.player_position = Vector3( spb.get_float(), @@ -131,10 +186,10 @@ func decode_frame_packet(spb: StreamPeerBuffer): spb.get_float() ) self.correct_player_position = Vector3(player_position.x, player_position.y, -player_position.z) - + if $Control/Position.visible: $Control/Position.text = "X " + str(player_position.x) + " Y " + str(player_position.y) + " Z " + str(-player_position.z) - + var map_offset = Vector2( spb.get_float(), spb.get_float() @@ -144,7 +199,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): map_scale = 0.000001 var map_rotation: float = spb.get_float() var ui_flags: int = spb.get_32() - + map_is_open = (ui_flags & 0x01) == 0x01; compass_is_top_right = (ui_flags & 0x02) == 0x02; var compass_rotation_is_enabled: bool = (ui_flags & 0x04) == 0x04; @@ -167,7 +222,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): $CameraMount.translation.x = camera_position.x $CameraMount.translation.y = camera_position.y $CameraMount.translation.z = -camera_position.z - + # Orent the camera in the same rotation as it is facing in game $CameraMount/Camera.rotation.x = asin(camera_facing.y) $CameraMount.rotation.y = -atan2(camera_facing.x, camera_facing.z) @@ -183,7 +238,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): var map_size = get_viewport().size var map_corner = Vector2(0, 0) - + if (!map_is_open): map_size = Vector2(compass_width, compass_height) if !compass_is_top_right: @@ -203,16 +258,16 @@ func decode_frame_packet(spb: StreamPeerBuffer): var x = (cosTheta * (player_map_position.x - pivot.x) - sinTheta * (player_map_position.y - pivot.y) + pivot.x); var y = (sinTheta * (player_map_position.x - pivot.x) + cosTheta * (player_map_position.y - pivot.y) + pivot.y); - + delta_position = player_map_position - Vector2(x, y); - + #print(map_rotation) $Control/MiniMap.rotation = map_rotation else: $Control/MiniMap.rotation = 0 - + var map_midpoint = map_size/2 + map_corner; - + $Control/MiniMap.scale=Vector2(map_object_scaling, map_object_scaling) var map_translation = map_offset $Control/MiniMap.position = (map_translation / map_scale) + map_midpoint - player_map_position + delta_position @@ -242,7 +297,7 @@ func decode_context_packet(spb: StreamPeerBuffer): var identity_length: int = spb.get_32() var identity_str = spb.get_utf8_string(identity_length) var identity = JSON.parse(identity_str).result - + # FOV Calculations # The minimum value on the FOV slider gives a float value in this field of 0.436 # The maximum value on the FOV slider gives a float value in this field of 1.222 @@ -255,7 +310,7 @@ func decode_context_packet(spb: StreamPeerBuffer): if self.map_id != old_map_id: print("New Map") - + print("Saving Old Map") self.markerdata[str(old_map_id)] = data_from_renderview() print("Loading New Map") @@ -272,6 +327,13 @@ func decode_context_packet(spb: StreamPeerBuffer): reset_minimap_masks() +func decode_timeout_packet(spb: StreamPeerBuffer): + if Settings.burrito_link_auto_launch_enabled: + print("Link Timeout Reached, should restart link if started by burrito automatically") + close_burrito_link() + launch_burrito_link() + + func reset_minimap_masks(): var viewport_size = get_viewport().size compass_corner1 = Vector2(0, 0) @@ -282,7 +344,7 @@ func reset_minimap_masks(): elif !map_is_open && compass_is_top_right: compass_corner1 = viewport_size - Vector2(compass_width, compass_height) compass_corner2 = compass_corner1 + Vector2(compass_width, compass_height) - + for minimap_path in $Control/MiniMap.get_children(): minimap_path.material.set_shader_param("minimap_corner", compass_corner1) minimap_path.material.set_shader_param("minimap_corner2", compass_corner2) @@ -291,7 +353,7 @@ var markerdata = {} var marker_file_path = "" func load_taco_markers(marker_json_file): self.marker_file_path = marker_json_file - + if is_xml_file(marker_json_file): print("Loading XML file from path ", marker_json_file) var parsed_taco_tuple = taco_parser.parse_taco_xml(marker_json_file) @@ -306,7 +368,7 @@ func load_taco_markers(marker_json_file): file.open(marker_json_file, file.READ) var text = file.get_as_text() self.markerdata = JSON.parse(text).result - + relative_textures_to_absolute_textures(marker_file_path.get_base_dir()) gen_map_markers() @@ -396,8 +458,8 @@ func _unhandled_input(event): if is_instance_valid(self.last_hover) and self.last_hover.has_method("unhover"): self.last_hover.unhover() self.last_hover = null - - + + ################################################################################ # ################################################################################ @@ -427,13 +489,13 @@ func gen_map_markers(): gen_new_icon(position, icon["texture"]) func gen_new_path(points: Array, texture_path: String): - var points_2d: PoolVector2Array = [] + var points_2d: PoolVector2Array = [] # Create the texture to use from an image file # TODO: We want to be able to cache this data so that if a texture is used # by multiple objects we only need to keep ony copy of it in memory. #22. - # TODO: We want to have two copies of each texture in memory one for 2D + # TODO: We want to have two copies of each texture in memory one for 2D # which does not use srgb to render properly, and one for 3D which forces # srgb to render properly. Issue #23. var texture_file = File.new() @@ -460,31 +522,31 @@ func gen_new_path(points: Array, texture_path: String): # new_path.curve = new_curve new_route.texture_path = texture_path # Save the location of the image for later #path_3d_markers.append(new_path) - + var points_3d := PoolVector3Array() for point in points: points_3d.append(Vector3(point[0], point[1], -point[2])) - + new_route.create_mesh(points_3d) new_route.set_texture(texture) paths.add_child(new_route) - - - - - - - + + + + + + + for point in points: points_2d.append(Vector2(point[0], -point[2])) - - + + # Create a new 2D Path var new_2d_path = path2d_scene.instance() new_2d_path.points = points_2d new_2d_path.texture = texture minimap.add_child(new_2d_path) - + self.currently_active_path = new_route self.currently_active_path_2d = new_2d_path @@ -506,13 +568,13 @@ func gen_new_icon(position: Vector3, texture_path: String): func data_from_renderview(): var icons_data = [] var paths_data = [] - + for icon in $Icons.get_children(): icons_data.append({ "position": [icon.translation.x, icon.translation.y, -icon.translation.z], "texture": icon.texture_path }) - + for path in $Paths.get_children(): #print(path) var points = [] @@ -554,7 +616,7 @@ func gen_adjustment_nodes(): #var curve: Curve3D = path.curve for i in range(route.get_point_count()): var gizmo_position = route.get_point_position(i) - + # Simplistic cull to prevent nodes that are too far away to be # visible from being created. Additional work can be done here # if this is not enough of an optimization in the future. @@ -567,7 +629,7 @@ func gen_adjustment_nodes(): new_gizmo.connect("selected", self, "on_gizmo_selected") new_gizmo.connect("deselected", self, "on_gizmo_deselected") $Gizmos.add_child(new_gizmo) - + for index in range(self.icons.get_child_count()): var icon = self.icons.get_child(index) var new_gizmo = gizmo_scene.instance() @@ -737,14 +799,14 @@ func _on_NewNodeAfter_pressed(): if path.get_point_count() > index+1: var end = path.get_point_position(index+1) midpoint = ((start-end)/2) + end - + path.add_point(midpoint, index+1) path2d.add_point(Vector2(midpoint.x, midpoint.z), index+1) clear_adjustment_nodes() gen_adjustment_nodes() on_gizmo_deselected(self.currently_selected_node) - + func _on_XZSnapToPlayer_pressed(): self.currently_selected_node.translation.x = self.player_position.x self.currently_selected_node.translation.z = -self.player_position.z @@ -773,7 +835,7 @@ func _on_ReversePathDirection_pressed(): func _on_ExitButton_pressed(): - get_tree().quit() + exit_burrito() func _on_Settings_pressed(): diff --git a/Spatial.tscn b/Spatial.tscn index 825a6da9..6a08e7e4 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -193,6 +193,7 @@ __meta__ = { } [node name="MainMenu" type="WindowDialog" parent="Control/Dialogs"] +visible = true margin_left = 48.1808 margin_top = 88.7138 margin_right = 261.181 @@ -603,6 +604,7 @@ disabled = true text = "Reverse Path Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] +visible = true margin_left = 592.0 margin_top = 146.0 margin_right = 981.0 @@ -627,24 +629,24 @@ __meta__ = { [node name="OverrideSizeLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 13.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 27.0 text = "Override Size" [node name="OverrideSize" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_right = 369.0 margin_bottom = 40.0 size_flags_horizontal = 3 [node name="OverrideWidthLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 49.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 63.0 text = "Override Width" [node name="OverrideWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_top = 44.0 margin_right = 369.0 margin_bottom = 68.0 @@ -652,19 +654,18 @@ size_flags_horizontal = 3 [node name="OverrideHeightLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 77.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 91.0 text = "Override Height" [node name="OverrideHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_top = 72.0 margin_right = 369.0 margin_bottom = 96.0 size_flags_horizontal = 3 [node name="HSeparator" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false margin_top = 100.0 margin_right = 112.0 margin_bottom = 104.0 @@ -673,58 +674,72 @@ __meta__ = { } [node name="HSeparator2" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false +margin_left = 116.0 margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 131.0 +margin_right = 369.0 +margin_bottom = 104.0 __meta__ = { "_edit_use_anchors_": false } [node name="AutoLaunchBurritoLinkLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 104.0 +margin_top = 112.0 margin_right = 112.0 -margin_bottom = 135.0 +margin_bottom = 143.0 text = "Auto Launch Burrito Link" [node name="AutoLaunchBurritoLink" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 140.0 +margin_left = 116.0 +margin_top = 108.0 +margin_right = 369.0 +margin_bottom = 148.0 size_flags_horizontal = 3 [node name="WinePathLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 105.0 +margin_top = 157.0 margin_right = 112.0 -margin_bottom = 119.0 +margin_bottom = 171.0 text = "Wine Path" [node name="WinePath" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 124.0 +margin_left = 116.0 +margin_top = 152.0 +margin_right = 369.0 +margin_bottom = 176.0 size_flags_horizontal = 3 [node name="EnvironmentVarsLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 143.0 +margin_top = 223.0 margin_right = 112.0 -margin_bottom = 157.0 +margin_bottom = 237.0 text = "Environment Vars" [node name="EnvironmentVars" type="TextEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 200.0 +margin_left = 116.0 +margin_top = 180.0 +margin_right = 369.0 +margin_bottom = 280.0 rect_min_size = Vector2( 0, 100 ) size_flags_horizontal = 3 +[node name="Spacer" type="Control" parent="Control/Dialogs/SettingsDialog/GridContainer"] +visible = false +margin_top = 284.0 +margin_right = 112.0 +margin_bottom = 284.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LoadLutrisProfile" type="Button" parent="Control/Dialogs/SettingsDialog/GridContainer"] +visible = false +margin_left = 116.0 +margin_top = 284.0 +margin_right = 369.0 +margin_bottom = 304.0 +text = "Load Lutris Profile" + [node name="Border" type="Control" parent="Control"] visible = false anchor_right = 1.0 diff --git a/project.godot b/project.godot index 7cd22479..be568f6c 100644 --- a/project.godot +++ b/project.godot @@ -9,12 +9,12 @@ config_version=4 _global_script_classes=[ { -"base": "", +"base": "Node", "class": "TacoParser", "language": "NativeScript", "path": "res://tacoparser.gdns" }, { -"base": "", +"base": "Node", "class": "X11_FG", "language": "NativeScript", "path": "res://Spatial.gdns" From 49a070c59d8f94897d82e2739a8c39bdba54dbb4 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 5 Dec 2021 22:42:58 -0600 Subject: [PATCH 04/32] removing trailing whitespace from some gdscript files --- Gizmo/PointEdit.gd | 2 +- Route.gd | 4 ++-- Settings.gd | 6 +++--- SettingsDialog.gd | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gizmo/PointEdit.gd b/Gizmo/PointEdit.gd index ea6769ba..93ddfa5c 100644 --- a/Gizmo/PointEdit.gd +++ b/Gizmo/PointEdit.gd @@ -69,5 +69,5 @@ func _process(delta): ) $Plane.scale = new_scale $Pillar.scale = new_scale - + update_point() diff --git a/Route.gd b/Route.gd index f0132264..97aa155b 100644 --- a/Route.gd +++ b/Route.gd @@ -14,7 +14,7 @@ func refresh_mesh(): var tmpMesh = Mesh.new() var i = 0 var last_uv: float = 0.0 - for point_index in range(len(point_list)-1): + for point_index in range(len(point_list)-1): var point:Vector3 = point_list[point_index] var next_point:Vector3 = point_list[point_index+1] @@ -52,7 +52,7 @@ func refresh_mesh(): var st = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN) - for v in vertices.size(): + for v in vertices.size(): st.add_color(color) st.add_uv(UVs[v]) st.add_vertex(vertices[v]) diff --git a/Settings.gd b/Settings.gd index 2d315cbd..a6eadb8f 100644 --- a/Settings.gd +++ b/Settings.gd @@ -17,12 +17,12 @@ func _ready(): var file = File.new() file.open(CONFIG_PATH, file.READ) var text = file.get_as_text() - var datum = JSON.parse(text) + var datum = JSON.parse(text) self._config_data = JSON.parse(text).result if self._config_data == null: self._config_data = {} - + if "override_size_enabled" in self._config_data: self.override_size_enabled = self._config_data["override_size_enabled"] if "override_size_height" in self._config_data: @@ -46,7 +46,7 @@ func save(): "burrito_link_wine_path": burrito_link_wine_path, "burrito_link_env_args": burrito_link_env_args, } - + var file = File.new() file.open(CONFIG_PATH, File.WRITE) file.store_string(JSON.print(self._config_data)) diff --git a/SettingsDialog.gd b/SettingsDialog.gd index b79c0129..c3333e53 100644 --- a/SettingsDialog.gd +++ b/SettingsDialog.gd @@ -29,6 +29,6 @@ func save_settings(new_value=null): Settings.burrito_link_wine_path = wine_path.text var environment_vars: TextEdit = $GridContainer/EnvironmentVars Settings.burrito_link_env_args = environment_vars.text - + Settings.save() From 2be26b53b43bd9e35732abf9e3021ecc234d387a Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 6 Dec 2021 01:27:52 -0600 Subject: [PATCH 05/32] Adding a new setting that allows for a minimum size to be specified --- Settings.gd | 9 +++ SettingsDialog.gd | 34 ++++++---- Spatial.tscn | 170 ++++++++++++++++++++++++++++------------------ 3 files changed, 135 insertions(+), 78 deletions(-) diff --git a/Settings.gd b/Settings.gd index a6eadb8f..663f6e2f 100644 --- a/Settings.gd +++ b/Settings.gd @@ -4,6 +4,9 @@ const CONFIG_PATH = "user://settings.json" var _config_data = {} +var minimum_width: int = 800 +var minimum_height: int = 600 + var override_size_enabled: bool = false; var override_size_height: int = 1080 var override_size_width: int = 1920 @@ -23,6 +26,10 @@ func _ready(): if self._config_data == null: self._config_data = {} + if "minimum_width" in self._config_data: + self.minimum_width = self._config_data["minimum_width"] + if "minimum_height" in self._config_data: + self.minimum_height = self._config_data["minimum_height"] if "override_size_enabled" in self._config_data: self.override_size_enabled = self._config_data["override_size_enabled"] if "override_size_height" in self._config_data: @@ -39,6 +46,8 @@ func _ready(): func save(): _config_data = { + "minimum_width": minimum_width, + "minimum_height": minimum_height, "override_size_enabled": override_size_enabled, "override_size_height": override_size_height, "override_size_width": override_size_width, diff --git a/SettingsDialog.gd b/SettingsDialog.gd index c3333e53..a78b0458 100644 --- a/SettingsDialog.gd +++ b/SettingsDialog.gd @@ -1,33 +1,43 @@ extends WindowDialog func load_settings(): - var override_size: CheckButton = $GridContainer/OverrideSize + var minimum_width: LineEdit = $ScrollContainer/GridContainer/MinimumWidth + minimum_width.text = String(Settings.minimum_width) + var minimum_height: LineEdit = $ScrollContainer/GridContainer/MinimumHeight + minimum_height.text = String(Settings.minimum_height) + + var override_size: CheckButton = $ScrollContainer/GridContainer/OverrideSize override_size.pressed = Settings.override_size_enabled - var override_height: LineEdit = $GridContainer/OverrideHeight + var override_height: LineEdit = $ScrollContainer/GridContainer/OverrideHeight override_height.text = String(Settings.override_size_height) - var override_width: LineEdit = $GridContainer/OverrideWidth + var override_width: LineEdit = $ScrollContainer/GridContainer/OverrideWidth override_width.text = String(Settings.override_size_width) - var autolaunch_burrito_link: CheckButton = $GridContainer/AutoLaunchBurritoLink + var autolaunch_burrito_link: CheckButton = $ScrollContainer/GridContainer/AutoLaunchBurritoLink autolaunch_burrito_link.pressed = Settings.burrito_link_auto_launch_enabled - var wine_path: LineEdit = $GridContainer/WinePath + var wine_path: LineEdit = $ScrollContainer/GridContainer/WinePath wine_path.text = Settings.burrito_link_wine_path - var environment_vars: TextEdit = $GridContainer/EnvironmentVars + var environment_vars: TextEdit = $ScrollContainer/GridContainer/EnvironmentVars environment_vars.text = Settings.burrito_link_env_args func save_settings(new_value=null): - var override_size: CheckButton = $GridContainer/OverrideSize + var minimum_width: LineEdit = $ScrollContainer/GridContainer/MinimumWidth + Settings.minimum_width = int(minimum_width.text) + var minimum_height: LineEdit = $ScrollContainer/GridContainer/MinimumHeight + Settings.minimum_height = int(minimum_height.text) + + var override_size: CheckButton = $ScrollContainer/GridContainer/OverrideSize Settings.override_size_enabled = override_size.pressed - var override_height: LineEdit = $GridContainer/OverrideHeight + var override_height: LineEdit = $ScrollContainer/GridContainer/OverrideHeight Settings.override_size_height = int(override_height.text) - var override_width: LineEdit = $GridContainer/OverrideWidth + var override_width: LineEdit = $ScrollContainer/GridContainer/OverrideWidth Settings.override_size_width = int(override_width.text) - var autolaunch_burrito_link: CheckButton = $GridContainer/AutoLaunchBurritoLink + var autolaunch_burrito_link: CheckButton = $ScrollContainer/GridContainer/AutoLaunchBurritoLink Settings.burrito_link_auto_launch_enabled = autolaunch_burrito_link.pressed - var wine_path: LineEdit = $GridContainer/WinePath + var wine_path: LineEdit = $ScrollContainer/GridContainer/WinePath Settings.burrito_link_wine_path = wine_path.text - var environment_vars: TextEdit = $GridContainer/EnvironmentVars + var environment_vars: TextEdit = $ScrollContainer/GridContainer/EnvironmentVars Settings.burrito_link_env_args = environment_vars.text Settings.save() diff --git a/Spatial.tscn b/Spatial.tscn index 6a08e7e4..d54c654f 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -605,125 +605,161 @@ text = "Reverse Path Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] visible = true -margin_left = 592.0 -margin_top = 146.0 -margin_right = 981.0 -margin_bottom = 575.0 +margin_left = 616.368 +margin_top = 40.0536 +margin_right = 1005.37 +margin_bottom = 469.054 window_title = "Settings" +resizable = true script = ExtResource( 12 ) __meta__ = { "_edit_use_anchors_": false } -[node name="GridContainer" type="GridContainer" parent="Control/Dialogs/SettingsDialog"] +[node name="ScrollContainer" type="ScrollContainer" parent="Control/Dialogs/SettingsDialog"] anchor_right = 1.0 anchor_bottom = 1.0 -margin_left = 10.0 -margin_top = 10.0 -margin_right = -10.0 -margin_bottom = -10.0 +margin_left = 5.0 +margin_top = 5.0 +margin_bottom = -5.0 +scroll_horizontal_enabled = false +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="GridContainer" type="GridContainer" parent="Control/Dialogs/SettingsDialog/ScrollContainer"] +margin_right = 384.0 +margin_bottom = 419.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 columns = 2 __meta__ = { "_edit_use_anchors_": false } -[node name="OverrideSizeLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 13.0 +[node name="MinimumWidthLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 5.0 +margin_right = 112.0 +margin_bottom = 19.0 +text = "Minimum Width" + +[node name="MinimumWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_left = 116.0 +margin_right = 384.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 + +[node name="MinimumHeightLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 33.0 +margin_right = 112.0 +margin_bottom = 47.0 +text = "Minimum Height" + +[node name="MinimumHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_left = 116.0 +margin_top = 28.0 +margin_right = 384.0 +margin_bottom = 52.0 +size_flags_horizontal = 3 + +[node name="OverrideSizeLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 69.0 margin_right = 112.0 -margin_bottom = 27.0 +margin_bottom = 83.0 text = "Override Size" -[node name="OverrideSize" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="OverrideSize" type="CheckButton" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_right = 369.0 -margin_bottom = 40.0 +margin_top = 56.0 +margin_right = 384.0 +margin_bottom = 96.0 size_flags_horizontal = 3 -[node name="OverrideWidthLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 49.0 +[node name="OverrideWidthLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 105.0 margin_right = 112.0 -margin_bottom = 63.0 +margin_bottom = 119.0 text = "Override Width" -[node name="OverrideWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="OverrideWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 44.0 -margin_right = 369.0 -margin_bottom = 68.0 +margin_top = 100.0 +margin_right = 384.0 +margin_bottom = 124.0 size_flags_horizontal = 3 -[node name="OverrideHeightLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 77.0 +[node name="OverrideHeightLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 133.0 margin_right = 112.0 -margin_bottom = 91.0 +margin_bottom = 147.0 text = "Override Height" -[node name="OverrideHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="OverrideHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 72.0 -margin_right = 369.0 -margin_bottom = 96.0 +margin_top = 128.0 +margin_right = 384.0 +margin_bottom = 152.0 size_flags_horizontal = 3 -[node name="HSeparator" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 100.0 +[node name="HSeparator" type="HSeparator" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 156.0 margin_right = 112.0 -margin_bottom = 104.0 +margin_bottom = 160.0 __meta__ = { "_edit_use_anchors_": false } -[node name="HSeparator2" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="HSeparator2" type="HSeparator" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 100.0 -margin_right = 369.0 -margin_bottom = 104.0 +margin_top = 156.0 +margin_right = 384.0 +margin_bottom = 160.0 __meta__ = { "_edit_use_anchors_": false } -[node name="AutoLaunchBurritoLinkLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 112.0 +[node name="AutoLaunchBurritoLinkLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 168.0 margin_right = 112.0 -margin_bottom = 143.0 +margin_bottom = 199.0 text = "Auto Launch Burrito Link" -[node name="AutoLaunchBurritoLink" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="AutoLaunchBurritoLink" type="CheckButton" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 108.0 -margin_right = 369.0 -margin_bottom = 148.0 +margin_top = 164.0 +margin_right = 384.0 +margin_bottom = 204.0 size_flags_horizontal = 3 -[node name="WinePathLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 157.0 +[node name="WinePathLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 213.0 margin_right = 112.0 -margin_bottom = 171.0 +margin_bottom = 227.0 text = "Wine Path" -[node name="WinePath" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="WinePath" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 152.0 -margin_right = 369.0 -margin_bottom = 176.0 +margin_top = 208.0 +margin_right = 384.0 +margin_bottom = 232.0 size_flags_horizontal = 3 -[node name="EnvironmentVarsLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_top = 223.0 +[node name="EnvironmentVarsLabel" type="Label" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] +margin_top = 279.0 margin_right = 112.0 -margin_bottom = 237.0 +margin_bottom = 293.0 text = "Environment Vars" -[node name="EnvironmentVars" type="TextEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="EnvironmentVars" type="TextEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 -margin_top = 180.0 -margin_right = 369.0 -margin_bottom = 280.0 +margin_top = 236.0 +margin_right = 384.0 +margin_bottom = 336.0 rect_min_size = Vector2( 0, 100 ) size_flags_horizontal = 3 -[node name="Spacer" type="Control" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="Spacer" type="Control" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] visible = false margin_top = 284.0 margin_right = 112.0 @@ -732,11 +768,11 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="LoadLutrisProfile" type="Button" parent="Control/Dialogs/SettingsDialog/GridContainer"] +[node name="LoadLutrisProfile" type="Button" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] visible = false margin_left = 116.0 margin_top = 284.0 -margin_right = 369.0 +margin_right = 384.0 margin_bottom = 304.0 text = "Load Lutris Profile" @@ -863,9 +899,11 @@ material/0 = SubResource( 4 ) [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActivePath" to="." method="_on_SetActivePath_pressed"] [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReversePathDirection" to="." method="_on_ReversePathDirection_pressed"] [connection signal="hide" from="Control/Dialogs/SettingsDialog" to="." method="_on_NodeEditorDialog_hide"] -[connection signal="pressed" from="Control/Dialogs/SettingsDialog/GridContainer/OverrideSize" to="Control/Dialogs/SettingsDialog" method="save_settings"] -[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/GridContainer/OverrideWidth" to="Control/Dialogs/SettingsDialog" method="save_settings"] -[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/GridContainer/OverrideHeight" to="Control/Dialogs/SettingsDialog" method="save_settings"] -[connection signal="pressed" from="Control/Dialogs/SettingsDialog/GridContainer/AutoLaunchBurritoLink" to="Control/Dialogs/SettingsDialog" method="save_settings"] -[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/GridContainer/WinePath" to="Control/Dialogs/SettingsDialog" method="save_settings"] -[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/GridContainer/EnvironmentVars" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/MinimumWidth" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/MinimumHeight" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="pressed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/OverrideSize" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/OverrideWidth" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/OverrideHeight" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="pressed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/AutoLaunchBurritoLink" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/WinePath" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/EnvironmentVars" to="Control/Dialogs/SettingsDialog" method="save_settings"] From c1d7cc05f951763d52cf4eec7ff1f0c54718ee85 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 6 Dec 2021 01:42:15 -0600 Subject: [PATCH 06/32] forcing minimum size value from settings when resizing window --- Spatial.gd | 6 ++++++ Spatial.tscn | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Spatial.gd b/Spatial.gd index 1de7f13c..7be06855 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -293,6 +293,12 @@ func decode_context_packet(spb: StreamPeerBuffer): var size_tuple = x11_fg.get_window_geometry(x11_window_id_gw2) size.x = size_tuple[0] size.y = size_tuple[1] + + if size.x < Settings.minimum_width: + size.x = Settings.minimum_width + if size.y < Settings.minimum_height: + size.y = Settings.minimum_height + OS.window_size = size var identity_length: int = spb.get_32() var identity_str = spb.get_utf8_string(identity_length) diff --git a/Spatial.tscn b/Spatial.tscn index d54c654f..825ab9a8 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -193,14 +193,14 @@ __meta__ = { } [node name="MainMenu" type="WindowDialog" parent="Control/Dialogs"] -visible = true -margin_left = 48.1808 -margin_top = 88.7138 -margin_right = 261.181 -margin_bottom = 714.714 +margin_left = 39.0 +margin_top = 71.0 +margin_right = 252.0 +margin_bottom = 583.0 window_title = "Main Menu" resizable = true __meta__ = { +"_edit_group_": true, "_edit_use_anchors_": false } @@ -604,15 +604,15 @@ disabled = true text = "Reverse Path Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] -visible = true -margin_left = 616.368 -margin_top = 40.0536 -margin_right = 1005.37 -margin_bottom = 469.054 +margin_left = 319.718 +margin_top = 105.74 +margin_right = 708.72 +margin_bottom = 534.741 window_title = "Settings" resizable = true script = ExtResource( 12 ) __meta__ = { +"_edit_group_": true, "_edit_use_anchors_": false } @@ -628,7 +628,7 @@ __meta__ = { } [node name="GridContainer" type="GridContainer" parent="Control/Dialogs/SettingsDialog/ScrollContainer"] -margin_right = 384.0 +margin_right = 384.002 margin_bottom = 419.0 size_flags_horizontal = 3 size_flags_vertical = 3 From 72113184321c2082cdbdfff626ab6a6ddba6d52c Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 6 Dec 2021 01:50:35 -0600 Subject: [PATCH 07/32] making the size settings more intuitive to understand --- Spatial.gd | 16 ++++++++++------ Spatial.tscn | 10 +++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Spatial.gd b/Spatial.gd index 7be06855..fd3702c9 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -55,7 +55,11 @@ func _ready(): x11_window_id_burrito = OS.get_native_handle(OS.WINDOW_HANDLE) OS.window_maximized = false # Start off with a small size before GW2 client is up - OS.window_size = Vector2(800, 600) + + if Settings.override_size_enabled: + OS.window_size = Vector2(Settings.override_size_width, Settings.override_size_height) + else: + OS.window_size = Vector2(Settings.minimum_width, Settings.minimum_height) # Postion at top left corner OS.set_window_position(Vector2(0,0)) set_minimal_mouse_block() @@ -285,7 +289,7 @@ func decode_context_packet(spb: StreamPeerBuffer): if !is_transient: is_transient = x11_fg.set_transient_for(x11_window_id_burrito, x11_window_id_gw2) - var size = Vector2(800, 600) + var size = Vector2(Settings.minimum_width, Settings.minimum_height) if Settings.override_size_enabled: size.x = Settings.override_size_width size.y = Settings.override_size_height @@ -294,10 +298,10 @@ func decode_context_packet(spb: StreamPeerBuffer): size.x = size_tuple[0] size.y = size_tuple[1] - if size.x < Settings.minimum_width: - size.x = Settings.minimum_width - if size.y < Settings.minimum_height: - size.y = Settings.minimum_height + if size.x < Settings.minimum_width: + size.x = Settings.minimum_width + if size.y < Settings.minimum_height: + size.y = Settings.minimum_height OS.window_size = size var identity_length: int = spb.get_32() diff --git a/Spatial.tscn b/Spatial.tscn index 825ab9a8..5ea7f43e 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -604,6 +604,7 @@ disabled = true text = "Reverse Path Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] +visible = true margin_left = 319.718 margin_top = 105.74 margin_right = 708.72 @@ -612,7 +613,6 @@ window_title = "Settings" resizable = true script = ExtResource( 12 ) __meta__ = { -"_edit_group_": true, "_edit_use_anchors_": false } @@ -629,7 +629,7 @@ __meta__ = { [node name="GridContainer" type="GridContainer" parent="Control/Dialogs/SettingsDialog/ScrollContainer"] margin_right = 384.002 -margin_bottom = 419.0 +margin_bottom = 419.001 size_flags_horizontal = 3 size_flags_vertical = 3 columns = 2 @@ -666,7 +666,7 @@ size_flags_horizontal = 3 margin_top = 69.0 margin_right = 112.0 margin_bottom = 83.0 -text = "Override Size" +text = "Use Fixed Size" [node name="OverrideSize" type="CheckButton" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 @@ -679,7 +679,7 @@ size_flags_horizontal = 3 margin_top = 105.0 margin_right = 112.0 margin_bottom = 119.0 -text = "Override Width" +text = "Fixed Width" [node name="OverrideWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 @@ -692,7 +692,7 @@ size_flags_horizontal = 3 margin_top = 133.0 margin_right = 112.0 margin_bottom = 147.0 -text = "Override Height" +text = "Fixed Height" [node name="OverrideHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] margin_left = 116.0 From fc2513dce52ec48e557b1d2a415e8fd06a7de2cd Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Fri, 10 Dec 2021 00:18:49 -0600 Subject: [PATCH 08/32] Autolaunch Burrito Link (#48) * cleaning up the mumble link code * adding a timeout for burrito link to allow it to exit if it is orphaned * adding a method to allow for burrito link to be launched automatically * removing trailing whitespace from some gdscript files --- Gizmo/PointEdit.gd | 2 +- Route.gd | 4 +- Settings.gd | 6 +- SettingsDialog.gd | 2 +- Spatial.gd | 152 ++++++++++----- Spatial.tscn | 77 ++++---- burrito_link/gw2mumbleudp.c | 356 +++++++++++++++++++++--------------- project.godot | 4 +- 8 files changed, 372 insertions(+), 231 deletions(-) diff --git a/Gizmo/PointEdit.gd b/Gizmo/PointEdit.gd index ea6769ba..93ddfa5c 100644 --- a/Gizmo/PointEdit.gd +++ b/Gizmo/PointEdit.gd @@ -69,5 +69,5 @@ func _process(delta): ) $Plane.scale = new_scale $Pillar.scale = new_scale - + update_point() diff --git a/Route.gd b/Route.gd index f0132264..97aa155b 100644 --- a/Route.gd +++ b/Route.gd @@ -14,7 +14,7 @@ func refresh_mesh(): var tmpMesh = Mesh.new() var i = 0 var last_uv: float = 0.0 - for point_index in range(len(point_list)-1): + for point_index in range(len(point_list)-1): var point:Vector3 = point_list[point_index] var next_point:Vector3 = point_list[point_index+1] @@ -52,7 +52,7 @@ func refresh_mesh(): var st = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN) - for v in vertices.size(): + for v in vertices.size(): st.add_color(color) st.add_uv(UVs[v]) st.add_vertex(vertices[v]) diff --git a/Settings.gd b/Settings.gd index 2d315cbd..a6eadb8f 100644 --- a/Settings.gd +++ b/Settings.gd @@ -17,12 +17,12 @@ func _ready(): var file = File.new() file.open(CONFIG_PATH, file.READ) var text = file.get_as_text() - var datum = JSON.parse(text) + var datum = JSON.parse(text) self._config_data = JSON.parse(text).result if self._config_data == null: self._config_data = {} - + if "override_size_enabled" in self._config_data: self.override_size_enabled = self._config_data["override_size_enabled"] if "override_size_height" in self._config_data: @@ -46,7 +46,7 @@ func save(): "burrito_link_wine_path": burrito_link_wine_path, "burrito_link_env_args": burrito_link_env_args, } - + var file = File.new() file.open(CONFIG_PATH, File.WRITE) file.store_string(JSON.print(self._config_data)) diff --git a/SettingsDialog.gd b/SettingsDialog.gd index b79c0129..c3333e53 100644 --- a/SettingsDialog.gd +++ b/SettingsDialog.gd @@ -29,6 +29,6 @@ func save_settings(new_value=null): Settings.burrito_link_wine_path = wine_path.text var environment_vars: TextEdit = $GridContainer/EnvironmentVars Settings.burrito_link_env_args = environment_vars.text - + Settings.save() diff --git a/Spatial.gd b/Spatial.gd index 738b4d67..1de7f13c 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -27,7 +27,7 @@ var map_was_open = false var player_position := Vector3(0,0,0) # Player Position as accurate to Godot (z value sign is flipped) -var correct_player_position := Vector3(0,0,0) +var correct_player_position := Vector3(0,0,0) var compass_height: int = 0; var compass_width: int = 0; @@ -35,7 +35,7 @@ var compass_width: int = 0; # A temporary setting able to be configured by the user. It is used to allow # for faster trail mesh generation. The higher the value the fewer samples are -# taken for the MeshCSG leading to an overall lower number of polygons. +# taken for the MeshCSG leading to an overall lower number of polygons. var path_resolution = 1 # Variables that store opposit corners of the compass @@ -61,14 +61,67 @@ func _ready(): set_minimal_mouse_block() server.listen(4242) + if (Settings.burrito_link_auto_launch_enabled): + launch_burrito_link() + + +################################################################################ +# show_error +# +# This function prints a user error out. Currently it prints to stdout but may +# one day be shown to the user. +################################################################################ +func show_user_error(error_string: String): + print(error_string) + + +# The process id of burrito link if it is launched automatically by burrito +var burrito_link_process_id = 0 + +################################################################################ +# launch_burrito_link +# +# This function launches the burrito link binary using the values for it that +# are saved in "settings". +################################################################################ +func launch_burrito_link(): + for env_arg in Settings.burrito_link_env_args.split("\n"): + env_arg = env_arg.trim_prefix("export ") + var key_values = env_arg.split('=', true, 1) + + if len(key_values) != 2: + show_user_error("Invalid burrito_link environment arg: " + env_arg) + return + + var key = key_values[0] + var value = key_values[1].trim_prefix('"').trim_suffix('"') + OS.set_environment(key, value) + + # Launch burrito link with a 2 hour timeout + # If burrito crashes then burrito_link will automatically exit at the timeout. + # If burrito does not crash and the timeout expires then burrito will relaunch burrito_link automatically + burrito_link_process_id = OS.execute(Settings.burrito_link_wine_path, ["burrito_link/burrito_link.exe", "--timeout", "7200"], false) + +func close_burrito_link(): + if (burrito_link_process_id != 0): + OS.kill(burrito_link_process_id) + burrito_link_process_id = 0 + + +func exit_burrito(): + if Settings.burrito_link_auto_launch_enabled: + close_burrito_link() + get_tree().quit() + + func set_minimal_mouse_block(): var top_corner := Vector2(287, 0) var bottom_corner := Vector2(314, 32) - + if self.edit_panel_open: bottom_corner.y = 49 bottom_corner.x = 314+377 - + var clickthrough: PoolVector2Array = [ Vector2(top_corner.x ,top_corner.y), Vector2(bottom_corner.x, top_corner.y), @@ -84,7 +137,7 @@ func set_maximal_mouse_block(): # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): - #OS.window_position = Vector2(1920, 0) # TODO: This does not seem to work + #OS.window_position = Vector2(1920, 0) # TODO: This does not seem to work #OS.set_window_position(Vector2(1920,0)) #print(OS.window_position) server.poll() # Important @@ -105,7 +158,9 @@ func _process(delta): if packet_type == 1: decode_frame_packet(spb) elif packet_type == 2: - decode_context_packet(spb) + decode_context_packet(spb) + elif packet_type == 3: + decode_timeout_packet(spb) return @@ -116,14 +171,14 @@ func decode_frame_packet(spb: StreamPeerBuffer): spb.get_float(), spb.get_float() ) - + # Extract the rotation of the camera in the form of a normal vector var camera_facing = Vector3( spb.get_float(), spb.get_float(), spb.get_float() ) - + # Extract the position of the player's foot self.player_position = Vector3( spb.get_float(), @@ -131,10 +186,10 @@ func decode_frame_packet(spb: StreamPeerBuffer): spb.get_float() ) self.correct_player_position = Vector3(player_position.x, player_position.y, -player_position.z) - + if $Control/Position.visible: $Control/Position.text = "X " + str(player_position.x) + " Y " + str(player_position.y) + " Z " + str(-player_position.z) - + var map_offset = Vector2( spb.get_float(), spb.get_float() @@ -144,7 +199,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): map_scale = 0.000001 var map_rotation: float = spb.get_float() var ui_flags: int = spb.get_32() - + map_is_open = (ui_flags & 0x01) == 0x01; compass_is_top_right = (ui_flags & 0x02) == 0x02; var compass_rotation_is_enabled: bool = (ui_flags & 0x04) == 0x04; @@ -167,7 +222,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): $CameraMount.translation.x = camera_position.x $CameraMount.translation.y = camera_position.y $CameraMount.translation.z = -camera_position.z - + # Orent the camera in the same rotation as it is facing in game $CameraMount/Camera.rotation.x = asin(camera_facing.y) $CameraMount.rotation.y = -atan2(camera_facing.x, camera_facing.z) @@ -183,7 +238,7 @@ func decode_frame_packet(spb: StreamPeerBuffer): var map_size = get_viewport().size var map_corner = Vector2(0, 0) - + if (!map_is_open): map_size = Vector2(compass_width, compass_height) if !compass_is_top_right: @@ -203,16 +258,16 @@ func decode_frame_packet(spb: StreamPeerBuffer): var x = (cosTheta * (player_map_position.x - pivot.x) - sinTheta * (player_map_position.y - pivot.y) + pivot.x); var y = (sinTheta * (player_map_position.x - pivot.x) + cosTheta * (player_map_position.y - pivot.y) + pivot.y); - + delta_position = player_map_position - Vector2(x, y); - + #print(map_rotation) $Control/MiniMap.rotation = map_rotation else: $Control/MiniMap.rotation = 0 - + var map_midpoint = map_size/2 + map_corner; - + $Control/MiniMap.scale=Vector2(map_object_scaling, map_object_scaling) var map_translation = map_offset $Control/MiniMap.position = (map_translation / map_scale) + map_midpoint - player_map_position + delta_position @@ -242,7 +297,7 @@ func decode_context_packet(spb: StreamPeerBuffer): var identity_length: int = spb.get_32() var identity_str = spb.get_utf8_string(identity_length) var identity = JSON.parse(identity_str).result - + # FOV Calculations # The minimum value on the FOV slider gives a float value in this field of 0.436 # The maximum value on the FOV slider gives a float value in this field of 1.222 @@ -255,7 +310,7 @@ func decode_context_packet(spb: StreamPeerBuffer): if self.map_id != old_map_id: print("New Map") - + print("Saving Old Map") self.markerdata[str(old_map_id)] = data_from_renderview() print("Loading New Map") @@ -272,6 +327,13 @@ func decode_context_packet(spb: StreamPeerBuffer): reset_minimap_masks() +func decode_timeout_packet(spb: StreamPeerBuffer): + if Settings.burrito_link_auto_launch_enabled: + print("Link Timeout Reached, should restart link if started by burrito automatically") + close_burrito_link() + launch_burrito_link() + + func reset_minimap_masks(): var viewport_size = get_viewport().size compass_corner1 = Vector2(0, 0) @@ -282,7 +344,7 @@ func reset_minimap_masks(): elif !map_is_open && compass_is_top_right: compass_corner1 = viewport_size - Vector2(compass_width, compass_height) compass_corner2 = compass_corner1 + Vector2(compass_width, compass_height) - + for minimap_path in $Control/MiniMap.get_children(): minimap_path.material.set_shader_param("minimap_corner", compass_corner1) minimap_path.material.set_shader_param("minimap_corner2", compass_corner2) @@ -291,7 +353,7 @@ var markerdata = {} var marker_file_path = "" func load_taco_markers(marker_json_file): self.marker_file_path = marker_json_file - + if is_xml_file(marker_json_file): print("Loading XML file from path ", marker_json_file) var parsed_taco_tuple = taco_parser.parse_taco_xml(marker_json_file) @@ -306,7 +368,7 @@ func load_taco_markers(marker_json_file): file.open(marker_json_file, file.READ) var text = file.get_as_text() self.markerdata = JSON.parse(text).result - + relative_textures_to_absolute_textures(marker_file_path.get_base_dir()) gen_map_markers() @@ -396,8 +458,8 @@ func _unhandled_input(event): if is_instance_valid(self.last_hover) and self.last_hover.has_method("unhover"): self.last_hover.unhover() self.last_hover = null - - + + ################################################################################ # ################################################################################ @@ -427,13 +489,13 @@ func gen_map_markers(): gen_new_icon(position, icon["texture"]) func gen_new_path(points: Array, texture_path: String): - var points_2d: PoolVector2Array = [] + var points_2d: PoolVector2Array = [] # Create the texture to use from an image file # TODO: We want to be able to cache this data so that if a texture is used # by multiple objects we only need to keep ony copy of it in memory. #22. - # TODO: We want to have two copies of each texture in memory one for 2D + # TODO: We want to have two copies of each texture in memory one for 2D # which does not use srgb to render properly, and one for 3D which forces # srgb to render properly. Issue #23. var texture_file = File.new() @@ -460,31 +522,31 @@ func gen_new_path(points: Array, texture_path: String): # new_path.curve = new_curve new_route.texture_path = texture_path # Save the location of the image for later #path_3d_markers.append(new_path) - + var points_3d := PoolVector3Array() for point in points: points_3d.append(Vector3(point[0], point[1], -point[2])) - + new_route.create_mesh(points_3d) new_route.set_texture(texture) paths.add_child(new_route) - - - - - - - + + + + + + + for point in points: points_2d.append(Vector2(point[0], -point[2])) - - + + # Create a new 2D Path var new_2d_path = path2d_scene.instance() new_2d_path.points = points_2d new_2d_path.texture = texture minimap.add_child(new_2d_path) - + self.currently_active_path = new_route self.currently_active_path_2d = new_2d_path @@ -506,13 +568,13 @@ func gen_new_icon(position: Vector3, texture_path: String): func data_from_renderview(): var icons_data = [] var paths_data = [] - + for icon in $Icons.get_children(): icons_data.append({ "position": [icon.translation.x, icon.translation.y, -icon.translation.z], "texture": icon.texture_path }) - + for path in $Paths.get_children(): #print(path) var points = [] @@ -554,7 +616,7 @@ func gen_adjustment_nodes(): #var curve: Curve3D = path.curve for i in range(route.get_point_count()): var gizmo_position = route.get_point_position(i) - + # Simplistic cull to prevent nodes that are too far away to be # visible from being created. Additional work can be done here # if this is not enough of an optimization in the future. @@ -567,7 +629,7 @@ func gen_adjustment_nodes(): new_gizmo.connect("selected", self, "on_gizmo_selected") new_gizmo.connect("deselected", self, "on_gizmo_deselected") $Gizmos.add_child(new_gizmo) - + for index in range(self.icons.get_child_count()): var icon = self.icons.get_child(index) var new_gizmo = gizmo_scene.instance() @@ -737,14 +799,14 @@ func _on_NewNodeAfter_pressed(): if path.get_point_count() > index+1: var end = path.get_point_position(index+1) midpoint = ((start-end)/2) + end - + path.add_point(midpoint, index+1) path2d.add_point(Vector2(midpoint.x, midpoint.z), index+1) clear_adjustment_nodes() gen_adjustment_nodes() on_gizmo_deselected(self.currently_selected_node) - + func _on_XZSnapToPlayer_pressed(): self.currently_selected_node.translation.x = self.player_position.x self.currently_selected_node.translation.z = -self.player_position.z @@ -773,7 +835,7 @@ func _on_ReversePathDirection_pressed(): func _on_ExitButton_pressed(): - get_tree().quit() + exit_burrito() func _on_Settings_pressed(): diff --git a/Spatial.tscn b/Spatial.tscn index 825a6da9..6a08e7e4 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -193,6 +193,7 @@ __meta__ = { } [node name="MainMenu" type="WindowDialog" parent="Control/Dialogs"] +visible = true margin_left = 48.1808 margin_top = 88.7138 margin_right = 261.181 @@ -603,6 +604,7 @@ disabled = true text = "Reverse Path Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] +visible = true margin_left = 592.0 margin_top = 146.0 margin_right = 981.0 @@ -627,24 +629,24 @@ __meta__ = { [node name="OverrideSizeLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 13.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 27.0 text = "Override Size" [node name="OverrideSize" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_right = 369.0 margin_bottom = 40.0 size_flags_horizontal = 3 [node name="OverrideWidthLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 49.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 63.0 text = "Override Width" [node name="OverrideWidth" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_top = 44.0 margin_right = 369.0 margin_bottom = 68.0 @@ -652,19 +654,18 @@ size_flags_horizontal = 3 [node name="OverrideHeightLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] margin_top = 77.0 -margin_right = 102.0 +margin_right = 112.0 margin_bottom = 91.0 text = "Override Height" [node name="OverrideHeight" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -margin_left = 106.0 +margin_left = 116.0 margin_top = 72.0 margin_right = 369.0 margin_bottom = 96.0 size_flags_horizontal = 3 [node name="HSeparator" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false margin_top = 100.0 margin_right = 112.0 margin_bottom = 104.0 @@ -673,58 +674,72 @@ __meta__ = { } [node name="HSeparator2" type="HSeparator" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false +margin_left = 116.0 margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 131.0 +margin_right = 369.0 +margin_bottom = 104.0 __meta__ = { "_edit_use_anchors_": false } [node name="AutoLaunchBurritoLinkLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 104.0 +margin_top = 112.0 margin_right = 112.0 -margin_bottom = 135.0 +margin_bottom = 143.0 text = "Auto Launch Burrito Link" [node name="AutoLaunchBurritoLink" type="CheckButton" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 140.0 +margin_left = 116.0 +margin_top = 108.0 +margin_right = 369.0 +margin_bottom = 148.0 size_flags_horizontal = 3 [node name="WinePathLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 105.0 +margin_top = 157.0 margin_right = 112.0 -margin_bottom = 119.0 +margin_bottom = 171.0 text = "Wine Path" [node name="WinePath" type="LineEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 124.0 +margin_left = 116.0 +margin_top = 152.0 +margin_right = 369.0 +margin_bottom = 176.0 size_flags_horizontal = 3 [node name="EnvironmentVarsLabel" type="Label" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 143.0 +margin_top = 223.0 margin_right = 112.0 -margin_bottom = 157.0 +margin_bottom = 237.0 text = "Environment Vars" [node name="EnvironmentVars" type="TextEdit" parent="Control/Dialogs/SettingsDialog/GridContainer"] -visible = false -margin_top = 100.0 -margin_right = 182.0 -margin_bottom = 200.0 +margin_left = 116.0 +margin_top = 180.0 +margin_right = 369.0 +margin_bottom = 280.0 rect_min_size = Vector2( 0, 100 ) size_flags_horizontal = 3 +[node name="Spacer" type="Control" parent="Control/Dialogs/SettingsDialog/GridContainer"] +visible = false +margin_top = 284.0 +margin_right = 112.0 +margin_bottom = 284.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LoadLutrisProfile" type="Button" parent="Control/Dialogs/SettingsDialog/GridContainer"] +visible = false +margin_left = 116.0 +margin_top = 284.0 +margin_right = 369.0 +margin_bottom = 304.0 +text = "Load Lutris Profile" + [node name="Border" type="Control" parent="Control"] visible = false anchor_right = 1.0 diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index 1181cfd1..e2fd78b0 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -2,30 +2,35 @@ #include #include #include +#include + +// Enumerations of the different packet types that can be sent +#define PACKET_FRAME 1 +#define PACKET_METADATA 2 +#define PACKET_LINK_TIMEOUT 3 // Do a rolling average on the player position because that seems to be // Roughly what the camera position is doing and doing this will remove // some weird jitter I hope -struct rolling_average_5 -{ +struct rolling_average_5 { UINT8 index; float points[5]; }; -float get_rolling_average(struct rolling_average_5 *points) -{ + + +float get_rolling_average(struct rolling_average_5 *points) { float sum = 0; - for (int i = 0; i < 5; i++) - { + for (int i = 0; i < 5; i++) { sum += points->points[i]; } return sum / 5.0; } -void replace_point_in_rolling_average(struct rolling_average_5 *points, float newvalue) -{ + + +void replace_point_in_rolling_average(struct rolling_average_5 *points, float newvalue) { points->points[points->index] = newvalue; points->index = points->index + 1; - if (points->index > 4) - { + if (points->index > 4) { points->index = 0; } } @@ -35,43 +40,115 @@ struct rolling_average_5 playerz_avg; float fAvatarAveragePosition[3]; +//////////////////////////////////////////////////////////////////////////////// +// LinkedMem struct +// +// This struct represents the Mumble Link shared memory datum that Guild Wars 2 +// uses to communicate live player and camera data, as well as some other +// bits of information that are useful for tools like burrito. +// // https://wiki.guildwars2.com/wiki/API:MumbleLink -struct LinkedMem -{ +// https://www.mumble.info/documentation/developer/positional-audio/link-plugin/ +//////////////////////////////////////////////////////////////////////////////// +struct LinkedMem { UINT32 uiVersion; + + // The current update tick DWORD uiTick; - float fAvatarPosition[3]; // The XYZ location of the player + + // The XYZ location of the player + float fAvatarPosition[3]; + + // A 3D unit vector representing the forward direction of the player character float fAvatarFront[3]; + + // A 3D unit vector representing the up direction of the player character float fAvatarTop[3]; - wchar_t name[256]; // The string "Guild Wars 2" [Ignored] - float fCameraPosition[3]; // The XYZ position of the camera - float fCameraFront[3]; // A unit vector extending out the front of the camera - float fCameraTop[3]; // A perpendicular vector to fCameraFront, used for calculating roll [Ignored] - wchar_t identity[256]; // A json string containing json data - UINT32 context_len; // A value that is always 48 [Ignored] - unsigned char context[256]; // See MumbleContext struct - wchar_t description[2048]; // Empty [Ignored] + + // The string "Guild Wars 2" + wchar_t name[256]; + + // The XYZ Position of the camera + float fCameraPosition[3]; + + // A 3D unit vector representing the forward direction of the camera + float fCameraFront[3]; + + // A 3D unit vector representing the up direction of the camera + float fCameraTop[3]; + + // A json string containing json data. See https://wiki.guildwars2.com/wiki/API:MumbleLink#identity + wchar_t identity[256]; + + // A value that is always 48 + UINT32 context_len; + + // A binary chunk containing another struct. See the MumbleContext struct below + unsigned char context[256]; + + // An Empty Array, this field is not used by guild wars 2 + wchar_t description[2048]; }; -struct MumbleContext -{ - unsigned char serverAddress[28]; // contains sockaddr_in or sockaddr_in6 // IGNORED + +//////////////////////////////////////////////////////////////////////////////// +// MumbleContext struct +// +// This struct represents the LinkedMem.context datum that is passed in +// LinkedMem. It is a struct that is entirely specific to Guild Wars 2 which +// is why it is seperated out from the more mumble-generic LinkedMem struct. +// +// https://wiki.guildwars2.com/wiki/API:MumbleLink#context +//////////////////////////////////////////////////////////////////////////////// +struct MumbleContext { + // The current address of the guild wars 2 server the player is connected to + // can be a ipv4 `sockaddr_in` or a ipv6 `sockaddr_in6` + unsigned char serverAddress[28]; + + // The Guild Wars 2 id for the map the player is currently in UINT32 mapId; + UINT32 mapType; UINT32 shardId; UINT32 instance; UINT32 buildId; - // Additional data beyond the 48 bytes Mumble uses for identification - UINT32 uiState; // Bitmask: Bit 1 = IsMapOpen, Bit 2 = IsCompassTopRight, Bit 3 = DoesCompassHaveRotationEnabled, Bit 4 = Game has focus, Bit 5 = Is in Competitive game mode, Bit 6 = Textbox has focus, Bit 7 = Is in Combat - UINT16 compassWidth; // pixels - UINT16 compassHeight; // pixels - float compassRotation; // radians - float playerX; // continentCoords - float playerY; // continentCoords - float mapCenterX; // continentCoords - float mapCenterY; // continentCoords + + // A bitmask of various boolean element of the UI state + // Bit 1 = IsMapOpen + // Bit 2 = IsCompassTopRight + // Bit 3 = DoesCompassHaveRotationEnabled + // Bit 4 = Game has focus + // Bit 5 = Is in Competitive game mode + // Bit 6 = Textbox has focus + // Bit 7 = Is in Combat + UINT32 uiState; + + // The width of the minimap in pixels + UINT16 compassWidth; + + // The height of the minimap in pixels + UINT16 compassHeight; + + // The rotation of the minimap contents in radians + float compassRotation; + + // The X location of the player in continentCoords + float playerX; + // The Y location of the player in continentCoords + float playerY; + + // The center X of the current map in continentCoords + float mapCenterX; + // The center Y of the current map in continentCoords + float mapCenterY; + + // The scale of how zoomed in the visible map or minimap is float mapScale; - UINT32 processId; // Windows process id + + // The windows process id of the Guild Wars 2 process + UINT32 processId; + + // An enum representing which mount is currenty being used by the player UINT8 mountIndex; }; @@ -80,6 +157,14 @@ struct MumbleContext struct LinkedMem *lm = NULL; // mumble context pointer into the `lm` variable above. struct MumbleContext *lc = NULL; + +long program_timeout = 0; +long program_startime = 0; + + +time_t rawtime; + + #ifdef _WIN32 // handle to the shared memory of Mumble link . close at the end of program. windows will only release the shared memory once ALL handles are closed, @@ -89,9 +174,7 @@ HANDLE handle_lm; LPCTSTR mapped_lm; #endif -void initMumble() -{ - +void initMumble() { #ifdef _WIN32 // creates a shared memory IF it doesn't exist. otherwise, it returns the existing shared memory handle. // reference: https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory @@ -99,29 +182,28 @@ void initMumble() size_t BUF_SIZE = sizeof(struct LinkedMem); handle_lm = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // maximum object size (high-order DWORD) - BUF_SIZE, // maximum object size (low-order DWORD) - "MumbleLink"); // name of mapping object - // createfilemapping returns NULL when it fails, we print the error code for debugging purposes. - - if (handle_lm == NULL) - { + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + BUF_SIZE, // maximum object size (low-order DWORD) + "MumbleLink"); // name of mapping object + // createfilemapping returns NULL when it fails, we print the error code for debugging purposes. + + if (handle_lm == NULL) { printf("Could not create file mapping object (%lu).\n", GetLastError()); return; } - mapped_lm = (LPTSTR)MapViewOfFile(handle_lm, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - BUF_SIZE); + mapped_lm = (LPTSTR)MapViewOfFile( + handle_lm, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + BUF_SIZE); - if (mapped_lm == NULL) - { + if (mapped_lm == NULL) { printf("Could not map view of file (%lu).\n", GetLastError()); @@ -135,19 +217,17 @@ void initMumble() printf("successfully opened mumble link shared memory..\n"); #else char memname[256]; - snprintf(memname, 256, "/MumbleLink.%d", getuid()); + snprintf(memname, sizeof(memname), "/MumbleLink.%d", getuid()); int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); - if (shmfd < 0) - { + if (shmfd < 0) { return; } lm = (struct LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)); - if (lm == (void *)(-1)) - { + if (lm == (void *)(-1)) { lm = NULL; return; } @@ -156,21 +236,25 @@ void initMumble() int last_map_id = 0; +// The max buffer size for data that is being sent to burriot over the UDP socket #define MaxBufferSize 1024 -int connect_and_or_send() -{ + +//////////////////////////////////////////////////////////////////////////////// +// connect_and_or_send() +// +// This function loops until termination, grabbing information from the shared +// memory block and sending the memory over to burrito over a UDP socket. +//////////////////////////////////////////////////////////////////////////////// +int connect_and_or_send() { WSADATA wsaData; SOCKET SendingSocket; - SOCKADDR_IN ReceiverAddr, SrcInfo; + SOCKADDR_IN ReceiverAddr; int Port = 4242; int BufLength = 1024; char SendBuf[MaxBufferSize]; - int len; int TotalByteSent; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) - { - + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("Client: WSAStartup failed with error %d\n", WSAGetLastError()); // Clean up @@ -178,18 +262,14 @@ int connect_and_or_send() // Exit with error return -1; - } - else - { + } else { printf("Client: The Winsock DLL status is %s.\n", wsaData.szSystemStatus); } // Create a new socket to receive datagrams on. SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (SendingSocket == INVALID_SOCKET) - { - + if (SendingSocket == INVALID_SOCKET) { // Print error message printf("Client: Error at socket(): %d\n", WSAGetLastError()); @@ -198,9 +278,7 @@ int connect_and_or_send() // Exit with error return -1; - } - else - { + } else { printf("Client: socket() is OK!\n"); } @@ -218,16 +296,24 @@ int connect_and_or_send() int count = 0; DWORD lastuitick = 0; // Send data packages to the receiver(Server). - do - { + do { + if (program_timeout != 0 && clock()-program_startime > program_timeout) { + BufLength = 1; + // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet + SendBuf[0] = PACKET_LINK_TIMEOUT; + TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } - if (lm->uiTick == lastuitick) - { + printf("Breaking out due to timeout"); + break; + } + if (lm->uiTick == lastuitick) { Sleep(1); continue; } lastuitick = lm->uiTick; - //printf("%ld\n", lm->uiTick); replace_point_in_rolling_average(&playerx_avg, lm->fAvatarPosition[0]); replace_point_in_rolling_average(&playery_avg, lm->fAvatarPosition[1]); @@ -239,7 +325,8 @@ int connect_and_or_send() fAvatarAveragePosition[2] = get_rolling_average(&playerz_avg); BufLength = 1; - SendBuf[0] = 1; // Per Frame Updater + // Set the first byte of the packet to indicate this packet is a `Per Frame Updater` packet + SendBuf[0] = PACKET_FRAME; memcpy(SendBuf + BufLength, lm->fCameraPosition, sizeof(lm->fCameraPosition)); BufLength += sizeof(lm->fCameraPosition); @@ -279,12 +366,18 @@ int connect_and_or_send() // printf("UI State: %i\n", lc->uiState); // Bitmask: Bit 1 = IsMapOpen, Bit 2 = IsCompassTopRight, Bit 3 = DoesCompassHaveRotationEnabled, Bit 4 = Game has focus, Bit 5 = Is in Competitive game mode, Bit 6 = Textbox has focus, Bit 7 = Is in Combat TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } - if (count == 0 || lc->mapId != last_map_id) - { + // After so many iterations have passed or under specific conditions + // we will send a larger packet that contains more information about + // the current state of the game. + if (count == 0 || lc->mapId != last_map_id) { last_map_id = lc->mapId; BufLength = 1; - SendBuf[0] = 2; // Heaver Context Updater + // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet + SendBuf[0] = PACKET_METADATA; // printf("hello world\n"); // printf("%ls\n", lm->description); @@ -330,14 +423,12 @@ int connect_and_or_send() // Get and send the linux x server window id UINT32 x11_window_id = 0; - HWND window_handle=NULL; - BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) - { + HWND window_handle = NULL; + BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) { DWORD processId; GetWindowThreadProcessId(hwnd, &processId); - if(processId == lParam) - { - window_handle=hwnd; + if (processId == lParam) { + window_handle = hwnd; return FALSE; } return TRUE; @@ -380,56 +471,25 @@ int connect_and_or_send() BufLength += converted_size; TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)); - + if (TotalByteSent != BufLength) { + printf("Not all Bytes Sent"); + } // break; } - // Sleep(16); // Slightly faster then 60fps which would be 16.6666666...ms + // Update the count for the `Heaver Context Updater` packet and reset + // it to 0 when it hits a threshold value. count += 1; - if (count > 500) - { + if (count > 500) { count = 0; } - - // TODO: Maybe make a way to break out of this loop beyond program termination } while (TRUE); - // Print some info on the receiver(Server) side... - - // Allocate the required resources - - memset(&SrcInfo, 0, sizeof(SrcInfo)); - - len = sizeof(SrcInfo); - - getsockname(SendingSocket, (SOCKADDR *)&SrcInfo, &len); - - printf("Client: Sending IP(s) used: %s\n", inet_ntoa(SrcInfo.sin_addr)); - - printf("Client: Sending port used: %d\n", htons(SrcInfo.sin_port)); - - // Print some info on the sender(Client) side... - - getpeername(SendingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr)); - - printf("Client: Receiving IP used: %s\n", inet_ntoa(ReceiverAddr.sin_addr)); - - printf("Client: Receiving port used: %d\n", htons(ReceiverAddr.sin_port)); - - printf("Client: Total byte sent: %d\n", TotalByteSent); - - // When your application is finished receiving datagrams close the socket. - - printf("Client: Finished sending. Closing the sending socket...\n"); - - if (closesocket(SendingSocket) != 0) - { + if (closesocket(SendingSocket) != 0) { printf("Client: closesocket() failed! Error code: %d\n", WSAGetLastError()); - } - else - { + } else { printf("Server: closesocket() is OK\n"); } @@ -437,40 +497,44 @@ int connect_and_or_send() printf("Client: Cleaning up...\n"); - if (WSACleanup() != 0) - { + if (WSACleanup() != 0) { printf("Client: WSACleanup() failed! Error code: %d\n", WSAGetLastError()); - } - - else - { + } else { printf("Client: WSACleanup() is OK\n"); } + #ifdef _WIN32 // unmap the shared memory from our process address space. UnmapViewOfFile(mapped_lm); // close LinkedMemory handle CloseHandle(handle_lm); - #endif + // Back to the system return 0; } -int main(int argc, char **argv) -{ + +//////////////////////////////////////////////////////////////////////////////// +// The main function initializes some global variables and shared memory. Then +// calls the connect_and_or_send process which loops until termination. +//////////////////////////////////////////////////////////////////////////////// +int main(int argc, char **argv) { + + for (int i = 0; i < argc; i++) { + // If a timeout flag is passed in then set the timeout value + if (strcmp(argv[i], "--timeout") == 0) { + i = i+1; + program_timeout = atol(argv[i]) * CLOCKS_PER_SEC; + program_startime = clock(); + } + } + playerx_avg.index = 0; playery_avg.index = 0; playerz_avg.index = 0; - printf("hello world\n"); initMumble(); - // sockmain(argc, argv); - // initMumble(); - // for (int i = 0; i < 100; i++) { - // printf("%f\n", lm->fAvatarPosition[0]); - // Sleep(16); // Slightly faster then 60fps which would be 16.6666666...ms - // } connect_and_or_send(); -} \ No newline at end of file +} diff --git a/project.godot b/project.godot index 7cd22479..be568f6c 100644 --- a/project.godot +++ b/project.godot @@ -9,12 +9,12 @@ config_version=4 _global_script_classes=[ { -"base": "", +"base": "Node", "class": "TacoParser", "language": "NativeScript", "path": "res://tacoparser.gdns" }, { -"base": "", +"base": "Node", "class": "X11_FG", "language": "NativeScript", "path": "res://Spatial.gdns" From 3bb5bd6ca686c591f712601163f38fc3313d5a3c Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 01:42:49 -0600 Subject: [PATCH 09/32] updating burrito_link formatting with mostly clang-format --- burrito_link/.clang-format | 149 ++++++++++++++++++++++++++++++++++++ burrito_link/gw2mumbleudp.c | 51 +++++------- 2 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 burrito_link/.clang-format diff --git a/burrito_link/.clang-format b/burrito_link/.clang-format new file mode 100644 index 00000000..ce7356b5 --- /dev/null +++ b/burrito_link/.clang-format @@ -0,0 +1,149 @@ +--- +Language: Cpp # Validate C++ +# BasedOnStyle: Google +AccessModifierOffset: -3 # With a tab indent of 4 spaces this equals a 1 space access modifier indent. +AlignAfterOpenBracket: AlwaysBreak # Should be `BlockIndent` when it begins to work. +AlignConsecutiveMacros: false # Keep the value of a macro close to the macro name. +AlignConsecutiveAssignments: false # Keep the new value close to the variable it is being assigned to. +AlignConsecutiveDeclarations: false # Keep new variable names close to their type definitions. +AlignEscapedNewlines: DontAlign # Keep `\` for escaped newlines close to the last character in the line. +AlignOperands: true +AlignTrailingComments: false # Keep trailing commens close to the last character in the line. +AllowShortBlocksOnASingleLine: Never # Force short blocks to have proper newlines. +AllowShortCaseLabelsOnASingleLine: false # Force contents of case statements onto the next line. +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false # Dont binpack anything +BinPackParameters: false # Dont binpack anything +BraceWrapping: + AfterCaseLabel: false # Keep the open brace on the same line as the label + AfterClass: false # Keep the open brace on the same line as the class + AfterControlStatement: false + AfterEnum: false # V + AfterFunction: false # V + AfterNamespace: false # V + AfterObjCDeclaration: false + AfterStruct: false # V + AfterUnion: false # V + AfterExternBlock: false # V + BeforeCatch: true # V + BeforeElse: true # V + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 0 # Line break auto-formatting is very difficult. Ignoring it for now +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 # Use 4 spaces for an indent +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index e2fd78b0..77899213 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -1,8 +1,8 @@ #include -#include -#include #include #include +#include +#include // Enumerations of the different packet types that can be sent #define PACKET_FRAME 1 @@ -17,7 +17,6 @@ struct rolling_average_5 { float points[5]; }; - float get_rolling_average(struct rolling_average_5 *points) { float sum = 0; for (int i = 0; i < 5; i++) { @@ -26,7 +25,6 @@ float get_rolling_average(struct rolling_average_5 *points) { return sum / 5.0; } - void replace_point_in_rolling_average(struct rolling_average_5 *points, float newvalue) { points->points[points->index] = newvalue; points->index = points->index + 1; @@ -90,7 +88,6 @@ struct LinkedMem { wchar_t description[2048]; }; - //////////////////////////////////////////////////////////////////////////////// // MumbleContext struct // @@ -161,10 +158,8 @@ struct MumbleContext *lc = NULL; long program_timeout = 0; long program_startime = 0; - time_t rawtime; - #ifdef _WIN32 // handle to the shared memory of Mumble link . close at the end of program. windows will only release the shared memory once ALL handles are closed, @@ -183,29 +178,27 @@ void initMumble() { handle_lm = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // maximum object size (high-order DWORD) - BUF_SIZE, // maximum object size (low-order DWORD) - "MumbleLink"); // name of mapping object - // createfilemapping returns NULL when it fails, we print the error code for debugging purposes. + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + BUF_SIZE, // maximum object size (low-order DWORD) + "MumbleLink"); // name of mapping object + // CreateFileMapping returns NULL when it fails, we print the error code for debugging purposes. if (handle_lm == NULL) { - printf("Could not create file mapping object (%lu).\n", - GetLastError()); + printf("Could not create file mapping object (%lu).\n", GetLastError()); return; } mapped_lm = (LPTSTR)MapViewOfFile( - handle_lm, // handle to map object + handle_lm, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (mapped_lm == NULL) { - printf("Could not map view of file (%lu).\n", - GetLastError()); + printf("Could not map view of file (%lu).\n", GetLastError()); CloseHandle(handle_lm); @@ -262,7 +255,8 @@ int connect_and_or_send() { // Exit with error return -1; - } else { + } + else { printf("Client: The Winsock DLL status is %s.\n", wsaData.szSystemStatus); } // Create a new socket to receive datagrams on. @@ -278,7 +272,8 @@ int connect_and_or_send() { // Exit with error return -1; - } else { + } + else { printf("Client: socket() is OK!\n"); } @@ -297,7 +292,7 @@ int connect_and_or_send() { DWORD lastuitick = 0; // Send data packages to the receiver(Server). do { - if (program_timeout != 0 && clock()-program_startime > program_timeout) { + if (program_timeout != 0 && clock() - program_startime > program_timeout) { BufLength = 1; // Set the first byte of the packet to indicate this packet is a `Heaver Context Updater` packet SendBuf[0] = PACKET_LINK_TIMEOUT; @@ -420,7 +415,6 @@ int connect_and_or_send() { memcpy(SendBuf + BufLength, &lc->mapId, sizeof(lc->mapId)); BufLength += sizeof(lc->mapId); - // Get and send the linux x server window id UINT32 x11_window_id = 0; HWND window_handle = NULL; @@ -446,7 +440,6 @@ int connect_and_or_send() { memcpy(SendBuf + BufLength, &x11_window_id, sizeof(x11_window_id)); BufLength += sizeof(x11_window_id); - // Convert and send the JSON 'identity' payload char utf8str[1024]; @@ -477,7 +470,6 @@ int connect_and_or_send() { // break; } - // Update the count for the `Heaver Context Updater` packet and reset // it to 0 when it hits a threshold value. count += 1; @@ -486,10 +478,10 @@ int connect_and_or_send() { } } while (TRUE); - if (closesocket(SendingSocket) != 0) { printf("Client: closesocket() failed! Error code: %d\n", WSAGetLastError()); - } else { + } + else { printf("Server: closesocket() is OK\n"); } @@ -499,7 +491,8 @@ int connect_and_or_send() { if (WSACleanup() != 0) { printf("Client: WSACleanup() failed! Error code: %d\n", WSAGetLastError()); - } else { + } + else { printf("Client: WSACleanup() is OK\n"); } @@ -514,17 +507,15 @@ int connect_and_or_send() { return 0; } - //////////////////////////////////////////////////////////////////////////////// // The main function initializes some global variables and shared memory. Then // calls the connect_and_or_send process which loops until termination. //////////////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { - for (int i = 0; i < argc; i++) { // If a timeout flag is passed in then set the timeout value if (strcmp(argv[i], "--timeout") == 0) { - i = i+1; + i = i + 1; program_timeout = atol(argv[i]) * CLOCKS_PER_SEC; program_startime = clock(); } From e247d515fe60d9ced208377621ed420fd33d9b03 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 01:43:06 -0600 Subject: [PATCH 10/32] Cleaning up burrito_link Makefile to only reference burrito_link --- burrito_link/Makefile | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/burrito_link/Makefile b/burrito_link/Makefile index b4091a35..4cc0cbc4 100644 --- a/burrito_link/Makefile +++ b/burrito_link/Makefile @@ -1,21 +1,14 @@ -# all: gw2mumbleudp.exe -all: burrito_link.exe - CC=gcc WINECC=i686-w64-mingw32-gcc CFLAGS=-Wall -Os -g -lws2_32 -# assets/shmwrapper2.bin: shmwrapper2.c -# $(CC) $< $(CFLAGS) -o $@ +# Build all targets +all: burrito_link.exe -# gw2mumbleudp.exe: gw2mumbleudp.c +# Create the CLI Executable burrito_link.exe: gw2mumbleudp.c $(WINECC) $< $(CFLAGS) -mconsole -o $@ -# bindata.go: assets/shmwrapper1.exe assets/shmwrapper2.bin -# go-bindata -pkg=wineshm -ignore=.gitkeep assets/ - +# Remove all targets and generated files clean: - rm -f assets/shmwrapper1.exe assets/shmwrapper2.bin bindata.go - -# vim: syntax=make ts=4 sw=4 sts=4 sr noet + rm -f burrito_link.exe From 365c08c2cb6f362564ac622902d068406cad8850 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 02:42:16 -0600 Subject: [PATCH 11/32] Adding sanity check for memory mapped sruct sizes --- burrito_link/gw2mumbleudp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index 77899213..e4e511a9 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -1,6 +1,8 @@ +#include #include #include #include +#include #include #include @@ -88,6 +90,7 @@ struct LinkedMem { wchar_t description[2048]; }; + //////////////////////////////////////////////////////////////////////////////// // MumbleContext struct // @@ -147,6 +150,9 @@ struct MumbleContext { // An enum representing which mount is currenty being used by the player UINT8 mountIndex; + + // Extra bytes that are not currently accounted for or are unused in the context + uint8_t _padding[171]; }; // global variables @@ -529,3 +535,8 @@ int main(int argc, char **argv) { connect_and_or_send(); } + + +// Sanity check our memory map structs on compile. +static_assert(sizeof(struct LinkedMem) == 5460, "LinkedMem is expected to be 5460 bytes long."); +static_assert(sizeof(struct MumbleContext) == 256, "MumbleContext is expected to be 256 bytes long."); From e6d0e1f9d49976fe96ed72bcb58e1403fd24f06c Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 02:42:58 -0600 Subject: [PATCH 12/32] swapping memory map struct types for standard types --- burrito_link/gw2mumbleudp.c | 38 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index e4e511a9..4904d648 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -51,10 +51,10 @@ float fAvatarAveragePosition[3]; // https://www.mumble.info/documentation/developer/positional-audio/link-plugin/ //////////////////////////////////////////////////////////////////////////////// struct LinkedMem { - UINT32 uiVersion; + uint32_t uiVersion; // The current update tick - DWORD uiTick; + uint32_t uiTick; // The XYZ location of the player float fAvatarPosition[3]; @@ -81,10 +81,10 @@ struct LinkedMem { wchar_t identity[256]; // A value that is always 48 - UINT32 context_len; + uint32_t context_len; // A binary chunk containing another struct. See the MumbleContext struct below - unsigned char context[256]; + uint8_t context[256]; // An Empty Array, this field is not used by guild wars 2 wchar_t description[2048]; @@ -103,15 +103,15 @@ struct LinkedMem { struct MumbleContext { // The current address of the guild wars 2 server the player is connected to // can be a ipv4 `sockaddr_in` or a ipv6 `sockaddr_in6` - unsigned char serverAddress[28]; + uint8_t serverAddress[28]; // The Guild Wars 2 id for the map the player is currently in - UINT32 mapId; + uint32_t mapId; - UINT32 mapType; - UINT32 shardId; - UINT32 instance; - UINT32 buildId; + uint32_t mapType; + uint32_t shardId; + uint32_t instance; + uint32_t buildId; // A bitmask of various boolean element of the UI state // Bit 1 = IsMapOpen @@ -121,13 +121,13 @@ struct MumbleContext { // Bit 5 = Is in Competitive game mode // Bit 6 = Textbox has focus // Bit 7 = Is in Combat - UINT32 uiState; + uint32_t uiState; // The width of the minimap in pixels - UINT16 compassWidth; + uint16_t compassWidth; // The height of the minimap in pixels - UINT16 compassHeight; + uint16_t compassHeight; // The rotation of the minimap contents in radians float compassRotation; @@ -146,10 +146,10 @@ struct MumbleContext { float mapScale; // The windows process id of the Guild Wars 2 process - UINT32 processId; + uint32_t processId; // An enum representing which mount is currenty being used by the player - UINT8 mountIndex; + uint8_t mountIndex; // Extra bytes that are not currently accounted for or are unused in the context uint8_t _padding[171]; @@ -513,6 +513,7 @@ int connect_and_or_send() { return 0; } + //////////////////////////////////////////////////////////////////////////////// // The main function initializes some global variables and shared memory. Then // calls the connect_and_or_send process which loops until termination. @@ -540,3 +541,10 @@ int main(int argc, char **argv) { // Sanity check our memory map structs on compile. static_assert(sizeof(struct LinkedMem) == 5460, "LinkedMem is expected to be 5460 bytes long."); static_assert(sizeof(struct MumbleContext) == 256, "MumbleContext is expected to be 256 bytes long."); + +// Sanity check our various datatypes on compile. +static_assert(sizeof(float) == 4, "float is expected to be 32 bits long."); +static_assert(sizeof(uint8_t) == 1, "uint8_t is expected to be 8 bits long."); +static_assert(sizeof(uint16_t) == 2, "uint16_t is expected to be 16 bits long."); +static_assert(sizeof(uint32_t) == 4, "uint32_t is expected to be 32 bits long."); +static_assert(sizeof(wchar_t) == 2, "wchar_t is expected to be 16 bits long."); From 41848b25f9f509f48dffb53491e84ea7007bdbb0 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 02:59:18 -0600 Subject: [PATCH 13/32] splitting out the struct definitions to a seperate file --- burrito_link/Makefile | 2 +- burrito_link/gw2mumbleudp.c | 130 +--------------------------------- burrito_link/linked_memory.h | 132 +++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 128 deletions(-) create mode 100644 burrito_link/linked_memory.h diff --git a/burrito_link/Makefile b/burrito_link/Makefile index 4cc0cbc4..76a25413 100644 --- a/burrito_link/Makefile +++ b/burrito_link/Makefile @@ -6,7 +6,7 @@ CFLAGS=-Wall -Os -g -lws2_32 all: burrito_link.exe # Create the CLI Executable -burrito_link.exe: gw2mumbleudp.c +burrito_link.exe: gw2mumbleudp.c linked_memory.h $(WINECC) $< $(CFLAGS) -mconsole -o $@ # Remove all targets and generated files diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/gw2mumbleudp.c index 4904d648..fa3ab02c 100644 --- a/burrito_link/gw2mumbleudp.c +++ b/burrito_link/gw2mumbleudp.c @@ -6,6 +6,8 @@ #include #include +#include "linked_memory.h" + // Enumerations of the different packet types that can be sent #define PACKET_FRAME 1 #define PACKET_METADATA 2 @@ -40,124 +42,10 @@ struct rolling_average_5 playerz_avg; float fAvatarAveragePosition[3]; -//////////////////////////////////////////////////////////////////////////////// -// LinkedMem struct -// -// This struct represents the Mumble Link shared memory datum that Guild Wars 2 -// uses to communicate live player and camera data, as well as some other -// bits of information that are useful for tools like burrito. -// -// https://wiki.guildwars2.com/wiki/API:MumbleLink -// https://www.mumble.info/documentation/developer/positional-audio/link-plugin/ -//////////////////////////////////////////////////////////////////////////////// -struct LinkedMem { - uint32_t uiVersion; - - // The current update tick - uint32_t uiTick; - - // The XYZ location of the player - float fAvatarPosition[3]; - - // A 3D unit vector representing the forward direction of the player character - float fAvatarFront[3]; - - // A 3D unit vector representing the up direction of the player character - float fAvatarTop[3]; - - // The string "Guild Wars 2" - wchar_t name[256]; - - // The XYZ Position of the camera - float fCameraPosition[3]; - - // A 3D unit vector representing the forward direction of the camera - float fCameraFront[3]; - - // A 3D unit vector representing the up direction of the camera - float fCameraTop[3]; - - // A json string containing json data. See https://wiki.guildwars2.com/wiki/API:MumbleLink#identity - wchar_t identity[256]; - - // A value that is always 48 - uint32_t context_len; - - // A binary chunk containing another struct. See the MumbleContext struct below - uint8_t context[256]; - - // An Empty Array, this field is not used by guild wars 2 - wchar_t description[2048]; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// MumbleContext struct -// -// This struct represents the LinkedMem.context datum that is passed in -// LinkedMem. It is a struct that is entirely specific to Guild Wars 2 which -// is why it is seperated out from the more mumble-generic LinkedMem struct. -// -// https://wiki.guildwars2.com/wiki/API:MumbleLink#context -//////////////////////////////////////////////////////////////////////////////// -struct MumbleContext { - // The current address of the guild wars 2 server the player is connected to - // can be a ipv4 `sockaddr_in` or a ipv6 `sockaddr_in6` - uint8_t serverAddress[28]; - - // The Guild Wars 2 id for the map the player is currently in - uint32_t mapId; - - uint32_t mapType; - uint32_t shardId; - uint32_t instance; - uint32_t buildId; - - // A bitmask of various boolean element of the UI state - // Bit 1 = IsMapOpen - // Bit 2 = IsCompassTopRight - // Bit 3 = DoesCompassHaveRotationEnabled - // Bit 4 = Game has focus - // Bit 5 = Is in Competitive game mode - // Bit 6 = Textbox has focus - // Bit 7 = Is in Combat - uint32_t uiState; - - // The width of the minimap in pixels - uint16_t compassWidth; - - // The height of the minimap in pixels - uint16_t compassHeight; - - // The rotation of the minimap contents in radians - float compassRotation; - - // The X location of the player in continentCoords - float playerX; - // The Y location of the player in continentCoords - float playerY; - - // The center X of the current map in continentCoords - float mapCenterX; - // The center Y of the current map in continentCoords - float mapCenterY; - - // The scale of how zoomed in the visible map or minimap is - float mapScale; - - // The windows process id of the Guild Wars 2 process - uint32_t processId; - - // An enum representing which mount is currenty being used by the player - uint8_t mountIndex; - - // Extra bytes that are not currently accounted for or are unused in the context - uint8_t _padding[171]; -}; - // global variables // mumble link pointer struct LinkedMem *lm = NULL; + // mumble context pointer into the `lm` variable above. struct MumbleContext *lc = NULL; @@ -536,15 +424,3 @@ int main(int argc, char **argv) { connect_and_or_send(); } - - -// Sanity check our memory map structs on compile. -static_assert(sizeof(struct LinkedMem) == 5460, "LinkedMem is expected to be 5460 bytes long."); -static_assert(sizeof(struct MumbleContext) == 256, "MumbleContext is expected to be 256 bytes long."); - -// Sanity check our various datatypes on compile. -static_assert(sizeof(float) == 4, "float is expected to be 32 bits long."); -static_assert(sizeof(uint8_t) == 1, "uint8_t is expected to be 8 bits long."); -static_assert(sizeof(uint16_t) == 2, "uint16_t is expected to be 16 bits long."); -static_assert(sizeof(uint32_t) == 4, "uint32_t is expected to be 32 bits long."); -static_assert(sizeof(wchar_t) == 2, "wchar_t is expected to be 16 bits long."); diff --git a/burrito_link/linked_memory.h b/burrito_link/linked_memory.h new file mode 100644 index 00000000..eb2b88b8 --- /dev/null +++ b/burrito_link/linked_memory.h @@ -0,0 +1,132 @@ +#include +#include + +#ifndef wchar_t +#define wchar_t uint16_t +#endif + +//////////////////////////////////////////////////////////////////////////////// +// LinkedMem struct +// +// This struct represents the Mumble Link shared memory datum that Guild Wars 2 +// uses to communicate live player and camera data, as well as some other +// bits of information that are useful for tools like burrito. +// +// https://wiki.guildwars2.com/wiki/API:MumbleLink +// https://www.mumble.info/documentation/developer/positional-audio/link-plugin/ +//////////////////////////////////////////////////////////////////////////////// +struct LinkedMem { + uint32_t uiVersion; + + // The current update tick + uint32_t uiTick; + + // The XYZ location of the player + float fAvatarPosition[3]; + + // A 3D unit vector representing the forward direction of the player character + float fAvatarFront[3]; + + // A 3D unit vector representing the up direction of the player character + float fAvatarTop[3]; + + // The string "Guild Wars 2" + wchar_t name[256]; + + // The XYZ Position of the camera + float fCameraPosition[3]; + + // A 3D unit vector representing the forward direction of the camera + float fCameraFront[3]; + + // A 3D unit vector representing the up direction of the camera + float fCameraTop[3]; + + // A json string containing json data. See https://wiki.guildwars2.com/wiki/API:MumbleLink#identity + wchar_t identity[256]; + + // A value that is always 48 + uint32_t context_len; + + // A binary chunk containing another struct. See the MumbleContext struct below + uint8_t context[256]; + + // An Empty Array, this field is not used by guild wars 2 + wchar_t description[2048]; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// MumbleContext struct +// +// This struct represents the LinkedMem.context datum that is passed in +// LinkedMem. It is a struct that is entirely specific to Guild Wars 2 which +// is why it is seperated out from the more mumble-generic LinkedMem struct. +// +// https://wiki.guildwars2.com/wiki/API:MumbleLink#context +//////////////////////////////////////////////////////////////////////////////// +struct MumbleContext { + // The current address of the guild wars 2 server the player is connected to + // can be a ipv4 `sockaddr_in` or a ipv6 `sockaddr_in6` + uint8_t serverAddress[28]; + + // The Guild Wars 2 id for the map the player is currently in + uint32_t mapId; + + uint32_t mapType; + uint32_t shardId; + uint32_t instance; + uint32_t buildId; + + // A bitmask of various boolean element of the UI state + // Bit 1 = IsMapOpen + // Bit 2 = IsCompassTopRight + // Bit 3 = DoesCompassHaveRotationEnabled + // Bit 4 = Game has focus + // Bit 5 = Is in Competitive game mode + // Bit 6 = Textbox has focus + // Bit 7 = Is in Combat + uint32_t uiState; + + // The width of the minimap in pixels + uint16_t compassWidth; + + // The height of the minimap in pixels + uint16_t compassHeight; + + // The rotation of the minimap contents in radians + float compassRotation; + + // The X location of the player in continentCoords + float playerX; + // The Y location of the player in continentCoords + float playerY; + + // The center X of the current map in continentCoords + float mapCenterX; + // The center Y of the current map in continentCoords + float mapCenterY; + + // The scale of how zoomed in the visible map or minimap is + float mapScale; + + // The windows process id of the Guild Wars 2 process + uint32_t processId; + + // An enum representing which mount is currenty being used by the player + uint8_t mountIndex; + + // Extra bytes that are not currently accounted for or are unused in the context + uint8_t _padding[171]; +}; + +// Sanity check our memory map structs on compile. +static_assert(sizeof(struct LinkedMem) == 5460, "LinkedMem is expected to be 5460 bytes long."); +static_assert(sizeof(struct MumbleContext) == 256, "MumbleContext is expected to be 256 bytes long."); + +// Sanity check our various datatypes on compile. +static_assert(sizeof(float) == 4, "float is expected to be 32 bits long."); +static_assert(sizeof(uint8_t) == 1, "uint8_t is expected to be 8 bits long."); +static_assert(sizeof(uint16_t) == 2, "uint16_t is expected to be 16 bits long."); +static_assert(sizeof(uint32_t) == 4, "uint32_t is expected to be 32 bits long."); +static_assert(sizeof(wchar_t) == 2, "wchar_t is expected to be 16 bits long."); From 7445b09c03833d84c7d1d388f98739b7e237a176 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 03:00:37 -0600 Subject: [PATCH 14/32] renaming gw2mumbleudp.c to burrito_link.c --- burrito_link/Makefile | 2 +- burrito_link/{gw2mumbleudp.c => burrito_link.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename burrito_link/{gw2mumbleudp.c => burrito_link.c} (100%) diff --git a/burrito_link/Makefile b/burrito_link/Makefile index 76a25413..eb5e154a 100644 --- a/burrito_link/Makefile +++ b/burrito_link/Makefile @@ -6,7 +6,7 @@ CFLAGS=-Wall -Os -g -lws2_32 all: burrito_link.exe # Create the CLI Executable -burrito_link.exe: gw2mumbleudp.c linked_memory.h +burrito_link.exe: burrito_link.c linked_memory.h $(WINECC) $< $(CFLAGS) -mconsole -o $@ # Remove all targets and generated files diff --git a/burrito_link/gw2mumbleudp.c b/burrito_link/burrito_link.c similarity index 100% rename from burrito_link/gw2mumbleudp.c rename to burrito_link/burrito_link.c From 467d4590cff60cfaccfae91bdecb2fc953f976a3 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Mon, 21 Nov 2022 11:56:35 -0600 Subject: [PATCH 15/32] replacing make with cmake to get compile_commands.json for clangd more easily --- burrito_link/.gitignore | 3 +++ burrito_link/CMakeLists.txt | 21 +++++++++++++++++++++ burrito_link/Makefile | 4 ++++ 3 files changed, 28 insertions(+) create mode 100644 burrito_link/.gitignore create mode 100644 burrito_link/CMakeLists.txt diff --git a/burrito_link/.gitignore b/burrito_link/.gitignore new file mode 100644 index 00000000..7764270d --- /dev/null +++ b/burrito_link/.gitignore @@ -0,0 +1,3 @@ +.clangd/ +build/ +compile_commands.json diff --git a/burrito_link/CMakeLists.txt b/burrito_link/CMakeLists.txt new file mode 100644 index 00000000..ec617dc4 --- /dev/null +++ b/burrito_link/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) + +project (burrito_link) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# remove `-rdynamic` default link library flag set in the linux `Platform/*.cmake` file +SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) + +# Set the compiler to mingw so we can build a windows executable on linux +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) + +# Create the standalone executable +set(STANDALONE burrito_link.exe) +add_executable (${STANDALONE} "burrito_link.c") +target_link_libraries(${STANDALONE} PRIVATE "ws2_32") + +target_compile_options(${STANDALONE} PRIVATE -Wall -Os -g) + +# An option specifically for creating console application and not a windowed application +target_compile_options(${STANDALONE} PRIVATE -mconsole) diff --git a/burrito_link/Makefile b/burrito_link/Makefile index eb5e154a..0504f526 100644 --- a/burrito_link/Makefile +++ b/burrito_link/Makefile @@ -1,3 +1,7 @@ +# This Makefile is deprecated in favor of the CMakeLists.txt file, but is going +# to stick around for a little bit until whenever we deem that enough testing +# has been done on the files outputted by the CMake build process. + CC=gcc WINECC=i686-w64-mingw32-gcc CFLAGS=-Wall -Os -g -lws2_32 From 9b554a23c2fa47b131f8a3386dd06c22f576d73c Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Tue, 22 Nov 2022 00:27:25 -0600 Subject: [PATCH 16/32] moving some globals to the top of the file --- burrito_link/burrito_link.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/burrito_link/burrito_link.c b/burrito_link/burrito_link.c index fa3ab02c..c9041047 100644 --- a/burrito_link/burrito_link.c +++ b/burrito_link/burrito_link.c @@ -13,6 +13,15 @@ #define PACKET_METADATA 2 #define PACKET_LINK_TIMEOUT 3 + +// The max buffer size for data that is being sent to burriot over the UDP socket +#define MaxBufferSize 1024 + +// A state variable to keep track of the previous cycle's map_id to determine +// if the map_id has changed in this cycle. +int last_map_id = 0; + + // Do a rolling average on the player position because that seems to be // Roughly what the camera position is doing and doing this will remove // some weird jitter I hope @@ -52,7 +61,6 @@ struct MumbleContext *lc = NULL; long program_timeout = 0; long program_startime = 0; -time_t rawtime; #ifdef _WIN32 @@ -121,11 +129,6 @@ void initMumble() { #endif } -int last_map_id = 0; - -// The max buffer size for data that is being sent to burriot over the UDP socket -#define MaxBufferSize 1024 - //////////////////////////////////////////////////////////////////////////////// // connect_and_or_send() // From b498493579dd616a59deceb7f1940088ef28ba96 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Tue, 22 Nov 2022 00:37:25 -0600 Subject: [PATCH 17/32] Removing non _WIN32 memory mapping code Also removing all the ifdefs for _WIN32 specific code assuming that this program should only be compiled with _WIN32 --- burrito_link/burrito_link.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/burrito_link/burrito_link.c b/burrito_link/burrito_link.c index c9041047..7ee963d2 100644 --- a/burrito_link/burrito_link.c +++ b/burrito_link/burrito_link.c @@ -62,17 +62,13 @@ long program_timeout = 0; long program_startime = 0; -#ifdef _WIN32 - // handle to the shared memory of Mumble link . close at the end of program. windows will only release the shared memory once ALL handles are closed, // so we don't have to worry about other processes like arcdps or other overlays if they are using this. HANDLE handle_lm; // the pointer to the mapped view of the file. close before handle. LPCTSTR mapped_lm; -#endif void initMumble() { -#ifdef _WIN32 // creates a shared memory IF it doesn't exist. otherwise, it returns the existing shared memory handle. // reference: https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory @@ -110,23 +106,6 @@ void initMumble() { lc = (struct MumbleContext *)lm->context; printf("successfully opened mumble link shared memory..\n"); -#else - char memname[256]; - snprintf(memname, sizeof(memname), "/MumbleLink.%d", getuid()); - - int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); - - if (shmfd < 0) { - return; - } - - lm = (struct LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0)); - - if (lm == (void *)(-1)) { - lm = NULL; - return; - } -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -393,12 +372,10 @@ int connect_and_or_send() { printf("Client: WSACleanup() is OK\n"); } -#ifdef _WIN32 // unmap the shared memory from our process address space. UnmapViewOfFile(mapped_lm); // close LinkedMemory handle CloseHandle(handle_lm); -#endif // Back to the system return 0; From bcb88de1be682752f5c113bfde668021821a3006 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Tue, 22 Nov 2022 01:36:36 -0600 Subject: [PATCH 18/32] splitting out function to get the x11 window id from the windows process id --- burrito_link/burrito_link.c | 54 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/burrito_link/burrito_link.c b/burrito_link/burrito_link.c index 7ee963d2..9f33410b 100644 --- a/burrito_link/burrito_link.c +++ b/burrito_link/burrito_link.c @@ -108,6 +108,38 @@ void initMumble() { printf("successfully opened mumble link shared memory..\n"); } + +//////////////////////////////////////////////////////////////////////////////// +// x11_window_id_from_windows_process_id() +// +// When running a program in wine a property `__wine_x11_whole_window` is set. +// This function attempts to read that property and return it. +//////////////////////////////////////////////////////////////////////////////// +uint32_t x11_window_id_from_windows_process_id(uint32_t windows_process_id) { + // Get and send the linux x server window id + UINT32 x11_window_id = 0; + HWND window_handle = NULL; + BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) { + DWORD processId; + GetWindowThreadProcessId(hwnd, &processId); + if (processId == lParam) { + window_handle = hwnd; + return FALSE; + } + return TRUE; + } + EnumWindows(EnumWindowsProcMy, windows_process_id); + + HANDLE possible_x11_window_id = GetProp(window_handle, "__wine_x11_whole_window"); + if (possible_x11_window_id != NULL) { + x11_window_id = (size_t)possible_x11_window_id; + } + // else { + // printf("No Linux ID\n"); + // } + return x11_window_id; +} + //////////////////////////////////////////////////////////////////////////////// // connect_and_or_send() // @@ -291,27 +323,7 @@ int connect_and_or_send() { memcpy(SendBuf + BufLength, &lc->mapId, sizeof(lc->mapId)); BufLength += sizeof(lc->mapId); - // Get and send the linux x server window id - UINT32 x11_window_id = 0; - HWND window_handle = NULL; - BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) { - DWORD processId; - GetWindowThreadProcessId(hwnd, &processId); - if (processId == lParam) { - window_handle = hwnd; - return FALSE; - } - return TRUE; - } - EnumWindows(EnumWindowsProcMy, lc->processId); - - HANDLE possible_x11_window_id = GetProp(window_handle, "__wine_x11_whole_window"); - if (possible_x11_window_id != NULL) { - x11_window_id = (size_t)possible_x11_window_id; - } - // else { - // printf("No Linux ID\n"); - // } + uint32_t x11_window_id = x11_window_id_from_windows_process_id(lc->processId); memcpy(SendBuf + BufLength, &x11_window_id, sizeof(x11_window_id)); BufLength += sizeof(x11_window_id); From ca57358ee2cb439ed563f520ee0ec8991bbd66f5 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 27 Nov 2022 03:25:04 -0600 Subject: [PATCH 19/32] adding a barebones linked library proxy --- burrito_link/CMakeLists.txt | 20 ++- burrito_link/deffile.def | 5 + burrito_link/dllmain.c | 311 ++++++++++++++++++++++++++++++++++++ 3 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 burrito_link/deffile.def create mode 100644 burrito_link/dllmain.c diff --git a/burrito_link/CMakeLists.txt b/burrito_link/CMakeLists.txt index ec617dc4..b292d172 100644 --- a/burrito_link/CMakeLists.txt +++ b/burrito_link/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # Set the compiler to mingw so we can build a windows executable on linux -SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) # Create the standalone executable set(STANDALONE burrito_link.exe) @@ -19,3 +19,21 @@ target_compile_options(${STANDALONE} PRIVATE -Wall -Os -g) # An option specifically for creating console application and not a windowed application target_compile_options(${STANDALONE} PRIVATE -mconsole) + + +# Create the D3D11.dll file +set(CMAKE_SYSTEM_NAME Windows) + +SET(DX11LIB d3d11.dll) + +# Will this build a library +add_library(${DX11LIB} SHARED dllmain.c) + +target_compile_options(${DX11LIB} PRIVATE -mwindows) +target_compile_options(${DX11LIB} PRIVATE -static-libgcc -static-libstdc++) + +set_target_properties(${DX11LIB} PROPERTIES + PREFIX "" + SUFFIX "" + LINK_FLAGS "../deffile.def -Wl,--allow-shlib-undefined -Wl,-O1 -shared -static -static-libgcc -static-libstdc++ -Wl,--file-alignment=4096 -lm -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32" +) diff --git a/burrito_link/deffile.def b/burrito_link/deffile.def new file mode 100644 index 00000000..a9258fb5 --- /dev/null +++ b/burrito_link/deffile.def @@ -0,0 +1,5 @@ +LIBRARY d3d11.dll +EXPORTS + D3D11CreateDevice + D3D11CreateDeviceAndSwapChain + D3D11CoreCreateDevice diff --git a/burrito_link/dllmain.c b/burrito_link/dllmain.c new file mode 100644 index 00000000..0853b2b3 --- /dev/null +++ b/burrito_link/dllmain.c @@ -0,0 +1,311 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#ifndef true +#define true TRUE +#endif + +#ifndef false +#define false FALSE +#endif + +#ifndef nullptr +#define nullptr 0 +#endif + + +// #define CEXTERN extern "C" +#define CEXTERN extern + +BOOL should_launch = true; + +void writelog() { + if (should_launch) { + printf("Launching2\n"); + fflush(stdout); + should_launch = false; + } + else { + printf("Already Launched2\n"); + fflush(stdout); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// GetOriginalD3D11Module +// +// This loads the original d3d11.dll file so that we can pass the function +// calls made to this library into that library as if they were implemented in +// this library. +//////////////////////////////////////////////////////////////////////////////// +HMODULE D3D11Library = nullptr; +HMODULE GetOriginalD3D11Module() { + // If we have already loaded the library into this process return the + // pointer to it instead of loading it a second time. + if (!D3D11Library) { + char infoBuf[4096]; + GetSystemDirectory(infoBuf, 4096); + lstrcat(infoBuf, "\\d3d11.dll"); + + // Load this library and track it. We don't want to use GetModuleHandle + // here because GetModuleHandle does not increment the internal + // reference count meaning that FreeLibrary would incorrectly decrement + // it when we unload. + D3D11Library = LoadLibrary(infoBuf); + } + + return D3D11Library; +} + + +//////////////////////////////////////////////////////////////////////////////// +// FreeD3D11Module +// +// This frees the original d3d11.dll file so that this process no longer is +// using it. +//////////////////////////////////////////////////////////////////////////////// +void FreeD3D11Module() { + if (D3D11Library) { + FreeLibrary(D3D11Library); + + } +} + + + + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CreateDeviceAndSwapChainOriginal +// +// A pointer to a function that looks like D3D11CreateDeviceAndSwapChain() +//////////////////////////////////////////////////////////////////////////////// +typedef HRESULT(WINAPI* D3D11CreateDeviceAndSwapChainFunc)( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IDXGISwapChain** ppSwapChain, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext +); +D3D11CreateDeviceAndSwapChainFunc D3D11CreateDeviceAndSwapChainOriginal = nullptr; + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CreateDeviceAndSwapChain +// +// A proxy function that calls the original d3d11.dll's +// D3D11CreateDeviceAndSwapChain function, then returns the result. +//////////////////////////////////////////////////////////////////////////////// +CEXTERN HRESULT WINAPI D3D11CreateDeviceAndSwapChain( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IDXGISwapChain** ppSwapChain, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext +) { + printf("FUNCTION: D3D11CreateDeviceAndSwapChain\n"); + fflush(stdout); + // Get the function address if we don't have it yet. + if (!D3D11CreateDeviceAndSwapChainOriginal) { + HMODULE original_d3d11 = GetOriginalD3D11Module(); + D3D11CreateDeviceAndSwapChainOriginal = (D3D11CreateDeviceAndSwapChainFunc)GetProcAddress(original_d3d11, "D3D11CreateDeviceAndSwapChain"); + } + + return D3D11CreateDeviceAndSwapChainOriginal( + pAdapter, + DriverType, + Software, + Flags, + pFeatureLevels, + FeatureLevels, + SDKVersion, + pSwapChainDesc, + ppSwapChain, + ppDevice, + pFeatureLevel, + ppImmediateContext + ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CreateDeviceOriginal +// +// A pointer to a function that looks like D3D11CreateDevice() +//////////////////////////////////////////////////////////////////////////////// +typedef HRESULT(WINAPI* D3D11CreateDeviceFunc)( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext +); +D3D11CreateDeviceFunc D3D11CreateDeviceOriginal = nullptr; + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CreateDevice +// +// A proxy function that call the original d3d11.dll's D3D11CreateDevice +// function, then returns the result. +//////////////////////////////////////////////////////////////////////////////// +CEXTERN HRESULT WINAPI D3D11CreateDevice( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext +) { + printf("FUNCTION: D3D11CreateDevice\n"); + fflush(stdout); + // Get the function address if we don't have it yet. + if (!D3D11CreateDeviceOriginal) { + HMODULE original_d3d11 = GetOriginalD3D11Module(); + D3D11CreateDeviceOriginal = (D3D11CreateDeviceFunc)GetProcAddress(original_d3d11, "D3D11CreateDevice"); + } + + return D3D11CreateDeviceOriginal( + pAdapter, + DriverType, + Software, + Flags, + pFeatureLevels, + FeatureLevels, + SDKVersion, + ppDevice, + pFeatureLevel, + ppImmediateContext + ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CoreCreateDeviceOriginal +// +// A pointer to a function that looks like D3D11CoreCreateDevice() +//////////////////////////////////////////////////////////////////////////////// +typedef HRESULT(WINAPI* D3D11CoreCreateDeviceFunc)( + IDXGIFactory * pFactory, + IDXGIAdapter * pAdapter, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + ID3D11Device** ppDevice +); +D3D11CoreCreateDeviceFunc D3D11CoreCreateDeviceOriginal = nullptr; + +//////////////////////////////////////////////////////////////////////////////// +// D3D11CoreCreateDevice +// +// A proxy function that call the original d3d11.dll's D3D11CoreCreateDevice +// function, then returns the result. +//////////////////////////////////////////////////////////////////////////////// +CEXTERN HRESULT WINAPI D3D11CoreCreateDevice( + IDXGIFactory * pFactory, + IDXGIAdapter * pAdapter, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + ID3D11Device** ppDevice +) { + printf("FUNCTION: D3D11CoreCreateDevice\n"); + fflush(stdout); + // Get the function address if we don't have it yet. + if (!D3D11CoreCreateDeviceOriginal) { + HMODULE original_d3d11 = GetOriginalD3D11Module(); + D3D11CoreCreateDeviceOriginal = (D3D11CoreCreateDeviceFunc)GetProcAddress(original_d3d11, "D3D11CoreCreateDevice"); + } + + return D3D11CoreCreateDeviceOriginal( + pFactory, + pAdapter, + Flags, + pFeatureLevels, + FeatureLevels, + ppDevice + ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// DllMain +// +// DllMain is the entry point called when this dll is loaded. We use this +// function to spawn the background threads for burrito_link. +// +// The windows documentation says not to create threads inside of DllMain +// because of two reasons: +// 1) If you wait on the thread you will cause a deadlock. +// 2) Anybody who loads a DLL files would not expect purely loading the file +// to do business logic. +// The first reason is relevant to us, we must make sure to not ever wait on +// the thread or else we will cause a deadlock. The second reason is irrelevant +// as this behavior is the exact unexpected behavior we are trying to take +// advantage of in order to inject our code into the running process. Thus it +// is safe and a good idea to call CreateThread in DllMain. +//////////////////////////////////////////////////////////////////////////////// +BOOL WINAPI DllMain( + HINSTANCE hinstDLL, // handle to the DLL module + DWORD fdwReason, // reason for calling DllMain + LPVOID lpvReserved // Reserved +) { + printf("FUNCTION: 2 C DllMain "); + // Perform actions based on the reason for calling. + switch(fdwReason) { + // Do process initialization. Return false if initialization fails. + case DLL_PROCESS_ATTACH: + // TODO: Here is where we want to create a new process. + printf("DLL_PROCESS_ATTACH\n"); + break; + + // Do thread-specific initialization. + case DLL_THREAD_ATTACH: + printf("DLL_THREAD_ATTACH\n"); + break; + + // Do thread-specific cleanup. + case DLL_THREAD_DETACH: + printf("DLL_THREAD_DETACH\n"); + break; + + // Do process cleanup + case DLL_PROCESS_DETACH: + // Skip cleanup if process termination scenario + if (lpvReserved != nullptr) { + printf("DLL_THREAD_DETACH no cleanup\n"); + break; + } + printf("DLL_THREAD_DETACH\n"); + + // Cleanup process + FreeD3D11Module(); + break; + } + fflush(stdout); + + return true; +} From 89bc9b6be1a85f7be22e0143ba5948cc350c83ca Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 27 Nov 2022 03:47:07 -0600 Subject: [PATCH 20/32] Getting burrito link to work in d3d11.dll The burrito_link infinite loop can now run within the built d3d11.dll file. Meaning that burrito link can now be auto launched by gw2 and does not need any configuration to do so. --- burrito_link/CMakeLists.txt | 4 +++- burrito_link/burrito_link.c | 17 ++++++++++------- burrito_link/dllmain.c | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/burrito_link/CMakeLists.txt b/burrito_link/CMakeLists.txt index b292d172..fc25597e 100644 --- a/burrito_link/CMakeLists.txt +++ b/burrito_link/CMakeLists.txt @@ -27,11 +27,13 @@ set(CMAKE_SYSTEM_NAME Windows) SET(DX11LIB d3d11.dll) # Will this build a library -add_library(${DX11LIB} SHARED dllmain.c) +add_library(${DX11LIB} SHARED dllmain.c burrito_link.c) target_compile_options(${DX11LIB} PRIVATE -mwindows) target_compile_options(${DX11LIB} PRIVATE -static-libgcc -static-libstdc++) +target_link_libraries(${DX11LIB} PRIVATE "ws2_32") + set_target_properties(${DX11LIB} PROPERTIES PREFIX "" SUFFIX "" diff --git a/burrito_link/burrito_link.c b/burrito_link/burrito_link.c index 9f33410b..b5f5dc64 100644 --- a/burrito_link/burrito_link.c +++ b/burrito_link/burrito_link.c @@ -393,6 +393,15 @@ int connect_and_or_send() { return 0; } +void run_link() { + playerx_avg.index = 0; + playery_avg.index = 0; + playerz_avg.index = 0; + + initMumble(); + + connect_and_or_send(); +} //////////////////////////////////////////////////////////////////////////////// // The main function initializes some global variables and shared memory. Then @@ -408,11 +417,5 @@ int main(int argc, char **argv) { } } - playerx_avg.index = 0; - playery_avg.index = 0; - playerz_avg.index = 0; - - initMumble(); - - connect_and_or_send(); + run_link(); } diff --git a/burrito_link/dllmain.c b/burrito_link/dllmain.c index 0853b2b3..ddbd4f03 100644 --- a/burrito_link/dllmain.c +++ b/burrito_link/dllmain.c @@ -251,6 +251,20 @@ CEXTERN HRESULT WINAPI D3D11CoreCreateDevice( } +// Forward declare the run_link() function defined in burrito_link.c +void run_link(); + +// Call the burrito link function from the thread. +// TODO: There is something odd here that causes a crash as gw2 is exiting. +// Because gw2 is exiting the crash does not really matter. I am guessing it +// has something to do with how we handle the infinite wait loop inside +// burrito_link and that we dont clean it up ever. +void WINAPI BurritoLinkThread() { + run_link(); + return; +} + + //////////////////////////////////////////////////////////////////////////////// // DllMain // @@ -280,6 +294,9 @@ BOOL WINAPI DllMain( case DLL_PROCESS_ATTACH: // TODO: Here is where we want to create a new process. printf("DLL_PROCESS_ATTACH\n"); + + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)BurritoLinkThread, NULL, 0, NULL); + break; // Do thread-specific initialization. From 084aabe235018c8c9be33adaccac347ef9e3e0a7 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Fri, 24 Feb 2023 17:06:30 -0600 Subject: [PATCH 21/32] Closing the thread when the dll is unloaded --- burrito_link/dllmain.c | 53 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/burrito_link/dllmain.c b/burrito_link/dllmain.c index ddbd4f03..b9c4dd1d 100644 --- a/burrito_link/dllmain.c +++ b/burrito_link/dllmain.c @@ -265,6 +265,48 @@ void WINAPI BurritoLinkThread() { } +//////////////////////////////////////////////////////////////////////////////// +// start_burrito_link_thread +// +// Creates a new burrito link thread if there is no existing burrito link +// thread running. +//////////////////////////////////////////////////////////////////////////////// +HANDLE burrito_link_thread_handle = nullptr; +void start_burrito_link_thread() { + if (burrito_link_thread_handle != nullptr) { + return; + } + + burrito_link_thread_handle = CreateThread( + NULL, + 0, + (LPTHREAD_START_ROUTINE)BurritoLinkThread, + NULL, + 0, + NULL + ); + + if (burrito_link_thread_handle == nullptr) { + // Failed to create the thread. + printf("Failed to create burrito link thread"); + } + +} + + +//////////////////////////////////////////////////////////////////////////////// +// stop_burrito_link_thread +// +// Kills a burrito link thread if there is a burrito link thread running. This +// is nessasry to avoid an error message on exit. +//////////////////////////////////////////////////////////////////////////////// +void stop_burrito_link_thread() { + if (burrito_link_thread_handle != nullptr) { + TerminateThread(burrito_link_thread_handle, 0); + } +} + + //////////////////////////////////////////////////////////////////////////////// // DllMain // @@ -294,9 +336,7 @@ BOOL WINAPI DllMain( case DLL_PROCESS_ATTACH: // TODO: Here is where we want to create a new process. printf("DLL_PROCESS_ATTACH\n"); - - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)BurritoLinkThread, NULL, 0, NULL); - + start_burrito_link_thread(); break; // Do thread-specific initialization. @@ -313,11 +353,12 @@ BOOL WINAPI DllMain( case DLL_PROCESS_DETACH: // Skip cleanup if process termination scenario if (lpvReserved != nullptr) { - printf("DLL_THREAD_DETACH no cleanup\n"); + printf("DLL_PROCESS_DETACH no cleanup\n"); break; } - printf("DLL_THREAD_DETACH\n"); - + printf("DLL_PROCESS_DETACH\n"); + stop_burrito_link_thread(); + // Cleanup process FreeD3D11Module(); break; From fc7bdc1bdba9204a2b2b6429132261ae3297dc47 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Fri, 24 Feb 2023 22:38:10 -0600 Subject: [PATCH 22/32] supporting burrito link dll as an arcdps plugin --- burrito_link/deffile.def | 2 ++ burrito_link/dllmain.c | 76 +++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/burrito_link/deffile.def b/burrito_link/deffile.def index a9258fb5..eb57a4e1 100644 --- a/burrito_link/deffile.def +++ b/burrito_link/deffile.def @@ -3,3 +3,5 @@ EXPORTS D3D11CreateDevice D3D11CreateDeviceAndSwapChain D3D11CoreCreateDevice + get_init_addr + get_release_addr diff --git a/burrito_link/dllmain.c b/burrito_link/dllmain.c index b9c4dd1d..62ea9ef3 100644 --- a/burrito_link/dllmain.c +++ b/burrito_link/dllmain.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifndef true #define true TRUE @@ -15,24 +16,8 @@ #define nullptr 0 #endif - -// #define CEXTERN extern "C" #define CEXTERN extern -BOOL should_launch = true; - -void writelog() { - if (should_launch) { - printf("Launching2\n"); - fflush(stdout); - should_launch = false; - } - else { - printf("Already Launched2\n"); - fflush(stdout); - } -} - //////////////////////////////////////////////////////////////////////////////// // GetOriginalD3D11Module @@ -76,7 +61,6 @@ void FreeD3D11Module() { - //////////////////////////////////////////////////////////////////////////////// // D3D11CreateDeviceAndSwapChainOriginal // @@ -329,7 +313,7 @@ BOOL WINAPI DllMain( DWORD fdwReason, // reason for calling DllMain LPVOID lpvReserved // Reserved ) { - printf("FUNCTION: 2 C DllMain "); + // printf("FUNCTION: 2 C DllMain "); // Perform actions based on the reason for calling. switch(fdwReason) { // Do process initialization. Return false if initialization fails. @@ -341,12 +325,12 @@ BOOL WINAPI DllMain( // Do thread-specific initialization. case DLL_THREAD_ATTACH: - printf("DLL_THREAD_ATTACH\n"); + // printf("DLL_THREAD_ATTACH\n"); break; // Do thread-specific cleanup. case DLL_THREAD_DETACH: - printf("DLL_THREAD_DETACH\n"); + // printf("DLL_THREAD_DETACH\n"); break; // Do process cleanup @@ -367,3 +351,55 @@ BOOL WINAPI DllMain( return true; } + + +//////////////////////////////////////////////////////////////////////////////// +// arcdps +// +// get_init_addr +// get_release_addr +// +// These functions are present to allow arcdps to recognize this dll as a +// plugin for arcdps and run it alongside arcdps. These two functions are the +// only functions that are required for arcdps' api and all others are optional. +//////////////////////////////////////////////////////////////////////////////// +#ifndef ImGuiContext +#define ImGuiContext void +#endif +typedef struct arcdps_exports { + uintptr_t size; + uint32_t sig; + uint32_t imguivers; + const char* out_name; + const char* out_build; + void* wnd_nofilter; + void* combat; + void* imgui; + void* options_end; + void* combat_local; + void* wnd_filter; + void* options_windows; +} arcdps_exports; + +arcdps_exports arc_exports; +arcdps_exports* mod_init() { + memset(&arc_exports, 0, sizeof(arcdps_exports)); + arc_exports.sig = 0xFFFA; + arc_exports.size = sizeof(arcdps_exports); + arc_exports.out_name = "BurritoLink"; + arc_exports.out_build = "1.0"; + return &arc_exports; +} + +extern __declspec(dllexport) void* get_init_addr(char* arcversion, ImGuiContext* imguictx, void* id3dptr, HANDLE arcdll, void* mallocfn, void* freefn, uint32_t d3dversion) { + return mod_init; +} + +uintptr_t mod_release() { + FreeConsole(); + return 0; +} + +extern __declspec(dllexport) void* get_release_addr() { + return mod_release; +} From d9bee0178132054fb4fd470dc4d232249decffbe Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Fri, 24 Feb 2023 23:14:50 -0600 Subject: [PATCH 23/32] burrito link cmake build --- .github/workflows/main.yml | 8 ++++++-- burrito_link/Makefile | 18 ------------------ 2 files changed, 6 insertions(+), 20 deletions(-) delete mode 100644 burrito_link/Makefile diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d4ad6bf6..6e8e9e73 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,9 +91,13 @@ jobs: - name: Build Burrito Link run: | - cd burrito_link + mkdir output/burrito_link + mkdir burrito_link/build + cd burrito_link/build + cmake .. make - mv burrito_link.exe ../output + mv burrito_link.exe ../../output/burrito_link + mv d3d11.dll ../../output/burrito_link - name: Build Burrito diff --git a/burrito_link/Makefile b/burrito_link/Makefile deleted file mode 100644 index 0504f526..00000000 --- a/burrito_link/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# This Makefile is deprecated in favor of the CMakeLists.txt file, but is going -# to stick around for a little bit until whenever we deem that enough testing -# has been done on the files outputted by the CMake build process. - -CC=gcc -WINECC=i686-w64-mingw32-gcc -CFLAGS=-Wall -Os -g -lws2_32 - -# Build all targets -all: burrito_link.exe - -# Create the CLI Executable -burrito_link.exe: burrito_link.c linked_memory.h - $(WINECC) $< $(CFLAGS) -mconsole -o $@ - -# Remove all targets and generated files -clean: - rm -f burrito_link.exe From 80e80d66c0c95cb4d988ffdf4fe162598ac628f4 Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Sun, 5 Mar 2023 13:20:40 -0600 Subject: [PATCH 24/32] Removing artifact retention 7 day limit In theory the 7 day limit seemed economical, but in practice not having easy access to whatever the "newest" build artifact on master is has proven annoying. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6e8e9e73..b8c1605c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -119,4 +119,4 @@ jobs: # The desired behavior if no files are found using the provided path. if-no-files-found: error # Duration after which artifact will expire in days. 0 means using default retention. - retention-days: 7 + retention-days: 0 From edbffaa5792ee8be853e6a55ca6d0b59b570c2cc Mon Sep 17 00:00:00 2001 From: klingbolt Date: Thu, 24 Aug 2023 20:22:47 -0400 Subject: [PATCH 25/32] Shifted the burrito button to the right --- Spatial.tscn | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Spatial.tscn b/Spatial.tscn index 0267bb63..5ee74235 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -80,8 +80,6 @@ __meta__ = { [node name="TextureRect" type="TextureRect" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0.439216 ) -margin_left = 1.591 -margin_top = 3.18198 margin_right = 26.591 margin_bottom = 28.182 texture = ExtResource( 3 ) @@ -91,8 +89,12 @@ __meta__ = { [node name="main_menu_toggle" type="Button" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0 ) -margin_right = 27.0 -margin_bottom = 32.0 +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = 51.152 +margin_top = 8.0 +margin_right = 78.152 +margin_bottom = 40.0 __meta__ = { "_edit_use_anchors_": false } From 31ae8723f3da3eee25dbd705e954b7d6c61f7a4c Mon Sep 17 00:00:00 2001 From: klingbolt Date: Thu, 24 Aug 2023 21:17:00 -0400 Subject: [PATCH 26/32] Change so that the button should work --- Spatial.tscn | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Spatial.tscn b/Spatial.tscn index 5ee74235..129dcff9 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -71,17 +71,18 @@ scale = Vector2( 2, 2 ) [node name="Line2D" parent="Control/MiniMap" instance=ExtResource( 4 )] [node name="GlobalMenuButton" type="Control" parent="Control"] -margin_left = 287.348 -margin_right = 314.348 -margin_bottom = 32.0 +margin_left = 321.348 +margin_top = 4.0 +margin_right = 348.348 +margin_bottom = 36.0 __meta__ = { "_edit_use_anchors_": false } [node name="TextureRect" type="TextureRect" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0.439216 ) -margin_right = 26.591 -margin_bottom = 28.182 +margin_right = 29.0 +margin_bottom = 30.0 texture = ExtResource( 3 ) __meta__ = { "_edit_use_anchors_": false @@ -89,12 +90,8 @@ __meta__ = { [node name="main_menu_toggle" type="Button" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0 ) -anchor_left = 0.5 -anchor_right = 0.5 -margin_left = 51.152 -margin_top = 8.0 -margin_right = 78.152 -margin_bottom = 40.0 +margin_right = 29.0 +margin_bottom = 30.0 __meta__ = { "_edit_use_anchors_": false } @@ -630,8 +627,8 @@ __meta__ = { } [node name="GridContainer" type="GridContainer" parent="Control/Dialogs/SettingsDialog/ScrollContainer"] -margin_right = 384.002 -margin_bottom = 419.001 +margin_right = 384.0 +margin_bottom = 419.0 size_flags_horizontal = 3 size_flags_vertical = 3 columns = 2 From ad4798db7a6beb3a93771506285db0e713d393db Mon Sep 17 00:00:00 2001 From: klingbolt Date: Thu, 24 Aug 2023 21:32:13 -0400 Subject: [PATCH 27/32] Changed the pass through coordinates --- Spatial.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Spatial.gd b/Spatial.gd index fd3702c9..29914896 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -119,8 +119,8 @@ func exit_burrito(): func set_minimal_mouse_block(): - var top_corner := Vector2(287, 0) - var bottom_corner := Vector2(314, 32) + var top_corner := Vector2(321, 0) + var bottom_corner := Vector2(348, 32) if self.edit_panel_open: bottom_corner.y = 49 From 3479b6ae7cbf2afbd940439b71deb4c60e1b4d6a Mon Sep 17 00:00:00 2001 From: klingbolt Date: Fri, 25 Aug 2023 00:37:07 -0400 Subject: [PATCH 28/32] Changed numbers to be the properties the numbers were coming from --- Spatial.gd | 9 +++++---- Spatial.tscn | 11 ++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Spatial.gd b/Spatial.gd index 29914896..0c02c809 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -119,12 +119,13 @@ func exit_burrito(): func set_minimal_mouse_block(): - var top_corner := Vector2(321, 0) - var bottom_corner := Vector2(348, 32) + var menu_button = $Control/GlobalMenuButton + var top_corner = menu_button.get_position() + var bottom_corner = menu_button.get_position() + menu_button.get_size() if self.edit_panel_open: - bottom_corner.y = 49 - bottom_corner.x = 314+377 + var editor_panel = $Control/GlobalMenuButton/EditorQuckPanel + bottom_corner = menu_button.get_position() + editor_panel.get_position() + editor_panel.get_size() var clickthrough: PoolVector2Array = [ Vector2(top_corner.x ,top_corner.y), diff --git a/Spatial.tscn b/Spatial.tscn index 129dcff9..1af517a5 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -71,16 +71,16 @@ scale = Vector2( 2, 2 ) [node name="Line2D" parent="Control/MiniMap" instance=ExtResource( 4 )] [node name="GlobalMenuButton" type="Control" parent="Control"] -margin_left = 321.348 -margin_top = 4.0 -margin_right = 348.348 -margin_bottom = 36.0 +margin_left = 321.0 +margin_right = 348.0 +margin_bottom = 32.0 __meta__ = { "_edit_use_anchors_": false } [node name="TextureRect" type="TextureRect" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0.439216 ) +margin_top = 4.0 margin_right = 29.0 margin_bottom = 30.0 texture = ExtResource( 3 ) @@ -99,9 +99,6 @@ __meta__ = { [node name="EditorQuckPanel" type="PanelContainer" parent="Control/GlobalMenuButton"] visible = false margin_left = 32.0 -margin_top = -2.0 -margin_right = 306.0 -margin_bottom = 52.0 __meta__ = { "_edit_use_anchors_": false } From 2a2ae5aa1255c903b8dc6e42976642cbcfd4be0a Mon Sep 17 00:00:00 2001 From: klingbolt Date: Mon, 28 Aug 2023 20:50:53 -0400 Subject: [PATCH 29/32] Changed some numbers --- Spatial.tscn | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Spatial.tscn b/Spatial.tscn index 1af517a5..f1391ede 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -71,8 +71,8 @@ scale = Vector2( 2, 2 ) [node name="Line2D" parent="Control/MiniMap" instance=ExtResource( 4 )] [node name="GlobalMenuButton" type="Control" parent="Control"] -margin_left = 321.0 -margin_right = 348.0 +margin_left = 323.0 +margin_right = 349.0 margin_bottom = 32.0 __meta__ = { "_edit_use_anchors_": false @@ -81,8 +81,6 @@ __meta__ = { [node name="TextureRect" type="TextureRect" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0.439216 ) margin_top = 4.0 -margin_right = 29.0 -margin_bottom = 30.0 texture = ExtResource( 3 ) __meta__ = { "_edit_use_anchors_": false @@ -90,15 +88,17 @@ __meta__ = { [node name="main_menu_toggle" type="Button" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0 ) -margin_right = 29.0 -margin_bottom = 30.0 +margin_left = -2.0 +margin_right = 27.0 +margin_bottom = 32.0 __meta__ = { "_edit_use_anchors_": false } [node name="EditorQuckPanel" type="PanelContainer" parent="Control/GlobalMenuButton"] -visible = false margin_left = 32.0 +margin_right = 342.0 +margin_bottom = 54.0 __meta__ = { "_edit_use_anchors_": false } From 70a74464a456b000084e69bcde1e603cae5b006f Mon Sep 17 00:00:00 2001 From: klingbolt <89052698+klingbolt@users.noreply.github.com> Date: Tue, 19 Sep 2023 19:37:08 -0400 Subject: [PATCH 30/32] Update Spatial.tscn --- Spatial.tscn | 1 + 1 file changed, 1 insertion(+) diff --git a/Spatial.tscn b/Spatial.tscn index f1391ede..5d5554cf 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -96,6 +96,7 @@ __meta__ = { } [node name="EditorQuckPanel" type="PanelContainer" parent="Control/GlobalMenuButton"] +visible = false margin_left = 32.0 margin_right = 342.0 margin_bottom = 54.0 From c6df8e1a74f14f5ffa9be55222c02b808c0eb5a5 Mon Sep 17 00:00:00 2001 From: klingbolt Date: Tue, 19 Sep 2023 21:12:01 -0400 Subject: [PATCH 31/32] Changed margin for editor bar --- Spatial.tscn | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Spatial.tscn b/Spatial.tscn index f1391ede..48bb5307 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -81,6 +81,8 @@ __meta__ = { [node name="TextureRect" type="TextureRect" parent="Control/GlobalMenuButton"] modulate = Color( 1, 1, 1, 0.439216 ) margin_top = 4.0 +margin_right = 25.0 +margin_bottom = 29.0 texture = ExtResource( 3 ) __meta__ = { "_edit_use_anchors_": false @@ -97,8 +99,9 @@ __meta__ = { [node name="EditorQuckPanel" type="PanelContainer" parent="Control/GlobalMenuButton"] margin_left = 32.0 +margin_top = -2.0 margin_right = 342.0 -margin_bottom = 54.0 +margin_bottom = 52.0 __meta__ = { "_edit_use_anchors_": false } From 0a691a68e79dd792e4dad52f40fc613f90df919c Mon Sep 17 00:00:00 2001 From: Asher Glick Date: Tue, 19 Sep 2023 23:45:35 -0500 Subject: [PATCH 32/32] pinning docker build version --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b8c1605c..7a53084d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,7 @@ jobs: # This workflow contains a single job called "build" Build-Linux: # The type of runner that the job will run on - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 # Steps represent a sequence of tasks that will be executed as part of the job steps: