[Add] Process cd and ls commands.
This commit is contained in:
parent
92106a3c44
commit
dbe6e437ad
@ -66,8 +66,10 @@ std::string ClientNetwork::receive_response(void) {
|
|||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
void* socket_ptr = _socket;
|
void* socket_ptr = _socket;
|
||||||
|
/* Wait up to 2 seconds for data to be available. */
|
||||||
if(NET_WaitUntilInputAvailable(&socket_ptr, 1, 2000) > 0) {
|
if(NET_WaitUntilInputAvailable(&socket_ptr, 1, 2000) > 0) {
|
||||||
if(NET_ReadFromStreamSocket(_socket, buffer, sizeof(buffer)) > 0) {
|
int bytes_received = NET_ReadFromStreamSocket(_socket, buffer, sizeof(buffer)-1);
|
||||||
|
if(bytes_received > 0) {
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <sstream>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
@ -10,13 +11,14 @@
|
|||||||
Terminal::Terminal(void) {
|
Terminal::Terminal(void) {
|
||||||
/* Placeholder welcome message to history. */
|
/* Placeholder welcome message to history. */
|
||||||
_history.push_back("Welcome to Bettola");
|
_history.push_back("Welcome to Bettola");
|
||||||
_scroll_offset = 0;
|
|
||||||
_network = new ClientNetwork();
|
_network = new ClientNetwork();
|
||||||
if(_network->connect("localhost", 8080)) {
|
if(_network->connect("localhost", 8080)) {
|
||||||
_history.push_back("Connection to server Success!");
|
_history.push_back("Connection to server Success!");
|
||||||
} else {
|
} else {
|
||||||
_history.push_back("Connection to server failed!");
|
_history.push_back("Connection to server failed!");
|
||||||
}
|
}
|
||||||
|
_current_path = "/";
|
||||||
|
_scroll_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal::~Terminal(void) {
|
Terminal::~Terminal(void) {
|
||||||
@ -33,8 +35,16 @@ void Terminal::_on_ret_press(void) {
|
|||||||
printf("Command entered: %s\n", _input_buffer.c_str());
|
printf("Command entered: %s\n", _input_buffer.c_str());
|
||||||
_network->send_command(_input_buffer.c_str());
|
_network->send_command(_input_buffer.c_str());
|
||||||
std::string response = _network->receive_response();
|
std::string response = _network->receive_response();
|
||||||
if(!response.empty()) {
|
/* Check if the response is a new path for the prompt. */
|
||||||
_history.push_back(response);
|
if(response.rfind("/", 0) == 0 && response.find('\n') == std::string::npos) {
|
||||||
|
_current_path = response;
|
||||||
|
} else if(!response.empty()) {
|
||||||
|
/* Otherwise, it's command out. Split it by newline and add to history. */
|
||||||
|
std::stringstream ss(response);
|
||||||
|
std::string line;
|
||||||
|
while(std::getline(ss, line, '\n')) {
|
||||||
|
_history.push_back(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_input_buffer == "clear") {
|
if(_input_buffer == "clear") {
|
||||||
@ -106,7 +116,7 @@ void Terminal::render(TextRenderer* renderer, int x, int y, int width, int heigh
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw current input line. */
|
/* Draw current input line. */
|
||||||
std::string line_to_render = "> " + _input_buffer;
|
std::string line_to_render = _current_path + "> " + _input_buffer;
|
||||||
if(show_cursor) {
|
if(show_cursor) {
|
||||||
line_to_render += "_";
|
line_to_render += "_";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,5 +21,6 @@ private:
|
|||||||
std::string _input_buffer;
|
std::string _input_buffer;
|
||||||
std::vector<std::string> _history;
|
std::vector<std::string> _history;
|
||||||
int _scroll_offset;
|
int _scroll_offset;
|
||||||
|
std::string _current_path;
|
||||||
ClientNetwork* _network;
|
ClientNetwork* _network;
|
||||||
};
|
};
|
||||||
|
|||||||
11
common/src/vfs.cpp
Normal file
11
common/src/vfs.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
|
std::string get_full_path(vfs_node* node) {
|
||||||
|
if(node->parent == nullptr) {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
if(node->parent->parent == nullptr) { /* If parent is root. */
|
||||||
|
return "/" + node->name;
|
||||||
|
}
|
||||||
|
return get_full_path(node->parent) + "/" + node->name;
|
||||||
|
}
|
||||||
@ -24,3 +24,5 @@ struct vfs_node {
|
|||||||
vfs_child_map children;
|
vfs_child_map children;
|
||||||
vfs_node* parent;
|
vfs_node* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string get_full_path(vfs_node* node);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "SDL_net.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
|
||||||
#include "network_manager.h"
|
#include "network_manager.h"
|
||||||
@ -72,8 +73,37 @@ void NetworkManager::_handle_client_activity(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::_process_command(Player* player, char* command) {
|
void NetworkManager::_process_command(Player* player, char* command) {
|
||||||
/* We'll just do 'ls' for now. */
|
/* Remove trailing newline for command comparison. */
|
||||||
if(strncmp(command, "ls", 2) == 0) {
|
std::string cmd_str = command;
|
||||||
|
if(!cmd_str.empty() && cmd_str.back() == '\n') {
|
||||||
|
cmd_str.pop_back();
|
||||||
|
}
|
||||||
|
if(strncmp(command, "cd ", 3) == 0) {
|
||||||
|
/* Handle 'cd' command. */
|
||||||
|
std::string target_dir_name = command + 3;
|
||||||
|
/* Remove trailing newline if it exists. */
|
||||||
|
if(!target_dir_name.empty() && target_dir_name.back() == '\n') {
|
||||||
|
target_dir_name.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(target_dir_name == "..") {
|
||||||
|
if(player->current_dir->parent) {
|
||||||
|
player->current_dir = player->current_dir->parent;
|
||||||
|
}
|
||||||
|
} else if(player->current_dir->children.count(target_dir_name)) {
|
||||||
|
vfs_node* target_node = player->current_dir->children[target_dir_name];
|
||||||
|
if(target_node->type == DIR_NODE) {
|
||||||
|
player->current_dir = target_node;
|
||||||
|
} else {
|
||||||
|
/* It's a file, not a directory. */
|
||||||
|
NET_WriteToStreamSocket(player->socket, "cd: not a directory\n", 22);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* On successful cd, send back the new path for the prompt. */
|
||||||
|
std::string new_path = get_full_path(player->current_dir);
|
||||||
|
NET_WriteToStreamSocket(player->socket, new_path.c_str(), new_path.length()+1);
|
||||||
|
} else if(cmd_str == "ls") {
|
||||||
std::string response = "";
|
std::string response = "";
|
||||||
if(player->current_dir && player->current_dir->type == DIR_NODE) {
|
if(player->current_dir && player->current_dir->type == DIR_NODE) {
|
||||||
for(auto const& [name, node] : player->current_dir->children) {
|
for(auto const& [name, node] : player->current_dir->children) {
|
||||||
@ -81,11 +111,18 @@ void NetworkManager::_process_command(Player* player, char* command) {
|
|||||||
if(node->type == DIR_NODE) {
|
if(node->type == DIR_NODE) {
|
||||||
response += "/";
|
response += "/";
|
||||||
}
|
}
|
||||||
response += "\n";
|
response += " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NET_WriteToStreamSocket is essentially the new send function in SDL3. */
|
/* NET_WriteToStreamSocket is essentially the new send function in SDL3. */
|
||||||
NET_WriteToStreamSocket(player->socket, response.c_str(), response.length()+1);
|
NET_WriteToStreamSocket(player->socket, response.c_str(), response.length()+1);
|
||||||
|
} else if(cmd_str == "clear") {
|
||||||
|
/* Send an empty reply to unblock. */
|
||||||
|
NET_WriteToStreamSocket(player->socket, "", 1);
|
||||||
|
} else {
|
||||||
|
/* Unknown command. */
|
||||||
|
std::string response = "Unknown command: " + cmd_str + "\n";
|
||||||
|
NET_WriteToStreamSocket(player->socket, response.c_str(), response.length()+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user