00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_LogCommandParser==1
00003
00004 #include "LogCommandParser.h"
00005 #include "TransportInterface.h"
00006 #if !defined(_PS3) && !defined(__PS3__) && !defined(SN_TARGET_PS3)
00007 #include <memory.h>
00008 #endif
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <stdarg.h>
00012
00013 #include "LinuxStrings.h"
00014
00015 #ifdef _MSC_VER
00016 #pragma warning( push )
00017 #endif
00018
00019 LogCommandParser::LogCommandParser()
00020 {
00021 RegisterCommand(CommandParserInterface::VARIABLE_NUMBER_OF_PARAMETERS,"Subscribe","[<ChannelName>] - Subscribes to a named channel, or all channels");
00022 RegisterCommand(CommandParserInterface::VARIABLE_NUMBER_OF_PARAMETERS,"Unsubscribe","[<ChannelName>] - Unsubscribes from a named channel, or all channels");
00023 memset(channelNames,0,sizeof(channelNames));
00024 }
00025 LogCommandParser::~LogCommandParser()
00026 {
00027 }
00028 bool LogCommandParser::OnCommand(const char *command, unsigned numParameters, char **parameterList, TransportInterface *transport, SystemAddress systemAddress, const char *originalString)
00029 {
00030 (void) originalString;
00031
00032 if (strcmp(command, "Subscribe")==0)
00033 {
00034 unsigned channelIndex;
00035 if (numParameters==0)
00036 {
00037 Subscribe(systemAddress, 0);
00038 transport->Send(systemAddress, "Subscribed to all channels.\r\n");
00039 }
00040 else if (numParameters==1)
00041 {
00042 if ((channelIndex=Subscribe(systemAddress, parameterList[0]))!=(unsigned)-1)
00043 {
00044 transport->Send(systemAddress, "You are now subscribed to channel %s.\r\n", channelNames[channelIndex]);
00045 }
00046 else
00047 {
00048 transport->Send(systemAddress, "Cannot find channel %s.\r\n", parameterList[0]);
00049 PrintChannels(systemAddress, transport);
00050 }
00051 }
00052 else
00053 {
00054 transport->Send(systemAddress, "Subscribe takes either 0 or 1 parameters.\r\n");
00055 }
00056 }
00057 else if (strcmp(command, "Unsubscribe")==0)
00058 {
00059 unsigned channelIndex;
00060 if (numParameters==0)
00061 {
00062 Unsubscribe(systemAddress, 0);
00063 transport->Send(systemAddress, "Unsubscribed from all channels.\r\n");
00064 }
00065 else if (numParameters==1)
00066 {
00067 if ((channelIndex=Unsubscribe(systemAddress, parameterList[0]))!=(unsigned)-1)
00068 {
00069 transport->Send(systemAddress, "You are now unsubscribed from channel %s.\r\n", channelNames[channelIndex]);
00070 }
00071 else
00072 {
00073 transport->Send(systemAddress, "Cannot find channel %s.\r\n", parameterList[0]);
00074 PrintChannels(systemAddress, transport);
00075 }
00076 }
00077 else
00078 {
00079 transport->Send(systemAddress, "Unsubscribe takes either 0 or 1 parameters.\r\n");
00080 }
00081 }
00082
00083 return true;
00084 }
00085 const char *LogCommandParser::GetName(void) const
00086 {
00087 return "Logger";
00088 }
00089 void LogCommandParser::SendHelp(TransportInterface *transport, SystemAddress systemAddress)
00090 {
00091 transport->Send(systemAddress, "The logger will accept user log data via the Log(...) function.\r\n");
00092 transport->Send(systemAddress, "Each log is associated with a named channel.\r\n");
00093 transport->Send(systemAddress, "You can subscribe to or unsubscribe from named channels.\r\n");
00094 PrintChannels(systemAddress, transport);
00095 }
00096 void LogCommandParser::AddChannel(const char *channelName)
00097 {
00098 unsigned channelIndex;
00099 channelIndex = GetChannelIndexFromName(channelName);
00100
00101 RakAssert(channelIndex==(unsigned)-1);
00102
00103 unsigned i;
00104 for (i=0; i < 32; i++)
00105 {
00106 if (channelNames[i]==0)
00107 {
00108
00109 channelNames[i]=channelName;
00110 return;
00111 }
00112 }
00113
00114
00115 RakAssert(0);
00116 }
00117 void LogCommandParser::WriteLog(const char *channelName, const char *format, ...)
00118 {
00119 if (channelName==0 || format==0)
00120 return;
00121
00122 unsigned channelIndex;
00123 channelIndex = GetChannelIndexFromName(channelName);
00124 if (channelIndex==(unsigned)-1)
00125 {
00126 AddChannel(channelName);
00127 }
00128
00129 char text[REMOTE_MAX_TEXT_INPUT];
00130 va_list ap;
00131 va_start(ap, format);
00132 _vsnprintf(text, REMOTE_MAX_TEXT_INPUT, format, ap);
00133 va_end(ap);
00134 text[REMOTE_MAX_TEXT_INPUT-1]=0;
00135
00136
00137 int textLen;
00138 textLen=(int)strlen(text);
00139 if (textLen==0)
00140 return;
00141 if (text[textLen-1]=='\n')
00142 {
00143 text[textLen-1]=0;
00144 }
00145 if (textLen < REMOTE_MAX_TEXT_INPUT-4)
00146 strcat(text, "\r\n");
00147 else
00148 {
00149 text[textLen-3]='\r';
00150 text[textLen-2]='\n';
00151 text[textLen-1]=0;
00152 }
00153
00154
00155 unsigned i;
00156 for (i=0; i < remoteUsers.Size(); i++)
00157 {
00158 if (remoteUsers[i].channels & (1 << channelIndex))
00159 {
00160 trans->Send(remoteUsers[i].systemAddress, text);
00161 }
00162 }
00163 }
00164 void LogCommandParser::PrintChannels(SystemAddress systemAddress, TransportInterface *transport) const
00165 {
00166 unsigned i;
00167 bool anyChannels=false;
00168 transport->Send(systemAddress, "CHANNELS:\r\n");
00169 for (i=0; i < 32; i++)
00170 {
00171 if (channelNames[i])
00172 {
00173 transport->Send(systemAddress, "%i. %s\r\n", i+1,channelNames[i]);
00174 anyChannels=true;
00175 }
00176 }
00177 if (anyChannels==false)
00178 transport->Send(systemAddress, "None.\r\n");
00179 }
00180 void LogCommandParser::OnNewIncomingConnection(SystemAddress systemAddress, TransportInterface *transport)
00181 {
00182 (void) systemAddress;
00183 (void) transport;
00184 }
00185 void LogCommandParser::OnConnectionLost(SystemAddress systemAddress, TransportInterface *transport)
00186 {
00187 (void) transport;
00188 Unsubscribe(systemAddress, 0);
00189 }
00190 unsigned LogCommandParser::Unsubscribe(SystemAddress systemAddress, const char *channelName)
00191 {
00192 unsigned i;
00193 for (i=0; i < remoteUsers.Size(); i++)
00194 {
00195 if (remoteUsers[i].systemAddress==systemAddress)
00196 {
00197 if (channelName==0)
00198 {
00199
00200 remoteUsers[i]=remoteUsers[remoteUsers.Size()-1];
00201 remoteUsers.RemoveFromEnd();
00202 return 0;
00203 }
00204 else
00205 {
00206 unsigned channelIndex;
00207 channelIndex = GetChannelIndexFromName(channelName);
00208 if (channelIndex!=(unsigned)-1)
00209 {
00210 remoteUsers[i].channels&=0xFFFF ^ (1<<channelIndex);
00211 }
00212 return channelIndex;
00213 }
00214 }
00215 }
00216 return (unsigned)-1;
00217 }
00218 unsigned LogCommandParser::Subscribe(SystemAddress systemAddress, const char *channelName)
00219 {
00220 unsigned i;
00221 unsigned channelIndex=(unsigned)-1;
00222 if (channelName)
00223 {
00224 channelIndex = GetChannelIndexFromName(channelName);
00225 if (channelIndex==(unsigned)-1)
00226 return channelIndex;
00227 }
00228
00229 for (i=0; i < remoteUsers.Size(); i++)
00230 {
00231 if (remoteUsers[i].systemAddress==systemAddress)
00232 {
00233 if (channelName)
00234 remoteUsers[i].channels|=1<<channelIndex;
00235 else
00236 remoteUsers[i].channels=0xFFFF;
00237 return channelIndex;
00238 }
00239 }
00240
00241
00242 SystemAddressAndChannel newUser;
00243 newUser.systemAddress = systemAddress;
00244 if (channelName)
00245 newUser.channels=1<<channelIndex;
00246 else
00247 newUser.channels=0xFFFF;
00248 remoteUsers.Insert(newUser, __FILE__, __LINE__);
00249 return channelIndex;
00250 }
00251 unsigned LogCommandParser::GetChannelIndexFromName(const char *channelName)
00252 {
00253 unsigned i;
00254 for (i=0; i < 32; i++)
00255 {
00256 if (channelNames[i]==0)
00257 return (unsigned) -1;
00258
00259 if (_stricmp(channelNames[i], channelName)==0)
00260 return i;
00261 }
00262 return (unsigned)-1;
00263 }
00264
00265 void LogCommandParser::OnTransportChange(TransportInterface *transport)
00266 {
00267
00268 trans=transport;
00269 }
00270
00271 #ifdef _MSC_VER
00272 #pragma warning( pop )
00273 #endif
00274
00275 #endif // _RAKNET_SUPPORT_*