Difference between revisions of "Motd (Metamod:Source)"

From AlliedModders Wiki
Jump to: navigation, search
 
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Category:Documentation (SourceMM)]]
+
[[Category:Metamod:Source Development]]
 
== Message of the Day (MOTD) ==
 
== Message of the Day (MOTD) ==
Thanks to [[User:c0ldfyr3|coldfyr3]] for his [http://www.sourcemod.net/forums/viewtopic.php?t=2498&highlight=motd example] of displaying info in a MOTD panel. At the end of this page, I've built on his technique to send messages greater than 255 characters in length.
 
  
 
=== Showing a MOTD Panel ===
 
=== Showing a MOTD Panel ===
Line 9: Line 8:
 
<cpp>mVGUIMenu = UserMessageIndex("VGUIMenu");</cpp>
 
<cpp>mVGUIMenu = UserMessageIndex("VGUIMenu");</cpp>
  
 +
Then add this to your project:
 
<cpp>
 
<cpp>
void ShowMOTD(edict_t *pEdict, const char* lpcMsg, const char* lpcTitle, int iType, const char* lpcCmd)
+
void ShowMOTD(int index, char *title, char *msg, int type, char *cmd) {
{
+
   bf_write *buffer;
   KeyValues* kv = new KeyValues("data");   
+
   MRecipientFilter filter;
  kv->SetString("title", lpcTitle);  // info panel title
+
 
  if ( iType == 1 )
+
   filter.AddRecipient(index);
  {
 
      kv->SetString("type", "1");         // show userdata from stringtable entry
 
   }
 
  else if ( iType == 2 )
 
  {
 
      kv->SetString("type", "2");         // show userdata from stringtable entry
 
  }
 
   else if ( iType == 3 )
 
  {
 
      kv->SetString("type", "4");        // show userdata from stringtable entry
 
  }
 
  else if ( iType == 4 )
 
  {
 
      kv->SetString("type", "4");        // show userdata from stringtable entry
 
  }
 
                              //  TYPE_TEXT = 0,  // just display this plain text
 
                              //  TYPE_INDEX,      // lookup text & title in stringtable
 
                              //  TYPE_URL,      // show this URL
 
                              //  TYPE_FILE,      // show this local file
 
  kv->SetString("msg", lpcMsg);     // use this stringtable entry
 
  
   if(lpcCmd && *lpcCmd)
+
   buffer = engine->UserMessageBegin(&filter, mVGUIMenu);
   {
+
   buffer->WriteString("info");
      kv->SetString("cmd", lpcCmd);// exec this command if panel closed
+
   buffer->WriteByte(1);
   }
 
  
   ShowViewPortPanel(pEdict, "info", true, kv);
+
   if(cmd != NULL)
 +
      buffer->WriteByte(4);
 +
  else
 +
      buffer->WriteByte(3);
  
   kv->deleteThis();
+
   buffer->WriteString("title");
}
+
  buffer->WriteString(title);
  
// called from ShowMOTD
+
  buffer->WriteString("type");
void ShowViewPortPanel(edict_t* pEdict, const char* name, bool bShow, KeyValues* data)
+
  switch(type) {
{
+
      case TYPE_TEXT:
bf_write *netmsg; // our network message object
+
        buffer->WriteString("0"); //TYPE_TEXT = 0, just display this plain text
    MRecipientFilter recipient_filter; // the corresponding recipient filter
+
        break;
 
    // pPlayerEdict is a pointer to the edict of a player for which you want this HUD message
 
    // to be displayed. There can be several recipients in the filter, don't forget.
 
    recipient_filter.AddPlayer (m_Engine->IndexOfEdict (pEdict));
 
  
  int count = 0;
+
      case TYPE_INDEX:
  KeyValues *subkey = NULL;
+
        buffer->WriteString("1"); //TYPE_INDEX, lookup text & title in stringtable
 +
        break;
  
  if(data)
+
      case TYPE_URL:
  {
+
        buffer->WriteString("2"); //TYPE_URL, show this URL
      subkey = data->GetFirstSubKey();   
+
         break;
      while(subkey)
 
    {
 
        count++;    
 
         subkey = subkey->GetNextKey();
 
      }
 
  
       subkey = data->GetFirstSubKey(); // reset
+
       case TYPE_FILE:
 +
        buffer->WriteString("3"); //TYPE_FILE, show this local file
 +
        break;
 
   }
 
   }
 
 
 
  netmsg = m_Engine->UserMessageBegin (&recipient_filter, mVGUIMenu);
 
 
 
  netmsg->WriteString (name); // the HUD message itself
 
  netmsg->WriteByte (bShow ? 1 : 0); // index of the player this message comes from. "0" means the server.
 
    netmsg->WriteByte (count); // I don't know yet the purpose of this byte, it can be 1 or 0
 
     
 
  // write additional data (be carefull not more than 192 bytes!)
 
  while(subkey)
 
  {
 
  
      netmsg->WriteString (subkey->GetName()); // the HUD message itself
+
  buffer->WriteString("msg");
       netmsg->WriteString (subkey->GetString()); // the HUD message itself
+
  buffer->WriteString(msg); // msg must not be greater than 192 characters
       subkey = subkey->GetNextKey();
+
 
 +
  if(cmd != NULL) {
 +
       buffer->WriteString("cmd");
 +
       buffer->WriteString(cmd); // exec this command if panel closed
 
   }
 
   }
 
 
  m_Engine->MessageEnd ();
 
}
 
  
// lookup index for user messages
+
   engine->MessageEnd();
int UserMessageIndex(const char *messageName)
+
   return ;
{
+
}</cpp>
  char name[128] = "";
 
  int sizereturn = 0;
 
  bool boolrtn = false;
 
  for(int x=1; x<27; x++)
 
   {
 
      boolrtn =  m_ServerDll->GetUserMessageInfo(x, name, 128, sizereturn);  
 
      if(name && strcmp(messageName, name) == 0)
 
      {
 
        return x;   
 
      }
 
  }
 
   return -1;
 
} </cpp>
 
  
 
=== Displaying Your Info in the MOTD Panel ===
 
=== Displaying Your Info in the MOTD Panel ===
Line 117: Line 69:
 
For example:
 
For example:
 
To show a website
 
To show a website
<pre>ShowMOTD( pEdict, "http://www.yahoo.com", "Yahoo.com !", 2, "" )</pre>
+
<pre>ShowMOTD( pEdict, "http://www.yahoo.com", "Yahoo.com !", TYPE_URL, NULL )</pre>
 
To show some text
 
To show some text
<pre>ShowMOTD( pEdict, "Some Text", "A Title", 1, "" )</pre>
+
<pre>ShowMOTD( pEdict, "Some Text", "A Title", TYPE_TEXT, NULL )</pre>
  
 
== Using TYPE_INDEX to Send More Than 255 Characters ==
 
== Using TYPE_INDEX to Send More Than 255 Characters ==
Line 133: Line 85:
 
Next, we can setup our string table entry:
 
Next, we can setup our string table entry:
 
<cpp> char msg[4096];
 
<cpp> char msg[4096];
 +
// copy your info into msg
 +
// if you add any html tags, your msg will be formatted as html (for example <b>bold text</b>)
  
 
INetworkStringTable *pInfoPanel = m_NetworkStringtable->FindTable("InfoPanel");
 
INetworkStringTable *pInfoPanel = m_NetworkStringtable->FindTable("InfoPanel");

Latest revision as of 22:56, 5 October 2007

Message of the Day (MOTD)

Showing a MOTD Panel

To show a MOTD, you'll need to add this code to your project. You'll also need to include an MRecipientFilter class. You may want to make it part of a class instance in your program, but this will work as an example.

First add this to AllPluginsLoaded:

mVGUIMenu = UserMessageIndex("VGUIMenu");

Then add this to your project:

void ShowMOTD(int index, char *title, char *msg, int type, char *cmd) {
   bf_write *buffer;
   MRecipientFilter filter;
 
   filter.AddRecipient(index);
 
   buffer = engine->UserMessageBegin(&filter, mVGUIMenu);
   buffer->WriteString("info");
   buffer->WriteByte(1);
 
   if(cmd != NULL)
      buffer->WriteByte(4);
   else
      buffer->WriteByte(3);
 
   buffer->WriteString("title");
   buffer->WriteString(title);
 
   buffer->WriteString("type");
   switch(type) {
      case TYPE_TEXT:
         buffer->WriteString("0"); //TYPE_TEXT = 0, just display this plain text
         break;
 
      case TYPE_INDEX:
         buffer->WriteString("1"); //TYPE_INDEX, lookup text & title in stringtable
         break;
 
      case TYPE_URL:
         buffer->WriteString("2"); //TYPE_URL, show this URL
         break;
 
      case TYPE_FILE:
         buffer->WriteString("3"); //TYPE_FILE, show this local file
         break;
   }
 
   buffer->WriteString("msg");
   buffer->WriteString(msg); // msg must not be greater than 192 characters
 
   if(cmd != NULL) {
      buffer->WriteString("cmd");
      buffer->WriteString(cmd); // exec this command if panel closed
   }
 
   engine->MessageEnd();
   return ;
}

Displaying Your Info in the MOTD Panel

The types of MOTD available are:

TYPE_TEXT = 0  // just display this plain text
TYPE_INDEX = 1 // lookup text & title in stringtable
TYPE_URL = 2   // show this URL
TYPE_FILE = 3  // show this local file

For example: To show a website

ShowMOTD( pEdict, "http://www.yahoo.com", "Yahoo.com !", TYPE_URL, NULL )

To show some text

ShowMOTD( pEdict, "Some Text", "A Title", TYPE_TEXT, NULL )

Using TYPE_INDEX to Send More Than 255 Characters

TYPE_TEXT is limited to 255 characters. To send a longer piece of info, we need to create an entry in the StringTables and reference that using TYPE_INDEX.

First, we need to have a NetworkStringTableContainer:

INetworkStringTableContainer *m_NetworkStringtable;

Then, using the FIND_IFACE macro from the sample_mm plugin, we need to get the INetworkStringTable interface in Load():

	strcpy(iface_buffer, INTERFACENAME_NETWORKSTRINGTABLESERVER);
	FIND_IFACE(engineFactory, m_NetworkStringtable, num, iface_buffer, INetworkStringTableContainer *);

Next, we can setup our string table entry:

	char msg[4096];
	// copy your info into msg
	// if you add any html tags, your msg will be formatted as html (for example <b>bold text</b>)
 
	INetworkStringTable *pInfoPanel = m_NetworkStringtable->FindTable("InfoPanel");
	if (pInfoPanel)
	{
		bool save = m_Engine->LockNetworkStringTables(false);
		int StrIdx = pInfoPanel->AddString("myinfo");
		pInfoPanel->SetStringUserData(StrIdx, 4096, msg);
		m_Engine->LockNetworkStringTables(save);
	}
	}

NOTE: 4096 characters is the max length, you should use the smallest size that your string data will fit into.

Finally you can show the MOTD panel with the info you added to the string tables:

ShowMOTD( EntityIndex, "myinfo", "My MOTD Window Title", 1, "" );

NOTE: I've tested this using html formatted text. I assume that the maximum length for standard text would also be 4096 characters. --L. Duke 00:45, 18 March 2006 (EST)