Compare commits

...

3 Commits

Author SHA1 Message Date
52f8034f4e Rudimentary support for IPv6 in server socket creation
I haven't completely implemented it yet, but I did come up with a basic algorithm
to convert the IPv6 address into a 'code' form. I still have to write the code to
actually create the socket, though.
2024-03-09 19:32:45 -05:00
8758060bfb Updated TODO 2024-03-09 19:32:03 -05:00
10f91fafd4 Updated README 2024-03-09 19:31:51 -05:00
4 changed files with 78 additions and 12 deletions

View File

@@ -9,7 +9,7 @@ The game has only one runtime dependency: The [raylib](https://www.raylib.com/)
## Building ## Building
This application uses [Meson](https://mesonbuild.com/) as a build system. To build the application: This application uses [Meson](https://mesonbuild.com/) as a build system. To build the application:
1. Install __meson__ from the link above. 1. Install meson from the link above.
2. Set up the build directory. 2. Set up the build directory.
``` ```
meson setup build meson setup build

View File

@@ -30,7 +30,7 @@ GameType check_server(char* ip_text, char* port_text) {
std::string code = connect_code::encode(addr, std::to_string(port)); std::string code = connect_code::encode(addr, std::to_string(port));
/* Create server socket and wait for client to connect */ /* Create server socket and wait for client to connect */
Server* server = new Server(4, ES_UDP, addr.data(), port); Server* server = new Server(check_ip_ver(addr.data()), ES_UDP, addr.data(), port);
server->create_socket(); server->create_socket();
display_text_centered("Your code is " + code + "\nWaiting for connection..."); display_text_centered("Your code is " + code + "\nWaiting for connection...");
std::string response = ""; std::string response = "";

View File

@@ -1,3 +1,4 @@
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <iomanip> #include <iomanip>
@@ -5,6 +6,15 @@
#include <cstdint> #include <cstdint>
#include "includes/connect_code.hpp" #include "includes/connect_code.hpp"
#include "includes/numeric_base.hpp" #include "includes/numeric_base.hpp"
#include "includes/easysock.h"
#if defined(_WIN32)
#include <In6addr.h>
#include <Ws2tcpip.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif
namespace connect_code { namespace connect_code {
@@ -44,13 +54,67 @@ namespace connect_code {
uint32_t addr_val = (std::stoul(octets[0]) << 24) + (std::stoul(octets[1]) << 16) + (std::stoul(octets[2]) << 8) + (std::stoul(octets[3])); uint32_t addr_val = (std::stoul(octets[0]) << 24) + (std::stoul(octets[1]) << 16) + (std::stoul(octets[2]) << 8) + (std::stoul(octets[3]));
return std::to_string(addr_val); return std::to_string(addr_val);
} }
/* Expand an IPv6 address (expand '::' into ':0000:', for example).
This is done by first converting the address into a binary representation,
and then printing every character of the binary representation into a string. */
std::string expand_ip6_addr(std::string addr) {
char ip6_string[40]; // 32 characters + 7 colons
struct in6_addr* ip6_s_ptr = (struct in6_addr *)malloc(sizeof(in6_addr)); // Struct pointer, to store the binary representation of the address
inet_pton(AF_INET6, addr.data(), ip6_s_ptr); // Convert the string representation into a binary form
/* This abomination, converts the binary representation into a string.
It uses sprintf to print every byte in the binary representation into a string.
The bytes are formatted as 2-character hexadecimal values. */
sprintf(ip6_string,
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
ip6_s_ptr->s6_addr[0], ip6_s_ptr->s6_addr[1],
ip6_s_ptr->s6_addr[2], ip6_s_ptr->s6_addr[3],
ip6_s_ptr->s6_addr[4], ip6_s_ptr->s6_addr[5],
ip6_s_ptr->s6_addr[6], ip6_s_ptr->s6_addr[7],
ip6_s_ptr->s6_addr[8], ip6_s_ptr->s6_addr[9],
ip6_s_ptr->s6_addr[10], ip6_s_ptr->s6_addr[11],
ip6_s_ptr->s6_addr[12], ip6_s_ptr->s6_addr[13],
ip6_s_ptr->s6_addr[14], ip6_s_ptr->s6_addr[15]);
return std::string(ip6_string);
}
std::string encode(std::string address, std::string port) { std::string encode(std::string address, std::string port) {
std::string addr_coded;
/* Convert the address to decimal, and convert that to hex */ /* Convert the address to decimal, and convert that to hex */
std::string addr_coded = dotted_dec_to_dec(address); if (check_ip_ver(address.data()) == 4) {
addr_coded = base_convert(addr_coded, 10, 32); /* I don't really have a reason to use my own function (dotted_dec_to_dec()
and dec_to_dotted_dec()), to convert the IP address from text to binary.
The inet_pton() and inet_ntop() functions can do this just fine, and also
take care of edge cases. Maybe someday, I might change this code. I could probably
repurpose the functions for something else, though. */
/* First, convert the address into a 32-bit integer (the integer is stored as a string).
Then, convert the address into base-32. */
addr_coded = dotted_dec_to_dec(address);
addr_coded = base_convert(addr_coded, 10, 32);
}
if (check_ip_ver(address.data()) == 6) {
/* First, expand the address into the full 39-character format (32 hex values + 7 colons).
Then, tokenize the string, using colons as the delimiters.
Finally, take each token in the string, and convert it from base-16 to base-32, appending a '-' as a delimiter. */
std::string addr_expanded = expand_ip6_addr(address);
std::string addr_coded = "";
std::vector<std::string> addr_tokenized = tokenize_str(addr_expanded, ":");
for (int i = 0; i < addr_tokenized.size(); i++ ) {
addr_coded += base_convert(addr_tokenized[i], 16, 32);
addr_coded += "-";
}
/* TODO - Check if the IP address is actually converted properly, and test if the server socket is created correctly.
Also do the same for client side, and check client-server connection. */
std::cout << addr_coded << std::endl;
abort();
}
/* Convert the port to hex */ /* Convert the port to hex */
std::string port_coded = base_convert(port, 10, 32); std::string port_coded = base_convert(port, 10, 32);
std::string ret_val = addr_coded + "_" + port_coded; std::string ret_val = addr_coded + "_" + port_coded;

View File

@@ -1,10 +1,12 @@
1. Try to make the ball go between screens. 1. Try to make the ball go between screens.
2. ----SHOULD BE DONE---- Add code to zip the dist/ folder inside the release_build script. 2. ----SHOULD BE DONE---- Add code to zip the dist/ folder inside the release_build script.
3. Sign Windows executable, to remove 'Unknown Publisher' warnings. 3. Sign Windows executable, to remove 'Unknown Publisher' warnings.
5. Create and publish statically-linked Linux binary, and create a build script for packaging it. 4. Create and publish statically-linked Linux binary, and create a build script for packaging it.
6. Figure out how to build statically-linked Mac binary, and create a build script for packaging it. 5. Figure out how to build statically-linked Mac binary, and create a build script for packaging it.
7. ----IN PROGRESS---- Figure out how to input game mode and (if applicable) IP address and port through the GUI, instead of the command-line. 6. ----IN PROGRESS---- Figure out how to input game mode and (if applicable) IP address and port through the GUI, instead of the command-line.
8. Clean up / refactor the raygui code in main.cpp, that asks user for game mode. Instead of just having a giant blob of code in main.cpp, maybe split it into a function, or move it to another file. It should be easy to split it into a different function, since none of the functions take any specific parameters. The text box function, for example, only takes in the rectangle coordinates, and the text to display. I can move the code to a function, and then pass in any parameters that I need to pass in (I don't think I need to pass many parameters, though). 7. Clean up / refactor the raygui code in main.cpp, that asks user for game mode. Instead of just having a giant blob of code in main.cpp, maybe split it into a function, or move it to another file. It should be easy to split it into a different function, since none of the functions take any specific parameters. The text box function, for example, only takes in the rectangle coordinates, and the text to display. I can move the code to a function, and then pass in any parameters that I need to pass in (I don't think I need to pass many parameters, though).
9. Allow the user to quit before the game actually starts i.e. while they are inputting the game mode. 8. Allow the user to quit before the game actually starts i.e. while they are inputting the game mode.
11. Add better error checking in check_server and check_client functions in check_input.cpp. 9. Add better error checking in check_server and check_client functions in check_input.cpp.
12. Add 'install' target to Meson, to allow the user to install the game. This should also copy the .so files to the right locations. 10. Add 'install' target to Meson, to allow the user to install the game. This should also copy the .so files to the right locations.
11. Allow the user to specify which paddle they want to control, in multi-player mode.
12. Add IPv6 support for the server and client sockets (and everything that goes along with it, such as error handling for IP addresses).