Files
Leviathan/Client/Game/game/Console/ConsoleHelper.cpp
T
2026-06-01 12:46:52 +02:00

250 lines
5.4 KiB
C++

/*
ConsoleHepler.h
Console처리용 helper object
Created 2005/06, by JiYoung
*/
//=============================================
// Console helper
//=============================================
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
#include <string>
#include "ConsoleHelper.h"
bool ConsoleHelper::CollectCommandOutput(char *outputBuffer, const char **commandList)
{
assert(outputBuffer!=NULL && commandList!=NULL);
std::string _key;
std::vector<std::string> arg;
const char **c=commandList;
char lineBuf[1024];
char lineBuf2[1024];
outputBuffer[0]=0;
while (*c!=NULL) {
_key=*(c++);
processConsoleCommand(_key, (int)arg.size(), arg, lineBuf);
if (lineBuf[0]!=0) {
sprintf(lineBuf2, "%s %s\n", _key.c_str(), lineBuf); // Key와 result를 join
strcat(outputBuffer, lineBuf2);
}
}
return true;
}
bool ConsoleHelper::loadFromFile(const char *filename) // File을 load해서 setupByConfigurationText()을 부른다
{
int f=::_open(filename, _O_RDONLY | _O_TEXT, _S_IREAD | _S_IWRITE);
if (f==-1) return false;
long filesize=_lseek(f, 0, SEEK_END);
_lseek(f, 0, SEEK_SET);
char *text=new char[filesize*2];
int n=::_read(f, text, filesize*2);
text[n]=0;
bool b=setupByConfigurationText(text);
delete [] text;
::_close(f);
return b;
}
bool ConsoleHelper::saveToFile(const char *filename) // buildConfigurationText()를 부른 다음 결과를 file save한다
{
int f=::_open(filename, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_TEXT, _S_IREAD | _S_IWRITE);
if (f==-1) return false;
const int BUFFERSIZE=16384;
char *buffer=new char [BUFFERSIZE];
buildConfigurationText(buffer);
if (strlen(buffer) > BUFFERSIZE-1) {
// BUFFER OVERFLOW : INCREASE BUFFER SIZE (..........)
assert(0);
}
::_write(f, buffer, (unsigned int)strlen(buffer));
::_close(f);
delete [] buffer;
return true;
}
namespace {
size_t getLine(const char *str) { // str부터 scan해서 한 라인이 끝나는 char수를 센다. \r\n포함
size_t l=0;
while ( (*str!=0)&&(*str!='\r')&&(*str!='\n') ) { str++; l++; }
while ((*str=='\r')||(*str=='\n') ) { str++; l++; }
return l;
}
size_t stripLine(const char *str, int *startPos) // str부터 scan해서, strip된 line의 start pos와 length를 돌려준다
{
// 앞에서 strip
(*startPos)=0;
while ((*str==' ')||(*str=='\t')||(*str=='\r')||(*str=='\n')) {
str++;
(*startPos)++;
}
// 뒤에서 strip
size_t len=strlen(str);
const char *pEnd=str+len-1;
while ( ((*pEnd==' ')||(*pEnd=='\t')||(*pEnd=='\r')||(*pEnd=='\n')) && (len>0) ) {
pEnd--;
len--;
}
return len;
}
}
bool ConsoleHelper::setupByConfigurationText(const char *configText)
{
// strtok를 사용하기 위해 버퍼 카피
size_t len=strlen(configText);
if (len==0) return false;
char *buffer=new char[len+1];
memcpy(buffer, configText, len);
buffer[len]=0;
const int LINESIZE=512;
char line[512];
char *linep=buffer;
char *cmdp;
char *argp;
char dummyOutputBuffer[1024];
// Get a line
int strippedPos;
size_t lineLength;
int n, m;
std::string _key;
std::string _param;
std::vector<std::string> arg;
while (*linep!=0) {
// Get a line
lineLength=getLine(linep);
assert(lineLength < LINESIZE);
strncpy(line, linep, lineLength);
line[lineLength]=0;
linep+=lineLength; // Go to next line
// Strip line
lineLength=stripLine(line, &strippedPos);
cmdp=line+strippedPos;
if (lineLength==0) continue;
cmdp[lineLength]=0;
// Remove comment
n=(int)strcspn(cmdp, "!#"); // ! 이나 #으로 시작하면 커멘트 라인
cmdp[n]=0; // 커멘트 이후 삭제
lineLength=n;
// Parse command
n=(int)strcspn(cmdp, " \t\r\n");
if (n==0) continue;
cmdp[n]=0; // Save key
_key=cmdp;
n++;
arg.clear();
while (n < (int)lineLength) {
// Skip whitespaces
m = (int)strspn(cmdp+n, " \t\r\n");
argp=cmdp+n+m;
n+=m;
// Find end-of-arg
m = (int)strcspn(argp, " \t\r\n");
n+=m;
if (m!=0) {
// Add argument
argp[m]=0;
_param=argp;
arg.push_back(_param);
n++;
}
}
// Call processor
processConsoleCommand(_key, (int)arg.size(), arg, dummyOutputBuffer);
}
return true;
}
/*
bool ConsoleHelper::buildConfigurationText(char *outputBuffer)
// Status를 읽어서 config file을 build한다.
// outputBuffer: config file을 홀드할 '충분히 큰' 버퍼
{
// EXAMPLE!!!
const char *commandList[] = { // Config file에 write할 커맨드 목록을 여기 적는다
"wttexture"
, "wtwidth"
, "wtlength"
, "wt00color0"
, "wt00color1"
, "wt00u"
, "wt00v"
, "wt01color0"
, "wt01color1"
, "wt01u"
, "wt01v"
, "wt10color0"
, "wt10color1"
, "wt10u"
, "wt10v"
, "wt11color0"
, "wt11color1"
, "wt11u"
, "wt11v"
, NULL // EOL
};
return CollectCommandOutput(outputBuffer, commandList); // 여기서 그 결과를 gather해서 outputBuffer를 만든다
}
*/
//#define KEY(str) if (
#define PRINTKEY_INT(buf, intv) { sprintf(buf, "%d", intv); }
#define PRINTKEY_FLOAT(buf, floatv) { sprintf(buf, "%f", floatv); }
#define PRINT_COLOR(buf, intv) { sprintf(buf, "0x%08x", intv);}
#define PRINT_HEX(buf, intv) { sprintf(buf, "0x%x", intv); }
/*
void ConsoleHelper::processConsoleCommand(std::string &key, int argc, std::vector<std::string> &argv, char *outputBuffer)
// Game console에서 들어온 파라미터를 redirect한다
// outputBuffer : 처리 결과를 sprintf()할 텍스트 버퍼. 여기 들어가는 결과가 콘솔 화면에 출력된다
{
}
*/