void GetArgsFromBuffer( bf_read &buf, CUtlVector<char*> &newArgv, bool *bShowAppWindow ) { int nArgs = buf.ReadWord(); bool bSpewArgs = false; for ( int iArg=0; iArg < nArgs; iArg++ ) { char argStr[512]; buf.ReadString( argStr, sizeof( argStr ) ); AppendArg( newArgv, argStr ); if ( stricmp( argStr, "-mpi_verbose" ) == 0 ) bSpewArgs = true; if ( stricmp( argStr, "-mpi_ShowAppWindow" ) == 0 ) *bShowAppWindow = true; } if ( bSpewArgs ) { Msg( "nArgs: %d\n", newArgv.Count() ); for ( int i=0; i < newArgv.Count(); i++ ) Msg( "Arg %d: %s\n", i, newArgv[i] ); } }
// ---------------------------------------------------------- // ---------------------------------------------------------- void CHudTaskList::MsgFunc_TaskList( bf_read &msg ) { char szString[256]; int task_index; int task_priority; task_index = msg.ReadByte(); task_priority = msg.ReadByte(); msg.ReadString( szString, sizeof(szString) ); DevMsg (2, "CHudTaskList::MsgFunc_TaskList - got message for task %d, priority %d, string %s\n", task_index, task_priority, szString ); // ---------------------------------------------------------- // --- Convert it to localize friendly unicode // ---------------------------------------------------------- g_pVGuiLocalize->ConvertANSIToUnicode( szString, m_pText[task_index], sizeof(m_pText[task_index]) ); // ---------------------------------------------------------- // --- Setup a time tracker for tasks just added or updated // ---------------------------------------------------------- if ( m_iPriority[task_index] != task_priority ) { m_flStartTime[task_index] = gpGlobals->curtime; m_flDuration[task_index] = TASKLINE_FLASH_TIME; } m_iPriority[task_index] = task_priority; }
void CHud::MsgFunc_SendAudio( bf_read &msg ) { char szString[2048]; msg.ReadString( szString, sizeof(szString) ); CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, szString ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pszName - // iSize - // *pbuf - //----------------------------------------------------------------------------- void CHudChat::MsgFunc_SayText( bf_read &msg ) { char szString[256]; msg.ReadByte(); // client ID msg.ReadString( szString, sizeof(szString) ); Printf( CHAT_FILTER_NONE, "%s", szString ); }
void __MsgFunc_LessonLearned( bf_read &msg ) { char szString[256]; msg.ReadString(szString, sizeof(szString)); C_SDKPlayer* pPlayer = C_SDKPlayer::GetLocalSDKPlayer(); pPlayer->Instructor_LessonLearned(szString); }
//----------------------------------------------------------------------------- // Purpose: Handle an item pickup event from the server //----------------------------------------------------------------------------- void CHudHistoryResource::MsgFunc_ItemPickup( bf_read &msg ) { char szName[1024]; msg.ReadString( szName, sizeof(szName) ); // Add the item to the history AddToHistory( HISTSLOT_ITEM, szName ); }
void CHudLessonPanel::MsgFunc_HintText( bf_read &msg ) { // Read the string(s) char szString[255]; msg.ReadString( szString, sizeof(szString) ); char *tmpStr = hudtextmessage->LookupString( szString, NULL ); LocalizeAndDisplay( tmpStr, szString ); }
//----------------------------------------------------------------------------- // Purpose: Message handler for ShowMenu message // takes four values: // short: a bitfield of keys that are valid input // char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. // byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, false if it's the last string // string: menu string to display // if this message is never received, then scores will simply be the combined totals of the players. //----------------------------------------------------------------------------- void CHudMenu::MsgFunc_ShowMenu( bf_read &msg) { m_bitsValidSlots = (short)msg.ReadWord(); int DisplayTime = msg.ReadChar(); int NeedMore = msg.ReadByte(); if ( DisplayTime > 0 ) { m_flShutoffTime = m_flOpenCloseTime + DisplayTime + gpGlobals->realtime; } else { m_flShutoffTime = -1; } if ( m_bitsValidSlots ) { char szString[2048]; msg.ReadString( szString, sizeof(szString) ); if ( !m_fWaitingForMore ) // this is the start of a new menu { Q_strncpy( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ) ); } else { // append to the current menu string Q_strncat( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ), COPY_ALL_CHARACTERS ); } if ( !NeedMore ) { GetClientMode()->GetViewportAnimationController()->StartAnimationSequence("MenuOpen"); m_nSelectedItem = -1; // we have the whole string, so we can localise it now char szMenuString[MAX_MENU_STRING]; Q_strncpy( szMenuString, ConvertCRtoNL( hudtextmessage->BufferedLocaliseTextString( g_szPrelocalisedMenuString ) ), sizeof( szMenuString ) ); g_pVGuiLocalize->ConvertANSIToUnicode( szMenuString, g_szMenuString, sizeof( g_szMenuString ) ); ProcessText(); } m_bMenuDisplayed = true; m_bMenuTakesInput = true; m_flSelectionTime = gpGlobals->curtime; } else { HideMenu(); } m_fWaitingForMore = NeedMore; }
void HandlePacket_FORCE_PASSWORD_CHANGE( bf_read &buf, const CIPAddr &ipFrom ) { char newPassword[512]; buf.ReadString( newPassword, sizeof( newPassword ) ); Msg( "Got a FORCE_PASSWORD_CHANGE (%s) packet.\n", newPassword ); SetPassword( newPassword ); if ( g_pConnMgr ) g_pConnMgr->SendCurStateTo( -1 ); }
void CHoloShipComm::MsgFunc_HoloMessage( bf_read &msg ) { char szDisplayName[ 128 ]; char szWaveName[ 128 ]; msg.ReadString( szDisplayName, sizeof( szDisplayName ) ); msg.ReadString( szWaveName, sizeof( szWaveName ) ); const float flDuration = msg.ReadFloat(); //Msg( "Holo message received: %s, %s, %f\n", szDisplayName, szWaveName, flDuration ); wchar_t wszFormatted[ 64 ]; g_pVGuiLocalize->ConstructString( wszFormatted, sizeof( wszFormatted ), SafeLocalizeInline( "#holo_gui_comm_incoming" ).Get(), 1, SafeLocalizeInline( szDisplayName ).Get() ); m_pLabelHeader->SetText( wszFormatted ); m_flResetTimer = flDuration; m_flFlashTimer = 0.5f; ResetWaveForm( szWaveName ); }
// Message handler for PyNetworkCls void __MsgFunc_PyNetworkCls( bf_read &msg ) { char clientClass[PYNETCLS_BUFSIZE]; char networkName[PYNETCLS_BUFSIZE]; int iType = msg.ReadByte(); msg.ReadString(clientClass, PYNETCLS_BUFSIZE); msg.ReadString(networkName, PYNETCLS_BUFSIZE); DbgStrPyMsg( "__MsgFunc_PyNetworkCls: Registering Python network class message %d %s %s\n", iType, clientClass, networkName ); // Get module path const char *pch = Q_strrchr( networkName, '.' ); if( !pch ) { Warning( "Invalid python class name %s\n", networkName ); return; } int n = pch - networkName + 1; char modulePath[PYNETCLS_BUFSIZE]; Q_strncpy( modulePath, networkName, n ); // Make sure the client class is imported SrcPySystem()->Import( modulePath ); // Read which client class we are modifying PyClientClassBase *p = FindPyClientClass( clientClass ); if( !p ) { Warning( "__MsgFunc_PyNetworkCls: Invalid networked class %s\n", clientClass ); return; } // Set type p->SetType( iType ); SetupClientClassRecv( p, iType ); // Read network class name Q_strncpy( p->m_strPyNetworkedClassName, networkName, PYNETCLS_BUFSIZE ); // Attach if a network class exists unsigned short lookup = m_NetworkClassDatabase.Find( networkName ); if ( lookup != m_NetworkClassDatabase.InvalidIndex() ) { m_NetworkClassDatabase.Element(lookup)->AttachClientClass( p ); } else { Warning( "__MsgFunc_PyNetworkCls: Invalid networked class %s\n", networkName ); } }
void CHudGameMessage::MsgFunc_GameMessage( bf_read &msg ) { // Read in our string char szString[256]; msg.ReadString( szString, sizeof(szString) ); // Convert it to localize friendly unicode g_pVGuiLocalize->ConvertANSIToUnicode( szString, m_pText, sizeof(m_pText) ); // Setup our time trackers m_flStartTime = gpGlobals->curtime; m_flDuration = 5.0f; }
void CHudPickup::MsgFunc_WeaponPickup( bf_read &msg ) { bool loaded = msg.ReadOneBit(); char weapon[128]; char texture[128]; msg.ReadString( weapon, sizeof(weapon) ); Q_snprintf( texture, sizeof(texture), "death_%s", weapon ); m_PickupIcon = gHUD.GetIcon( texture ); m_fTouchExpire = gpGlobals->curtime + 0.2f; }
// Message handler for PyNetworkCls void __MsgFunc_PyNetworkCls( bf_read &msg ) { int iClassID; char networkName[PYNETCLS_BUFSIZE]; iClassID = msg.ReadWord(); msg.ReadString( networkName, PYNETCLS_BUFSIZE ); DbgStrPyMsg( "__MsgFunc_PyNetworkCls: Registering Python network class message %d %s\n", iClassID, networkName ); // Get module path const char *pch = V_strrchr( networkName, '.' ); if( !pch ) { Warning( "Invalid python class name %s\n", networkName ); return; } int n = pch - networkName + 1; char modulePath[PYNETCLS_BUFSIZE]; V_strncpy( modulePath, networkName, n ); // Make sure the client class is imported SrcPySystem()->Import( modulePath ); // Read which client class we are modifying PyClientClassBase *p = FindPyClientClassByID( iClassID ); if( !p ) { Warning( "__MsgFunc_PyNetworkCls: Invalid networked class %d\n", iClassID ); return; } // Read network class name V_strncpy( p->m_strPyNetworkedClassName, networkName, sizeof( p->m_strPyNetworkedClassName ) ); // Attach if a network class exists unsigned short lookup = m_NetworkClassDatabase.Find( networkName ); if ( lookup != m_NetworkClassDatabase.InvalidIndex() ) { m_NetworkClassDatabase.Element(lookup)->AttachClientClass( p ); } else { Warning( "__MsgFunc_PyNetworkCls: Invalid networked class %s\n", networkName ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudNotificationPanel::MsgFunc_HudNotifyCustom( bf_read &msg ) { // Ignore notifications in minmode ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) return; // Reload the base LoadControlSettings( "resource/UI/notifications/base_notification.res" ); char szText[256]; char szIcon[256]; msg.ReadString( szText, sizeof(szText) ); msg.ReadString( szIcon, sizeof(szIcon) ); int iBackgroundTeam = msg.ReadByte(); SetupNotifyCustom( szText, szIcon, iBackgroundTeam ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pszName - // iSize - // *pbuf - //----------------------------------------------------------------------------- void CHudChat::MsgFunc_SayText( bf_read &msg ) { char szString[256]; int client = msg.ReadByte(); msg.ReadString( szString, sizeof(szString) ); bool bWantsToChat = msg.ReadByte(); if ( bWantsToChat ) { // print raw chat text ChatPrintf( client, "%s", szString ); } else { // try to lookup translated string Printf( "%s", hudtextmessage->LookupString( szString ) ); } Msg( "%s", szString ); }
void __MsgFunc_FolderPanel( bf_read &msg ) { char panelname[2048]; msg.ReadString( panelname, sizeof(panelname) ); IViewPortPanel *viewport = gViewPortInterface->FindPanelByName( "folder" ); CFolderMenu* pFolder = dynamic_cast<CFolderMenu*>(viewport); if ( !pFolder ) return; C_SDKPlayer *pPlayer = C_SDKPlayer::GetLocalSDKPlayer(); gViewPortInterface->ShowPanel( (IViewPortPanel*)pFolder, true ); if (pPlayer && SDKGameRules()->IsTeamplay() && (pPlayer->GetTeamNumber() != SDK_TEAM_RED && pPlayer->GetTeamNumber() != SDK_TEAM_BLUE)) pFolder->ShowPage(PANEL_TEAM); else if (pPlayer && !pPlayer->HasCharacterBeenChosen()) pFolder->ShowPage(PANEL_CLASS); else pFolder->ShowPage(panelname); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pszName - // iSize - // *pbuf - //----------------------------------------------------------------------------- void CBaseHudChat::MsgFunc_SayText( bf_read &msg ) { char szString[256]; int client = msg.ReadByte(); msg.ReadString( szString, sizeof(szString) ); bool bWantsToChat = msg.ReadByte(); if ( bWantsToChat ) { // print raw chat text ChatPrintf( client, CHAT_FILTER_NONE, "%s", szString ); } else { // try to lookup translated string Printf( CHAT_FILTER_NONE, "%s", hudtextmessage->LookupString( szString ) ); } CLocalPlayerFilter filter; C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HudChat.Message" ); Msg( "%s", szString ); }
int HandleConnectionLessPacket(char*ip, short port, int connection_less, bf_read& recvdata) { recvdata.ReadLong(); int header = 0; int id = 0; int total = 0; int number = 0; short splitsize = 0; if (connection_less == 1) { header = recvdata.ReadByte(); } else { id = recvdata.ReadLong(); total = recvdata.ReadByte(); number = recvdata.ReadByte(); splitsize = recvdata.ReadByte(); } switch (header) { case '9': { recvdata.ReadLong(); char error[1024]; recvdata.ReadString(error, 1024); printf("Connection refused! [%s]\n", error); NET_Reconnect(); return 0; } case 'A': // A2A_GETCHALLENGE { bconnectstep = 2; long magicnumber = recvdata.ReadLong(); serverchallenge = recvdata.ReadLong(); ourchallenge = recvdata.ReadLong(); authprotocol = recvdata.ReadLong(); steamkey_encryptionsize = recvdata.ReadShort(); // gotta be 0 recvdata.ReadBytes(steamkey_encryptionkey, steamkey_encryptionsize); recvdata.ReadBytes(serversteamid, sizeof(serversteamid)); vacsecured = recvdata.ReadByte(); printf("Challenge: %lu__%lu|Auth: %x|SKey: %lu|VAC: %x\n", serverchallenge, ourchallenge, authprotocol, steamkey_encryptionsize, vacsecured); char connectpkg[700]; memset(connectpkg, 0, sizeof(connectpkg)); bf_write writeconnect(connectpkg, sizeof(connectpkg)); bf_read readsteamid(connectpkg, sizeof(connectpkg)); writeconnect.WriteLong(-1); writeconnect.WriteByte('k');//C2S_CONNECT writeconnect.WriteLong(0x18);//protocol ver writeconnect.WriteLong(0x03);//auth protocol 0x03 = PROTOCOL_STEAM, 0x02 = PROTOCOL_HASHEDCDKEY, 0x01=PROTOCOL_AUTHCERTIFICATE writeconnect.WriteLong(serverchallenge); writeconnect.WriteLong(ourchallenge); writeconnect.WriteUBitLong(2729496039, 32); writeconnect.WriteString(nickname); //nick writeconnect.WriteString(password); // pass writeconnect.WriteString("2000"); // game version unsigned char steamkey[STEAM_KEYSIZE]; unsigned int keysize = 0; steamuser->GetAuthSessionTicket(steamkey, STEAM_KEYSIZE, &keysize); CSteamID localsid = steamuser->GetSteamID(); writeconnect.WriteShort(242); unsigned long long steamid64 = localsid.ConvertToUint64(); writeconnect.WriteLongLong(steamid64); if (keysize) writeconnect.WriteBytes(steamkey, keysize); net.SendTo(ip, port, connectpkg, writeconnect.GetNumBytesWritten()); return 0; } case 'B': // S2C_CONNECTION { if (bconnectstep == 2) { bconnectstep = 3; printf("Connected successfully\n"); netchan->Initialize(); senddata.WriteUBitLong(6, 6); senddata.WriteByte(2); senddata.WriteLong(-1); senddata.WriteUBitLong(4, 6); senddata.WriteString("VModEnable 1"); senddata.WriteUBitLong(4, 6); senddata.WriteString("vban 0 0 0 0"); /* senddata.WriteByte(31); for (int i = 0; i < 31; i++) { senddata.WriteString("gm_snapangles"); senddata.WriteString("45"); }s */ NET_SendDatagram(); Sleep(3000); } return 0; } case 'I': { return 0; } default: { printf("Unknown message received from: %s, header: %i ( %c )\n", ip, header, header); break; } } return 0; }
//----------------------------------------------------------------------------- // Purpose: Parse string update //----------------------------------------------------------------------------- void CNetworkStringTable::ParseUpdate( bf_read &buf, int entries ) { int lastEntry = -1; CUtlVector< StringHistoryEntry > history; for (int i=0; i<entries; i++) { int entryIndex = lastEntry + 1; if ( !buf.ReadOneBit() ) { entryIndex = buf.ReadUBitLong( GetEntryBits() ); } lastEntry = entryIndex; if ( entryIndex < 0 || entryIndex >= GetMaxStrings() ) { Host_Error( "Server sent bogus string index %i for table %s\n", entryIndex, GetTableName() ); } const char *pEntry = NULL; char entry[ 1024 ]; char substr[ 1024 ]; if ( buf.ReadOneBit() ) { bool substringcheck = buf.ReadOneBit() ? true : false; if ( substringcheck ) { int index = buf.ReadUBitLong( 5 ); int bytestocopy = buf.ReadUBitLong( SUBSTRING_BITS ); Q_strncpy( entry, history[ index ].string, bytestocopy + 1 ); buf.ReadString( substr, sizeof(substr) ); Q_strncat( entry, substr, sizeof(entry), COPY_ALL_CHARACTERS ); } else { buf.ReadString( entry, sizeof( entry ) ); } pEntry = entry; } // Read in the user data. unsigned char tempbuf[ CNetworkStringTableItem::MAX_USERDATA_SIZE ]; memset( tempbuf, 0, sizeof( tempbuf ) ); const void *pUserData = NULL; int nBytes = 0; if ( buf.ReadOneBit() ) { if ( IsUserDataFixedSize() ) { // Don't need to read length, it's fixed length and the length was networked down already. nBytes = GetUserDataSize(); Assert( nBytes > 0 ); tempbuf[nBytes-1] = 0; // be safe, clear last byte buf.ReadBits( tempbuf, GetUserDataSizeBits() ); } else { nBytes = buf.ReadUBitLong( CNetworkStringTableItem::MAX_USERDATA_BITS ); ErrorIfNot( nBytes <= sizeof( tempbuf ), ("CNetworkStringTableClient::ParseUpdate: message too large (%d bytes).", nBytes) ); buf.ReadBytes( tempbuf, nBytes ); } pUserData = tempbuf; } // Check if we are updating an old entry or adding a new one if ( entryIndex < GetNumStrings() ) { SetStringUserData( entryIndex, nBytes, pUserData ); #ifdef _DEBUG if ( pEntry ) { Assert( !Q_strcmp( pEntry, GetString( entryIndex ) ) ); // make sure string didn't change } #endif pEntry = GetString( entryIndex ); // string didn't change } else { // Grow the table (entryindex must be the next empty slot) Assert( (entryIndex == GetNumStrings()) && (pEntry != NULL) ); if ( pEntry == NULL ) { Msg("CNetworkStringTable::ParseUpdate: NULL pEntry, table %s, index %i\n", GetTableName(), entryIndex ); pEntry = "";// avoid crash because of NULL strings } AddString( true, pEntry, nBytes, pUserData ); } if ( history.Count() > 31 ) { history.Remove( 0 ); } StringHistoryEntry she; Q_strncpy( she.string, pEntry, sizeof( she.string ) ); history.AddToTail( she ); } }
void HandlePacket_LOOKING_FOR_WORKERS( bf_read &buf, const CIPAddr &ipFrom ) { // If we're downloading files for a job request, don't process any more "looking for workers" packets. if ( g_Waiting_hProcess ) return; // This will be a nonzero-length string if patching. char versionString[512]; buf.ReadString( versionString, sizeof( versionString ) ); int iPort = buf.ReadShort(); int iPriority = buf.ReadShort(); // Make sure we don't run the same job more than once. if ( !CheckJobID( buf, g_CurJobID ) ) return; CUtlVector<char*> newArgv; GetArgsFromBuffer( buf, newArgv, &g_Waiting_bShowAppWindow ); bool bForcePatch = false; if ( buf.GetNumBytesLeft() >= 1 ) bForcePatch = (buf.ReadByte() != 0); int iDownloaderPort = iPort; if ( buf.GetNumBytesLeft() >= 2 ) iDownloaderPort = buf.ReadShort(); // Add these arguments after the executable filename to tell the program // that it's an MPI worker and who to connect to. char strDownloaderIP[128], strMainIP[128]; V_snprintf( strDownloaderIP, sizeof( strDownloaderIP ), "%d.%d.%d.%d:%d", ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3], iDownloaderPort ); V_snprintf( strMainIP, sizeof( strMainIP ), "%d.%d.%d.%d:%d", ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3], iPort ); // (-mpi is already on the command line of whoever ran the app). // AppendArg( commandLine, sizeof( commandLine ), "-mpi" ); newArgv.InsertAfter( 0, CopyString( "-mpi_worker" ) ); newArgv.InsertAfter( 1, CopyString( strDownloaderIP ) ); // If the version string is set, then this is a patch. bool bPatching = false; if ( versionString[0] != 0 ) { bPatching = true; // Check that we haven't applied this patch version yet. This case usually happens right after we've applied a patch // and we're restarting. The vmpi_transfer master is still pinging us telling us to patch, but we don't want to // reapply this patch. if ( atof( versionString ) <= atof( g_VersionString ) && !bForcePatch ) { newArgv.PurgeAndDeleteElements(); return; } // Ok, it's a new version. Get rid of whatever was running before. KillRunningProcess( "Starting a patch..", true ); } // If there's already a job running, only interrupt it if this new one has a higher priority. if ( WaitForProcessToExit() ) { if ( iPriority > g_CurJobPriority ) { KillRunningProcess( "Interrupted by a higher priority process", true ); } else { // This means we're already running a job with equal to or greater priority than // the one that has been requested. We're going to ignore this request. newArgv.PurgeAndDeleteElements(); return; } } // Responses go here. g_CurRespondAddr = ipFrom; // Also look for -mpi_ShowAppWindow in the args to the service. if ( !g_Waiting_bShowAppWindow && FindArg( __argc, __argv, "-mpi_ShowAppWindow" ) ) g_Waiting_bShowAppWindow = true; // Copy all the files from the master and put them in our cache dir to run with. char cacheDir[MAX_PATH]; if ( StartDownloadingAppFiles( newArgv, cacheDir, sizeof( cacheDir ), g_Waiting_bShowAppWindow, &g_Waiting_hProcess, bPatching ) ) { // After it's downloaded, we want it to switch to the main connection port. if ( newArgv.Count() >= 3 && V_stricmp( newArgv[2], strDownloaderIP ) == 0 ) { delete newArgv[2]; newArgv[2] = CopyString( strMainIP ); } g_Waiting_StartTime = Plat_FloatTime(); g_Waiting_Argv.PurgeAndDeleteElements(); g_Waiting_Argv = newArgv; g_Waiting_Priority = iPriority; g_Waiting_bPatching = bPatching; newArgv.Purge(); } else { newArgv.PurgeAndDeleteElements(); } // Remember that we tried to run this job so we don't try to run it again. AddJobMemory( g_CurJobID ); SendStateToServicesBrowsers(); }
// Message handler for text messages // displays a string, looking them up from the titles.txt file, which can be localised // parameters: // byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK ) // string: message // optional parameters: // string: message parameter 1 // string: message parameter 2 // string: message parameter 3 // string: message parameter 4 // any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt // the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#') void CHudChat::MsgFunc_TextMsg( bf_read &msg ) { char szString[2048]; int msg_dest = msg.ReadByte(); static char szBuf[6][256]; msg.ReadString( szString, sizeof(szString) ); char *msg_text = hudtextmessage->LookupString( szString, &msg_dest ); Q_strncpy( szBuf[0], msg_text, sizeof( szBuf[0] ) ); msg_text = szBuf[0]; // keep reading strings and using C format strings for subsituting the strings into the localised text string msg.ReadString( szString, sizeof(szString) ); char *sstr1 = hudtextmessage->LookupString( szString ); Q_strncpy( szBuf[1], sstr1, sizeof( szBuf[1] ) ); sstr1 = szBuf[1]; StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines msg.ReadString( szString, sizeof(szString) ); char *sstr2 = hudtextmessage->LookupString( szString ); Q_strncpy( szBuf[2], sstr2, sizeof( szBuf[2] ) ); sstr2 = szBuf[2]; StripEndNewlineFromString( sstr2 ); msg.ReadString( szString, sizeof(szString) ); char *sstr3 = hudtextmessage->LookupString( szString ); Q_strncpy( szBuf[3], sstr3, sizeof( szBuf[3] ) ); sstr3 = szBuf[3]; StripEndNewlineFromString( sstr3 ); msg.ReadString( szString, sizeof(szString) ); char *sstr4 = hudtextmessage->LookupString( szString ); Q_strncpy( szBuf[4], sstr4, sizeof( szBuf[4] ) ); sstr4 = szBuf[4]; StripEndNewlineFromString( sstr4 ); char *psz = szBuf[5]; if ( !cl_showtextmsg.GetInt() ) return; switch ( msg_dest ) { case HUD_PRINTCENTER: Q_snprintf( psz, sizeof( szBuf[5] ), msg_text, sstr1, sstr2, sstr3, sstr4 ); GetCenterPrint()->Print( ConvertCRtoNL( psz ) ); break; case HUD_PRINTNOTIFY: psz[0] = 1; // mark this message to go into the notify buffer Q_snprintf( psz+1, sizeof( szBuf[5] ) - 1, msg_text, sstr1, sstr2, sstr3, sstr4 ); Msg( "%s", ConvertCRtoNL( psz ) ); break; case HUD_PRINTTALK: Q_snprintf( psz, sizeof( szBuf[5] ), msg_text, sstr1, sstr2, sstr3, sstr4 ); Printf( CHAT_FILTER_NONE, "%s", ConvertCRtoNL( psz ) ); break; case HUD_PRINTCONSOLE: Q_snprintf( psz, sizeof( szBuf[5] ), msg_text, sstr1, sstr2, sstr3, sstr4 ); Msg( "%s", ConvertCRtoNL( psz ) ); break; } }
//----------------------------------------------------------------------------- // Message handler for text messages // displays a string, looking them up from the titles.txt file, which can be localised // parameters: // byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK ) // string: message // optional parameters: // string: message parameter 1 // string: message parameter 2 // string: message parameter 3 // string: message parameter 4 // any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt // the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#') //----------------------------------------------------------------------------- void CBaseHudChat::MsgFunc_TextMsg( bf_read &msg ) { char szString[2048]; int msg_dest = msg.ReadByte(); wchar_t szBuf[5][256]; wchar_t outputBuf[256]; for ( int i=0; i<5; ++i ) { msg.ReadString( szString, sizeof(szString) ); char *tmpStr = hudtextmessage->LookupString( szString, &msg_dest ); const wchar_t *pBuf = g_pVGuiLocalize->Find( tmpStr ); if ( pBuf ) { // Copy pBuf into szBuf[i]. int nMaxChars = sizeof( szBuf[i] ) / sizeof( wchar_t ); wcsncpy( szBuf[i], pBuf, nMaxChars ); szBuf[i][nMaxChars-1] = 0; } else { if ( i ) { StripEndNewlineFromString( tmpStr ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines } g_pVGuiLocalize->ConvertANSIToUnicode( tmpStr, szBuf[i], sizeof(szBuf[i]) ); } } if ( !cl_showtextmsg.GetInt() ) return; int len; switch ( msg_dest ) { case HUD_PRINTCENTER: g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); internalCenterPrint->Print( ConvertCRtoNL( outputBuf ) ); break; case HUD_PRINTNOTIFY: g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); len = strlen( szString ); if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); } Msg( "%s", ConvertCRtoNL( szString ) ); break; case HUD_PRINTTALK: g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); len = strlen( szString ); if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); } Printf( CHAT_FILTER_NONE, "%s", ConvertCRtoNL( szString ) ); Msg( "%s", ConvertCRtoNL( szString ) ); break; case HUD_PRINTCONSOLE: g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); len = strlen( szString ); if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); } Msg( "%s", ConvertCRtoNL( szString ) ); break; } }
bool HandleMessage(bf_read &msg, int type) { if (type == 0) // nop { // printf("NOP\n"); return true; } if (type == 1) // disconnect { char dcreason[1024]; msg.ReadString(dcreason, sizeof(dcreason)); printf("Disconnected: %s\n", dcreason); printf("Reconnecting in 5000 ms ..."); _sleep(5000); NET_Reconnect(); return true; } if (type == 2)//net_File { long transferid = msg.ReadUBitLong(32); char filename[255]; msg.ReadString(filename, sizeof(filename)); bool requested = (bool)(msg.ReadOneBit()==1); if (requested) printf("net_File: Server requested file: %s::%i\n", filename, transferid); else printf("net_File: Server is not sending file: %s::%i\n", filename, transferid); return true; } if (type == 3)//net_Tick { net_tick = msg.ReadLong(); net_hostframetime = msg.ReadUBitLong(16); net_hostframedeviation = msg.ReadUBitLong(16); //printf("Tick: %i - hostframetime: %i ( deviation: %i )\n", net_tick, net_hostframedeviation, net_hostframedeviation); return true; } if (type == 4)//net_StringCmd { char cmd[1024]; msg.ReadString(cmd, sizeof(cmd)); printf("net_StringCmd: %s\n", cmd); return true; } if (type == 5)//net_SetConVar { int count = msg.ReadByte(); char cmdname[255]; char cmdval[255]; printf("net_SetConVar: %i\n", count); for (int i = 0; i < count; i++) { msg.ReadString(cmdname, sizeof(cmdname)); msg.ReadString(cmdval, sizeof(cmdval)); printf("%s to: %s\n", cmdname, cmdval); } printf("net_SetConVar_end, left: %i\n", msg.GetNumBytesLeft()); return true; } if (type == 6)// net_SignonState { int state = msg.ReadByte(); long aservercount = msg.ReadLong(); printf("Received net_SignOnState: %i, count: %i\n", state, bconnectstep); if (netchan->m_iSignOnState == state) { printf("Ignored signonstate!\n"); return true; } netchan->m_iServerCount = aservercount; netchan->m_iSignOnState = state; printf("KK __ %i\n", state); if (state == 3) { senddata.WriteUBitLong(8, 6); senddata.WriteLong(netchan->m_iServerCount); senddata.WriteLong(518790445);//clc_ClientInfo crc senddata.WriteOneBit(1);//ishltv senddata.WriteLong(1337); static int shit = 20; shit++; printf("LOL: %i\n", shit); senddata.WriteUBitLong(0, shit); NET_SendDatagram(0); senddata.WriteUBitLong(0, 6); senddata.WriteUBitLong(6, 6); senddata.WriteByte(state); senddata.WriteLong(aservercount); NET_SendDatagram(0); return true; } if (bconnectstep) { if (state == 4 && false) { senddata.WriteUBitLong(12, 6); for (int i = 0; i < 32; i++) { senddata.WriteUBitLong(1, 32); } } senddata.WriteUBitLong(6, 6); senddata.WriteByte(state); senddata.WriteLong(aservercount); NET_SendDatagram(false); return true; } senddata.WriteUBitLong(6, 6); senddata.WriteByte(state); senddata.WriteLong(aservercount); return true; } if (type == 7) // svc_Print { char print[2048]; msg.ReadString(print, sizeof(print)); // printf("svc_Print: %s", print); printf("%s", print); return true; } if (type == 8)//svc_ServerInfo { unsigned short protoversion = msg.ReadShort(); long servercount = msg.ReadLong(); bool srctv = (bool)(msg.ReadOneBit() == 1); bool dedicated = (bool)(msg.ReadOneBit() == 1); long crc = msg.ReadLong(); short maxclasses = msg.ReadWord(); char mapmd5[16]; msg.ReadBytes(mapmd5, 16); char players = msg.ReadByte(); char maxplayers = msg.ReadByte(); float tickinterval = msg.ReadFloat(); char platform = msg.ReadChar(); char gamedir[255]; char levelname[255]; char skyname[255]; char hostname[255]; char loadingurl[255]; char gamemode[255]; msg.ReadString(gamedir, sizeof(gamedir)); msg.ReadString(levelname, sizeof(levelname)); msg.ReadString(skyname, sizeof(skyname)); msg.ReadString(hostname, sizeof(hostname)); msg.ReadString(loadingurl, sizeof(loadingurl)); msg.ReadString(gamemode, sizeof(gamemode)); printf("ServerInfo, players: %lu/%lu | map: %s | name: %s | gm: %s | count: %i | left: %i | step: %i\n", players, maxplayers, levelname, hostname, gamemode, servercount, msg.GetNumBitsLeft(), bconnectstep); netchan->m_iServerCount = servercount; bconnectstep = 4; return true; } if (type == 10)//svc_ClassInfo { int classes = msg.ReadShort(); int useclientclasses = msg.ReadOneBit(); unsigned int size = (int)(log2(classes) + 1); if (useclientclasses == 0) { printf("Received svc_ClassInfo | classes: %i: \n", classes); for (int i = 0; i < classes; i++) { int classid = msg.ReadUBitLong(size); char classname[255]; char dtname[255]; msg.ReadString(classname, sizeof(classname)); msg.ReadString(dtname, sizeof(dtname)); printf("Classname: %s | DTname: %s | ClassID: %i\n", classname, dtname, classid); } printf("svc_ClassInfo end\n"); } else { printf("Received svc_ClassInfo, classes: %i\n", classes); } return true; } if (type == 11)//svc_SetPause { int state = msg.ReadOneBit(); printf("Received svc_SetPause, state: %i\n", state); return true; } if (type == 12)//svc_CreateStringTable { char name[500]; msg.ReadString(name, sizeof(name)); short maxentries = msg.ReadWord(); unsigned int size = (int)(log2(maxentries) + 1); int entries = msg.ReadUBitLong(size); int bits = msg.ReadVarInt32(); int userdata = msg.ReadOneBit(); //if (m_bUserDataFixedSize) //{ // buffer.WriteUBitLong(m_nUserDataSize, 12); // buffer.WriteUBitLong(m_nUserDataSizeBits, 4); //} if (userdata == 1) { int userdatasize = msg.ReadUBitLong(12); int userdatabits = msg.ReadUBitLong(4); } int compressed = msg.ReadOneBit(); if (bits < 1) return true; unsigned int sz = (bits / 8) + 2; unsigned char* data = new unsigned char[sz*8]; //TODO: why is 8x the space required. (heap corruption otherwise) msg.ReadBits(data, bits); bool really_compressed = false; unsigned int actual_size; CLZSS s; printf("\n"); { unsigned int remaining = sz; unsigned char* ptr = data; ptr += + 8; // unknown data remaining -= 8; really_compressed = s.IsCompressed(ptr); actual_size = really_compressed?s.GetActualSize(ptr):0; if (really_compressed) { unsigned char* data_dec = new unsigned char[actual_size]; s.Uncompress(ptr, data_dec); // probably reuses the substring system used by old stringtable implementation. Shift the data by a bit or two to see the first entry of modelprecache for example. hexdump(data_dec, actual_size); delete[] data_dec; printf("\n"); } } hexdump(data, bits / 8); delete[] data; printf("Received svc_CreateStringTable, name: %s | maxentries: %i | size: %d | entries: %i | compressed: %i,%s,%i | " "bits: %i (%i bytes)\n", name, maxentries, size, entries, compressed, really_compressed?"y":"n", actual_size, bits,bits/8); return true; } if (type == 13)//svc_UpdateStringTable { int tableid = msg.ReadUBitLong((int)MAX_TABLES_BITS); int changed = 1; if (msg.ReadOneBit() != 0) { changed = msg.ReadWord(); } int bits = msg.ReadUBitLong(20); if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); delete[] data; printf("Received svc_UpdateStringTable, id: %i | changed: %i | bits: %i\n", tableid, changed, bits); return true; } if (type == 14)//svc_VoiceInit { char codec[255]; msg.ReadString(codec, sizeof(codec)); int quality = msg.ReadByte(); printf("Received svc_VoiceInit, codec: %s | quality: %i\n", codec, quality); return true; } if (type == 15)//svc_VoiceData { //FIX ME PLEASE int client = msg.ReadByte(); int proximity = msg.ReadByte(); int bits = msg.ReadWord(); if (msg.GetNumBitsLeft() < bits) bits = msg.GetNumBitsLeft(); //if (!bits)//its just us talking // return true; printf("Received svc_VoiceData, client: %i | proximity: %i | bits: %i\n", client, proximity, bits); char* voicedata = new char[(bits+8)/8]; msg.ReadBits(voicedata, bits); if(voicetoggle) { char*uncompressed = new char[0xFFFF]; unsigned int uncompressed_size = 0; EVoiceResult worked = clientaudio->DecompressVoice(voicedata, bits / 8, uncompressed, 0xFFFF, &uncompressed_size, clientaudio->GetVoiceOptimalSampleRate()); if (worked == k_EVoiceResultOK) { HWAVEOUT hWaveOut = 0; WAVEHDR header = { uncompressed, uncompressed_size, 0, 0, 0, 0, 0, 0 }; WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, clientaudio->GetVoiceOptimalSampleRate(), clientaudio->GetVoiceOptimalSampleRate()*2, 2, 16, sizeof(WAVEFORMATEX) }; waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL); waveOutPrepareHeader(hWaveOut, &header, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &header, sizeof(WAVEHDR)); waveOutUnprepareHeader(hWaveOut, &header, sizeof(WAVEHDR)); waveOutClose(hWaveOut); }else{ printf("RIP AUDIO: %i\n", worked); delete[] uncompressed; } delete[] voicedata; } if (voicemimic) { senddata.WriteUBitLong(10, 6); senddata.WriteWord(bits); senddata.WriteBits(voicedata, bits); } delete[] voicedata; return true; } if (type == 17)//svc_Sounds { int reliable = msg.ReadOneBit(); int num = 1; int bits = 0; if (reliable == 0) { num = msg.ReadUBitLong(8); bits = msg.ReadUBitLong(16); } else { bits = msg.ReadUBitLong(8); } if (bits < 1) return true; char*data = new char[bits]; msg.ReadBits(data, bits); delete[] data; //printf("Received svc_Sounds, reliable: %i, bits: %i, num: %i\n", reliable, bits, num); return true; } if (type == 18)//svc_SetView { int ent = msg.ReadUBitLong(MAX_EDICT_BITS); printf("Received svc_SetView, ent: %i\n", ent); return true; } if (type == 19)//svc_FixAngle { int relative = msg.ReadOneBit(); float x = msg.ReadBitAngle(16); float y = msg.ReadBitAngle(16); float z = msg.ReadBitAngle(16); printf("Received svc_FixAngle, x:%f y: %f z: %f | relative: %i\n", x, y, z, relative); return true; } if (type == 20)//svc_CrosshairAngle { int p = msg.ReadUBitLong(16); int y = msg.ReadUBitLong(16); int r = msg.ReadUBitLong(16); printf("Received svc_CrosshairAngle p: %d y: %d r: %d\n", p, y, r); } if (type == 21)//svc_BSPDecal { Vector vec; msg.ReadBitVec3Coord(vec); int texture = msg.ReadUBitLong(9); int useentity = msg.ReadOneBit(); int ent = 0; int modulation = 0; if (useentity == 1) { ent = msg.ReadUBitLong(MAX_EDICT_BITS); modulation = msg.ReadUBitLong(12);//fix me } int lowpriority = msg.ReadOneBit(); printf("Received svc_BSPDecal: pos: %f:%f:%f | tex: %i | useent: %i\n", vec.x, vec.y, vec.z, texture, useentity); return true; } if (type == 23)//svc_UserMessage { int msgtype = msg.ReadByte(); int bits = msg.ReadUBitLong(MAX_USERMESSAGE_BITS); if (bits < 1) return true; char* data = new char[bits]; msg.ReadBits(data, bits); bf_read userMsg(data, bits); if (msgtype == 3) { int client = userMsg.ReadByte(); //int bWantsChat = userMsg.ReadByte(); char readstr[MAX_USER_MSG_DATA]; userMsg.ReadString(readstr, sizeof(readstr)); int something3 = userMsg.ReadByte(); //idk, sometimes 1, might be bchat int something4 = userMsg.ReadByte(); //seems to be 1 when teamchatting int something5 = userMsg.ReadByte(); //idk, sometimes 1 printf("Chat message: %i:%s __ %i\n", client, readstr, userMsg.GetNumBytesLeft()); delete[] data; return true; } if (msgtype == 5) { userMsg.ReadByte(); char readstr[MAX_USER_MSG_DATA]; userMsg.ReadString(readstr, sizeof(readstr)); printf("umsg print: %s\n", readstr); } if (msgtype == 44)//nwvar { int c**k = userMsg.ReadUBitLong(32); int cock2 = userMsg.ReadByte(); char str[255]; userMsg.ReadString(str, sizeof(str)); char str2[255]; userMsg.ReadString(str2, sizeof(str2)); //printf("cock1:%i cock2: %i name: %s str2: %s | left: %i\n", c**k, cock2, str, str2, userMsg.GetNumBytesLeft()); delete[] data; return true; } delete[] data; printf("Received svc_UserMessage, type: %i | bits: %i\n", msgtype, bits); return true; } if (type == 24)//svc_EntityMessage { int ent = msg.ReadUBitLong(MAX_EDICT_BITS); int entclass = msg.ReadUBitLong(MAX_SERVER_CLASS_BITS); int bits = msg.ReadUBitLong(MAX_ENTITYMESSAGE_BITS); if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); delete[] data; printf("Received svc_EntityMessage, ent: %i | class: %i | bits: %i\n", ent, entclass, bits); return true; } if (type == 25)//svc_GameEvent { int bits = msg.ReadUBitLong(11); if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); delete[] data; printf("Received svc_GameEvent, bits: %i\n", bits); return true; } if (type == 26)//svc_PacketEntities { int max = msg.ReadUBitLong(MAX_EDICT_BITS); int isdelta = msg.ReadOneBit(); int delta = -1; if (isdelta) { delta = msg.ReadLong(); } int baseline = msg.ReadUBitLong(1); int changed = msg.ReadUBitLong(MAX_EDICT_BITS); int bits = msg.ReadUBitLong(20); int updatebaseline = msg.ReadOneBit(); int bytes = bits / 8; if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); delete[] data; //printf("Received svc_PacketEntities, max: %i | isdelta: %i | line: %i | changed: %i | bits: %i | update: %i\n", max, isdelta, baseline, changed, bits, updatebaseline); return true; } if (type == 27)//svc_TempEntities { int num = msg.ReadUBitLong(8); int bits = msg.ReadVarInt32(); if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); delete[] data; printf("Received svc_TempEntities, num: %i | bits: %i\n", num, bits); if (bconnectstep) { /* leynet_tcp tcp; printf("TCP TIME2\n"); tcp.OpenConnection(serverip, serverport);//is that really the tcp port printf("CONNECTED: %s __ %i\n", serverip, serverport); senddata.Reset(); memset(netsendbuffer, 0xFF, NETBUFFER_SIZE); tcp.Send("\x09", 1); Sleep(100); senddata.WriteUBitLong(10, 6); senddata.WriteWord(0xFFFF); for (int i = 0; i < 1000; i++) { senddata.WriteOneBit(i%2==0); } tcp.Send((const char*)senddata.GetData(), senddata.GetNumBytesWritten()); */ senddata.WriteUBitLong(6, 6); senddata.WriteByte(6); senddata.WriteLong(netchan->m_iServerCount); senddata.WriteUBitLong(11, 6); senddata.WriteLong(net_tick); senddata.WriteUBitLong(1, 1); Sleep(2000); bconnectstep = 0; } return true; } if (type == 28)//svc_Prefetch { int index = msg.ReadUBitLong(4); printf("Received svc_Prefetch, index: %i\n", index); return true; } if (type == 30)//svc_GameEventList { int num = msg.ReadUBitLong(9); int bits = msg.ReadUBitLong(20); if (bits < 1) return true; char *data = new char[bits]; msg.ReadBits(data, bits); printf("Received svc_GameEventList, num: %i | bits: %i\n", num, bits); delete[] data; return true; } if (type == 31)//svc_GetCvarValue { int cookie = msg.ReadUBitLong(32); char cvarname[255]; msg.ReadString(cvarname, sizeof(cvarname)); printf("Received svc_GetCvarValue, cookie: %i | name: %s\n", cookie, cvarname); return true; } if (type == 33)//svc_GMod_ServerToClient { int bits = msg.ReadUBitLong(20); int type = msg.ReadByte(); // 4= probably server telling about files if (bits < 1) return true; if (bits < 0) { printf("Received svc_Gmod_ServerToClient || Invalid!\n"); return true; } if (type == 4) { char* data = new char[bits]; int id = msg.ReadWord(); int toread = bits - 8 - 16; if (toread > 0) { msg.ReadBits(data, toread); } printf("Received svc_GMod_ServerToClient, type: %i | bits: %i | id: %i \n", type, bits, id); delete[] data; return true; } if(type==3) { printf("Received svc_GMod_ServerToClient, type: %i | bits: %i\n", type, bits); return true; } if (type == 0) { int id = msg.ReadWord(); char* data = new char[bits]; int toread = bits - 8 - 16; if (toread > 0) { msg.ReadBits(data, toread); } delete[] data; printf("Received svc_GMod_ServerToClient, type: %i | bits: %i\n", type, bits); return true; } printf("Received svc_GMod_ServerToClient, type: %i | bits: %i\n", type, bits); return true; } return false; }