[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));
 | 
			
		||||
 | 
			
		||||
  void* socket_ptr = _socket;
 | 
			
		||||
  /* Wait up to 2 seconds for data to be available. */
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <SDL3/SDL.h>
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
#include <SDL3/SDL_events.h>
 | 
			
		||||
@ -10,13 +11,14 @@
 | 
			
		||||
Terminal::Terminal(void) {
 | 
			
		||||
  /* Placeholder welcome message to history. */
 | 
			
		||||
  _history.push_back("Welcome to Bettola");
 | 
			
		||||
  _scroll_offset = 0;
 | 
			
		||||
  _network = new ClientNetwork();
 | 
			
		||||
  if(_network->connect("localhost", 8080)) {
 | 
			
		||||
    _history.push_back("Connection to server Success!");
 | 
			
		||||
  } else {
 | 
			
		||||
    _history.push_back("Connection to server failed!");
 | 
			
		||||
  }
 | 
			
		||||
  _current_path = "/";
 | 
			
		||||
  _scroll_offset = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Terminal::~Terminal(void) {
 | 
			
		||||
@ -33,8 +35,16 @@ void Terminal::_on_ret_press(void) {
 | 
			
		||||
  printf("Command entered: %s\n", _input_buffer.c_str());
 | 
			
		||||
  _network->send_command(_input_buffer.c_str());
 | 
			
		||||
  std::string response = _network->receive_response();
 | 
			
		||||
  if(!response.empty()) {
 | 
			
		||||
    _history.push_back(response);
 | 
			
		||||
  /* Check if the response is a new path for the prompt. */
 | 
			
		||||
  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") {
 | 
			
		||||
@ -106,7 +116,7 @@ void Terminal::render(TextRenderer* renderer, int x, int y, int width, int heigh
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Draw current input line. */
 | 
			
		||||
  std::string line_to_render = "> " + _input_buffer;
 | 
			
		||||
  std::string line_to_render = _current_path + "> " + _input_buffer;
 | 
			
		||||
  if(show_cursor) {
 | 
			
		||||
    line_to_render += "_";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -21,5 +21,6 @@ private:
 | 
			
		||||
  std::string _input_buffer;
 | 
			
		||||
  std::vector<std::string> _history;
 | 
			
		||||
  int _scroll_offset;
 | 
			
		||||
  std::string _current_path;
 | 
			
		||||
  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_node* parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::string get_full_path(vfs_node* node);
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include "SDL_net.h"
 | 
			
		||||
#include "vfs.h"
 | 
			
		||||
 | 
			
		||||
#include "network_manager.h"
 | 
			
		||||
@ -72,8 +73,37 @@ void NetworkManager::_handle_client_activity(void) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NetworkManager::_process_command(Player* player, char* command) {
 | 
			
		||||
  /* We'll just do 'ls' for now. */
 | 
			
		||||
  if(strncmp(command, "ls", 2) == 0) {
 | 
			
		||||
  /* Remove trailing newline for command comparison. */
 | 
			
		||||
  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 = "";
 | 
			
		||||
    if(player->current_dir && player->current_dir->type == DIR_NODE) {
 | 
			
		||||
      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) {
 | 
			
		||||
          response += "/";
 | 
			
		||||
        }
 | 
			
		||||
        response += "\n";
 | 
			
		||||
        response += "  ";
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    /* NET_WriteToStreamSocket is essentially the new send function in SDL3. */
 | 
			
		||||
    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