Raised This Month: $32 Target: $400
 8% 

Call ServerCommand and get the result


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
maitredede
Senior Member
Join Date: May 2005
Old 03-25-2015 , 19:23   Call ServerCommand and get the result
Reply With Quote #1

Hi,

I would like to execute a command using engine->ServerCommand(), but how can I get the result ?

For example, execute "status" and store result inside a char*...
(status or any other command)
__________________
make brain && make install
maitredede is offline
rcbotCheeseh
Junior Member
Join Date: May 2013
Old 03-25-2015 , 20:33   Re: Call ServerCommand and get the result
Reply With Quote #2

this is a bit of a long shot, not sure if it will work for servers -- maybe only clients

there may be numerous calls to messagebegin after a servercommand, or there may be none, this code expects one only. You can catch different msg_types such as HudText, or whatever.

Code:
#include "irecipientfilter.h"
SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write*, IRecipientFilter*, int);
SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0);
bf_write *current_msg = NULL;
#define BUF_SIZ 1024
char current_msg_buffer[BUF_SIZ];
// ---
///plugin::load()
//{
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &MyPlugin::Hook_MessageBegin, true);
SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &MyPlugin::Hook_MessageEnd, true);
//}
// --- you're going to take over message begin
bf_write *MyPlugin::Hook_MessageBegin ( IRecipientFilter *filter, int msg_type )
{
// grab the message that will be used for the console
current_msg = SH_CALL(engine, &IVEngineServer::UserMessageBegin)(filter,msg_type);
current_msg_buffer[0] = 0;
RETURN_META_VALUE(MRES_SUPERCEDE,current_msg);
}
void MyPlugin::Hook_MessageEnd ()
{
  // probe the current_msg m_pData
  // deep copy the data because it might free itself later
  strncpy(current_msg_buffer,current_msg->m_pData,BUF_SIZ-1);
  current_msg_buffer[BUF_SIZ-1] = 0;
  current_msg = NULL;
}
// my plugin
// {
engine->ServerCommand("status");
if ( current_msg_buffer[0] != 0 )
{
  // The console stuff should be in current_msg_buffer
}
// }


if it doesn't work, your next best best would be
\public\vgui_controls\consoledialog.h

Code:
class CConsolePanel : public vgui::EditablePanel, public IConsoleDisplayFunc
{

// Inherited from IConsoleDisplayFunc

virtual void ColorPrint( const Color& clr, const char *pMessage );

virtual void Print( const char *pMessage );
virtual void DPrint( const char *pMessage );



__________________

Last edited by rcbotCheeseh; 03-29-2015 at 21:10.
rcbotCheeseh is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 03-25-2015 , 21:19   Re: Call ServerCommand and get the result
Reply With Quote #3

SourceMod's method is quite a bit saner.

If you're doing async stuff, you can also process inside sm_conhook_stop (remember to rename them) rather than requiring the ServerExecute calls.

Remember the SourceMod license before you even read this though, let alone copy it into your plugin if it isn't also GPL-licensed.
__________________

Last edited by asherkin; 03-25-2015 at 21:21.
asherkin is offline
maitredede
Senior Member
Join Date: May 2005
Old 03-26-2015 , 12:32   Re: Call ServerCommand and get the result
Reply With Quote #4

Hi,
Thanks for replying.

By reading your answers, "there is no easy way"... I will try to make something and post it if it worth it, when I need it.
__________________
make brain && make install
maitredede is offline
maitredede
Senior Member
Join Date: May 2005
Old 04-01-2015 , 10:05   Re: Call ServerCommand and get the result
Reply With Quote #5

Hi again,

The IConsoleDisplayFunc way does nothing : is seams that it is not called during command execution so :
Code:
	engine->ServerExecute();
        icvar->InstallConsoleDisplayFunc(conDispFunc);
	engine->ServerCommand(cmdWithNewLine);
	engine->ServerExecute();
	icvar->RemoveConsoleDisplayFunc(conDispFunc);
ConsoleDisplayFunc buffer remains empty.

I have used a slightly modified version of the SourceMod's method :
Code:
class LoggingListener :public ILoggingListener
{
public:
	LoggingListener();
	~LoggingListener();

	void Log(const LoggingContext_t *pContext, const tchar *pMessage);
	void Dump(char** dest, int* size);
private:
	struct Node {
		char* str;
		Node *next;
	};
	Node* pBuffer;
	size_t iBufferLen;
	void Append(const char* pMessage);
};

LoggingListener::LoggingListener()
{
	this->pBuffer = NULL;
	this->iBufferLen = 0;
}
LoggingListener::~LoggingListener()
{
	while (this->pBuffer){
		Node* next = this->pBuffer->next;
		delete this->pBuffer->str;
		delete this->pBuffer;
		this->pBuffer = next;
	}
}

void LoggingListener::Log(const LoggingContext_t *pContext, const tchar *pMessage)
{
	size_t msgLen = strlen(pMessage);
	size_t buffLen = msgLen + 1;
	if (this->pBuffer){
		Node* last = this->pBuffer;
		while (last->next){
			last = last->next;
		}
		last->next = new Node();
		last->next->next = NULL;
		last->next->str = new char[buffLen];
		ZeroMemory(last->next->str, buffLen);
		strcpy_s(last->next->str, buffLen, pMessage);
	}
	else{
		this->pBuffer = new Node();
		this->pBuffer->next = NULL;
		this->pBuffer->str = new char[buffLen];
		ZeroMemory(this->pBuffer->str, buffLen);
		strcpy_s(this->pBuffer->str, buffLen, pMessage);
	}
	this->iBufferLen += msgLen;
}

void LoggingListener::Dump(char** dest, int* size)
{
	size_t bufLen = this->iBufferLen + 1;
	char* buffer = new char[bufLen];
	ZeroMemory(buffer, bufLen);

	Node* pNode = this->pBuffer;
	while (pNode){
		strcat_s(buffer, bufLen, pNode->str);
		pNode = pNode->next;
	}

	*dest = buffer;
	*size = this->iBufferLen;
}
And usage :
Code:
LoggingListener vLog;

	engine->ServerExecute();
	LoggingSystem_PushLoggingState(false, false);
	LoggingSystem_RegisterLoggingListener(&vLog);
	engine->ServerCommand(cmdWithNewLine);
	engine->ServerExecute();
	LoggingSystem_PopLoggingState(false);
__________________
make brain && make install
maitredede is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 22:13.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode