/*
-Copyright (C) 1999-2007 id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+ Copyright (C) 1999-2007 id Software, Inc. and contributors.
+ For a list of contributors, see the accompanying CONTRIBUTORS file.
-This file is part of GtkRadiant.
+ This file is part of GtkRadiant.
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ GtkRadiant is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GtkRadiant is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ You should have received a copy of the GNU General Public License
+ along with GtkRadiant; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
//-----------------------------------------------------------------------------
//
//
// DESCRIPTION:
// deal with in/out tasks, for either stdin/stdout or network/XML stream
-//
+//
+#include "globaldefs.h"
#include "cmdlib.h"
#include "mathlib.h"
#include "polylib.h"
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef WIN32
+#if GDEF_OS_WINDOWS
#include <direct.h>
#include <windows.h>
#endif
#include "libxml/tree.h"
// utf8 conversion
-#include <glib/gconvert.h>
-#include <glib/gmem.h>
+#include <glib.h>
-#ifdef WIN32
+#if GDEF_OS_WINDOWS
HWND hwndOut = NULL;
qboolean lookedForServer = qfalse;
UINT wm_BroadcastCommand = -1;
xmlNodePtr tree;
// some useful stuff
-xmlNodePtr xml_NodeForVec( vec3_t v )
-{
- xmlNodePtr ret;
- char buf[1024];
-
- sprintf (buf, "%f %f %f", v[0], v[1], v[2]);
- ret = xmlNewNode (NULL, "point");
- xmlNodeSetContent (ret, buf);
- return ret;
+xmlNodePtr xml_NodeForVec( vec3_t v ){
+ xmlNodePtr ret;
+ char buf[1024];
+
+ sprintf( buf, "%f %f %f", v[0], v[1], v[2] );
+ ret = xmlNewNode( NULL, (xmlChar*)"point" );
+ xmlNodeSetContent( ret, (xmlChar*)buf );
+ return ret;
}
// send a node down the stream, add it to the document
-void xml_SendNode (xmlNodePtr node)
-{
- xmlBufferPtr xml_buf;
- char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
- // this index loops through the node buffer
- int pos = 0;
- int size;
-
- xmlAddChild( doc->children, node );
-
- if (brdcst_socket)
- {
- xml_buf = xmlBufferCreate();
- xmlNodeDump( xml_buf, doc, node, 0, 0 );
-
- // the XML node might be too big to fit in a single network message
- // l_net library defines an upper limit of MAX_NETMESSAGE
- // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
- // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
- while (pos < xml_buf->use)
- {
- // what size are we gonna send now?
- (xml_buf->use - pos < MAX_NETMESSAGE - 10) ? (size = xml_buf->use - pos) : (size = MAX_NETMESSAGE - 10);
- //++timo just a debug thing
- if (size == MAX_NETMESSAGE - 10)
- Sys_FPrintf (SYS_NOXML, "Got to split the buffer\n");
- memcpy( xmlbuf, xml_buf->content+pos, size);
- xmlbuf[size] = '\0';
- NMSG_Clear( &msg );
- NMSG_WriteString (&msg, xmlbuf );
- Net_Send(brdcst_socket, &msg );
- // now that the thing is sent prepare to loop again
- pos += size;
- }
+void xml_SendNode( xmlNodePtr node ){
+ xmlBufferPtr xml_buf;
+ char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
+ // this index loops through the node buffer
+ int pos = 0;
+ int size;
+
+ xmlAddChild( doc->children, node );
+
+ if ( brdcst_socket ) {
+ xml_buf = xmlBufferCreate();
+ xmlNodeDump( xml_buf, doc, node, 0, 0 );
+
+ // the XML node might be too big to fit in a single network message
+ // l_net library defines an upper limit of MAX_NETMESSAGE
+ // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
+ // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
+ while ( pos < (int)xml_buf->use )
+ {
+ // what size are we gonna send now?
+ ( xml_buf->use - pos < MAX_NETMESSAGE - 10 ) ? ( size = xml_buf->use - pos ) : ( size = MAX_NETMESSAGE - 10 );
+ //++timo just a debug thing
+ if ( size == MAX_NETMESSAGE - 10 ) {
+ Sys_FPrintf( SYS_NOXML, "Got to split the buffer\n" );
+ }
+ memcpy( xmlbuf, xml_buf->content + pos, size );
+ xmlbuf[size] = '\0';
+ NMSG_Clear( &msg );
+ NMSG_WriteString( &msg, xmlbuf );
+ Net_Send( brdcst_socket, &msg );
+ // now that the thing is sent prepare to loop again
+ pos += size;
+ }
#if 0
- // NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
- // we will need to split into chunks
- // (we could also go lower level, in the end it's using send and receiv which are not size limited)
- //++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
- // there's some tweaking to do in l_net for that .. so let's give us a margin for now
-
- //++timo we need to handle the case of a buffer too big to fit in a single message
- // try without checks for now
- if (xml_buf->use > MAX_NETMESSAGE-10 )
- {
- // if we send that we are probably gonna break the stream at the other end..
- // and Error will call right there
- //Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
- Sys_FPrintf (SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
- xml_buf->content[xml_buf->use]='\0'; //++timo this corrupts the buffer but we don't care it's for printing
- Sys_FPrintf (SYS_NOXML, xml_buf->content);
-
- }
-
- size = xml_buf->use;
- memcpy( xmlbuf, xml_buf->content, size );
- xmlbuf[size] = '\0';
- NMSG_Clear( &msg );
- NMSG_WriteString (&msg, xmlbuf );
- Net_Send(brdcst_socket, &msg );
+ // NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
+ // we will need to split into chunks
+ // (we could also go lower level, in the end it's using send and receiv which are not size limited)
+ //++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
+ // there's some tweaking to do in l_net for that .. so let's give us a margin for now
+
+ //++timo we need to handle the case of a buffer too big to fit in a single message
+ // try without checks for now
+ if ( xml_buf->use > MAX_NETMESSAGE - 10 ) {
+ // if we send that we are probably gonna break the stream at the other end..
+ // and Error will call right there
+ //Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
+ Sys_FPrintf( SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use );
+ xml_buf->content[xml_buf->use] = '\0'; //++timo this corrupts the buffer but we don't care it's for printing
+ Sys_FPrintf( SYS_NOXML, xml_buf->content );
+
+ }
+
+ size = xml_buf->use;
+ memcpy( xmlbuf, xml_buf->content, size );
+ xmlbuf[size] = '\0';
+ NMSG_Clear( &msg );
+ NMSG_WriteString( &msg, xmlbuf );
+ Net_Send( brdcst_socket, &msg );
#endif
- xmlBufferFree( xml_buf );
- }
+ xmlBufferFree( xml_buf );
+ }
}
-void xml_Select (char *msg, int entitynum, int brushnum, qboolean bError)
-{
- xmlNodePtr node, select;
- char buf[1024];
- char level[2];
-
- // now build a proper "select" XML node
- sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg);
- node = xmlNewNode (NULL, "select");
- xmlNodeSetContent (node, buf);
- level[0] = (int)'0' + (bError ? SYS_ERR : SYS_WRN) ;
- level[1] = 0;
- xmlSetProp (node, "level", (char *)&level);
- // a 'select' information
- sprintf (buf, "%i %i", entitynum, brushnum);
- select = xmlNewNode (NULL, "brush");
- xmlNodeSetContent (select, buf);
- xmlAddChild (node, select);
- xml_SendNode (node);
-
- sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg);
- if (bError)
- Error(buf);
- else
- Sys_FPrintf (SYS_NOXML, "%s\n", buf);
+void xml_Select( char *msg, int entitynum, int brushnum, qboolean bError ){
+ xmlNodePtr node, select;
+ char buf[1024];
+ char level[2];
+
+ // now build a proper "select" XML node
+ sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
+ node = xmlNewNode( NULL, (xmlChar*)"select" );
+ xmlNodeSetContent( node, (xmlChar*)buf );
+ level[0] = (int)'0' + ( bError ? SYS_ERR : SYS_WRN ) ;
+ level[1] = 0;
+ xmlSetProp( node, (xmlChar*)"level", (xmlChar*)&level );
+ // a 'select' information
+ sprintf( buf, "%i %i", entitynum, brushnum );
+ select = xmlNewNode( NULL, (xmlChar*)"brush" );
+ xmlNodeSetContent( select, (xmlChar*)buf );
+ xmlAddChild( node, select );
+ xml_SendNode( node );
+
+ sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
+ if ( bError ) {
+ Error( buf );
+ }
+ else{
+ Sys_FPrintf( SYS_NOXML, "%s\n", buf );
+ }
}
-void xml_Point (char *msg, vec3_t pt)
-{
- xmlNodePtr node, point;
- char buf[1024];
- char level[2];
-
- node = xmlNewNode (NULL, "pointmsg");
- xmlNodeSetContent (node, msg);
- level[0] = (int)'0' + SYS_ERR;
- level[1] = 0;
- xmlSetProp (node, "level", (char *)&level);
- // a 'point' node
- sprintf (buf, "%g %g %g", pt[0], pt[1], pt[2]);
- point = xmlNewNode (NULL, "point");
- xmlNodeSetContent (point, buf);
- xmlAddChild (node, point);
- xml_SendNode (node);
-
- sprintf (buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2]);
- Error (buf);
+void xml_Point( char *msg, vec3_t pt ){
+ xmlNodePtr node, point;
+ char buf[1024];
+ char level[2];
+
+ node = xmlNewNode( NULL, (xmlChar*)"pointmsg" );
+ xmlNodeSetContent( node, (xmlChar*)msg );
+ level[0] = (int)'0' + SYS_ERR;
+ level[1] = 0;
+ xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level );
+ // a 'point' node
+ sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] );
+ point = xmlNewNode( NULL, (xmlChar*)"point" );
+ xmlNodeSetContent( point, (xmlChar*)buf );
+ xmlAddChild( node, point );
+ xml_SendNode( node );
+
+ sprintf( buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2] );
+ Error( buf );
}
#define WINDING_BUFSIZE 2048
-void xml_Winding (char *msg, vec3_t p[], int numpoints, qboolean die)
-{
- xmlNodePtr node, winding;
- char buf[WINDING_BUFSIZE];
- char smlbuf[128];
- char level[2];
- int i;
-
- node = xmlNewNode (NULL, "windingmsg");
- xmlNodeSetContent (node, msg);
- level[0] = (int)'0' + SYS_ERR;
- level[1] = 0;
- xmlSetProp (node, "level", (char *)&level);
- // a 'winding' node
- sprintf( buf, "%i ", numpoints);
- for(i = 0; i < numpoints; i++)
- {
- sprintf (smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2]);
- // don't overflow
- if (strlen(buf)+strlen(smlbuf)>WINDING_BUFSIZE)
- break;
- strcat( buf, smlbuf);
- }
-
- winding = xmlNewNode (NULL, "winding");
- xmlNodeSetContent (winding, buf);
- xmlAddChild (node, winding);
- xml_SendNode (node);
-
- if(die)
- Error (msg);
- else
- {
- Sys_Printf(msg);
- Sys_Printf("\n");
- }
+void xml_Winding( char *msg, vec3_t p[], int numpoints, qboolean die ){
+ xmlNodePtr node, winding;
+ char buf[WINDING_BUFSIZE];
+ char smlbuf[128];
+ char level[2];
+ int i;
+
+ node = xmlNewNode( NULL, (xmlChar*)"windingmsg" );
+ xmlNodeSetContent( node, (xmlChar*)msg );
+ level[0] = (int)'0' + SYS_ERR;
+ level[1] = 0;
+ xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level );
+ // a 'winding' node
+ sprintf( buf, "%i ", numpoints );
+ for ( i = 0; i < numpoints; i++ )
+ {
+ sprintf( smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2] );
+ // don't overflow
+ if ( strlen( buf ) + strlen( smlbuf ) > WINDING_BUFSIZE ) {
+ break;
+ }
+ strcat( buf, smlbuf );
+ }
+
+ winding = xmlNewNode( NULL, (xmlChar*)"winding" );
+ xmlNodeSetContent( winding, (xmlChar*)buf );
+ xmlAddChild( node, winding );
+ xml_SendNode( node );
+
+ if ( die ) {
+ Error( msg );
+ }
+ else
+ {
+ Sys_Printf( msg );
+ Sys_Printf( "\n" );
+ }
}
// in include
#include "stream_version.h"
-void Broadcast_Setup( const char *dest )
-{
+void Broadcast_Setup( const char *dest ){
address_t address;
- char sMsg[1024];
+ char sMsg[1024];
Net_Setup();
- Net_StringToAddress((char *)dest, &address);
- brdcst_socket = Net_Connect(&address, 0);
- if (brdcst_socket)
- {
- // send in a header
- sprintf (sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">");
- NMSG_Clear( &msg );
- NMSG_WriteString(&msg, sMsg );
- Net_Send(brdcst_socket, &msg );
- }
+ Net_StringToAddress( dest, &address );
+ brdcst_socket = Net_Connect( &address, 0 );
+ if ( brdcst_socket ) {
+ // send in a header
+ sprintf( sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">" );
+ NMSG_Clear( &msg );
+ NMSG_WriteString( &msg, sMsg );
+ Net_Send( brdcst_socket, &msg );
+ }
}
-void Broadcast_Shutdown()
-{
- if (brdcst_socket)
- {
- Sys_Printf("Disconnecting\n");
- Net_Disconnect(brdcst_socket);
- brdcst_socket = NULL;
- }
+void Broadcast_Shutdown(){
+ if ( brdcst_socket ) {
+ Sys_Printf( "Disconnecting\n" );
+ Net_Disconnect( brdcst_socket );
+ brdcst_socket = NULL;
+ }
}
// all output ends up through here
-void FPrintf (int flag, char *buf)
-{
- xmlNodePtr node;
- static qboolean bGotXML = qfalse;
- char level[2];
-
- printf(buf);
-
- // the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe?
- if (flag == SYS_NOXML)
- return;
-
- // ouput an XML file of the run
- // use the DOM interface to build a tree
- /*
- <message level='flag'>
- message string
- .. various nodes to describe corresponding geometry ..
- </message>
- */
- if (!bGotXML)
- {
- // initialize
- doc = xmlNewDoc("1.0");
- doc->children = xmlNewDocRawNode(doc, NULL, "q3map_feedback", NULL);
- bGotXML = qtrue;
- }
- node = xmlNewNode (NULL, "message");
- {
- gchar* utf8 = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
- xmlNodeSetContent(node, utf8);
- g_free(utf8);
- }
- level[0] = (int)'0' + flag;
- level[1] = 0;
- xmlSetProp (node, "level", (char *)&level );
-
- xml_SendNode (node);
+void FPrintf( int flag, char *buf ){
+ xmlNodePtr node;
+ static qboolean bGotXML = qfalse;
+ char level[2];
+
+ printf( "%s", buf );
+
+ // the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe?
+ if ( flag == SYS_NOXML ) {
+ return;
+ }
+
+ // ouput an XML file of the run
+ // use the DOM interface to build a tree
+ /*
+ <message level='flag'>
+ message string
+ .. various nodes to describe corresponding geometry ..
+ </message>
+ */
+ if ( !bGotXML ) {
+ // initialize
+ doc = xmlNewDoc( (xmlChar*)"1.0" );
+ doc->children = xmlNewDocRawNode( doc, NULL, (xmlChar*)"q3map_feedback", NULL );
+ bGotXML = qtrue;
+ }
+ node = xmlNewNode( NULL, (xmlChar*)"message" );
+ {
+ gchar* utf8 = g_locale_to_utf8( buf, -1, NULL, NULL, NULL );
+ xmlNodeSetContent( node, (xmlChar*)utf8 );
+ g_free( utf8 );
+ }
+ level[0] = (int)'0' + flag;
+ level[1] = 0;
+ xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level );
+
+ xml_SendNode( node );
}
#ifdef DBG_XML
-void DumpXML()
-{
- xmlSaveFile( "XMLDump.xml", doc );
+void DumpXML(){
+ xmlSaveFile( "XMLDump.xml", doc );
}
#endif
-void Sys_FPrintf (int flag, const char *format, ...)
-{
- char out_buffer[4096];
+void Sys_FPrintf( int flag, const char *format, ... ){
+ char out_buffer[4096];
va_list argptr;
-
- if ((flag == SYS_VRB) && (verbose == qfalse))
- return;
- va_start (argptr, format);
- vsprintf (out_buffer, format, argptr);
- va_end (argptr);
+ if ( ( flag == SYS_VRB ) && ( verbose == qfalse ) ) {
+ return;
+ }
+
+ va_start( argptr, format );
+ vsprintf( out_buffer, format, argptr );
+ va_end( argptr );
- FPrintf (flag, out_buffer);
+ FPrintf( flag, out_buffer );
}
-void Sys_Printf (const char *format, ...)
-{
- char out_buffer[4096];
+void Sys_Printf( const char *format, ... ){
+ char out_buffer[4096];
va_list argptr;
- va_start (argptr, format);
- vsprintf (out_buffer, format, argptr);
- va_end (argptr);
-
- FPrintf (SYS_STD, out_buffer);
+ va_start( argptr, format );
+ vsprintf( out_buffer, format, argptr );
+ va_end( argptr );
+
+ FPrintf( SYS_STD, out_buffer );
}
/*
-=================
-Error
-
-For abnormal program terminations
-=================
-*/
-void Error( const char *error, ...)
-{
- char out_buffer[4096];
- char tmp[4096];
+ =================
+ Error
+
+ For abnormal program terminations
+ =================
+ */
+void Error( const char *error, ... ){
+ char out_buffer[4096];
+ char tmp[4096];
va_list argptr;
- va_start (argptr,error);
- vsprintf (tmp, error, argptr);
- va_end (argptr);
+ va_start( argptr,error );
+ vsprintf( tmp, error, argptr );
+ va_end( argptr );
- sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
+ sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
- FPrintf( SYS_ERR, out_buffer );
+ FPrintf( SYS_ERR, out_buffer );
-#ifdef DBG_XML
- DumpXML();
+#ifdef DBG_XML
+ DumpXML();
#endif
- //++timo HACK ALERT .. if we shut down too fast the xml stream won't reach the listener.
- // a clean solution is to send a sync request node in the stream and wait for an answer before exiting
- Sys_Sleep( 1000 );
-
- Broadcast_Shutdown();
+ //++timo HACK ALERT .. if we shut down too fast the xml stream won't reach the listener.
+ // a clean solution is to send a sync request node in the stream and wait for an answer before exiting
+ Sys_Sleep( 1000 );
- exit (1);
-}
+ Broadcast_Shutdown();
+ exit( 1 );
+}