//--------------------------------------------------------------------------- bool NIF_Files::CreateUIElements() { NiSample::CreateUIElements(); // The Log is a text output used by all NiSample derived classes AddLogEntry("Press ESC or Start + Select to quit"); return true; }
void NCLDebug::Log(const std::string text, ...) { va_list args; va_start(args, text); char buf[1024]; int needed = vsnprintf_s(buf, 1023, _TRUNCATE, text.c_str(), args); va_end(args); int length = (needed < 0) ? 1024 : needed; AddLogEntry(Vector3(0.4f, 1.0f, 0.6f), std::string(buf, (size_t)length)); }
void BotControl::Think (void) { // this function calls think () function for all available at call moment bots, and // try to catch internal error if such shit occurs float thinkFps = yb_thinkfps.GetFloat (); // check ranges if (thinkFps <= 0.0f || thinkFps > 40.0f) { thinkFps = 22.0f; AddLogEntry (true, LOG_ERROR, "Value of yb_thinkfps should be greater than zero and lower than 40."); yb_thinkfps.SetFloat (thinkFps); } thinkFps = (1.0f / thinkFps) * 0.88f; for (int i = 0; i < engine->GetMaxClients (); i++) { if (m_bots[i] != null) { if (m_bots[i]->m_thinkTimer <= engine->GetTime ()) { // use these try-catch blocks to prevent server crashes when error occurs #if !defined (NDEBUG) && !defined (_DEBUG) try { m_bots[i]->Think (); } catch (...) { // error occurred. kick off all bots and then print a warning message RemoveAll (); ServerPrintNoTag ("**** INTERNAL BOT ERROR! PLEASE SHUTDOWN AND RESTART YOUR SERVER! ****"); } #else m_bots[i]->Think (); #endif m_bots[i]->m_thinkTimer = engine->GetTime () + thinkFps; } } } }
void NCLDebug::LogE(const char* filename, int linenumber, const std::string text, ...) { //Error Format: //<text> // -> <line number> : <file name> va_list args; va_start(args, text); char buf[1024]; int needed = vsnprintf_s(buf, 1023, _TRUNCATE, text.c_str(), args); va_end(args); int length = (needed < 0) ? 1024 : needed; Log(Vector3(1.0f, 0.25f, 0.25f), "[ERROR] %s:%d", filename, linenumber); AddLogEntry(Vector3(1.0f, 0.5f, 0.5f), "\t \x01 \"" + std::string(buf, (size_t)length) + "\""); std::cout << endl; }
Bot::Bot (edict_t *bot, int skill, int personality, int team, int member) { // this function does core operation of creating bot, it's called by CreateBot (), // when bot setup completed, (this is a bot class constructor) char rejectReason[128]; int clientIndex = ENTINDEX (bot); memset (this, 0, sizeof (Bot)); pev = VARS (bot); if (bot->pvPrivateData != null) FREE_PRIVATE (bot); bot->pvPrivateData = null; bot->v.frags = 0; // create the player entity by calling MOD's player function BotControl::CallGameEntity (&bot->v); // set all info buffer keys for this bot char *buffer = GET_INFOKEYBUFFER (bot); SET_CLIENT_KEYVALUE (clientIndex, buffer, "model", ""); SET_CLIENT_KEYVALUE (clientIndex, buffer, "rate", "3500.000000"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_updaterate", "20"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lw", "1"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lc", "1"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "tracker", "0"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_dlmax", "128"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "friends", "0"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "dm", "0"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "_ah", "0"); if (yb_tagbots.GetBool ()) SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", "1"); SET_CLIENT_KEYVALUE (clientIndex, buffer, "_vgui_menus", "0"); memset (rejectReason, 0, sizeof (rejectReason)); // reset the reject reason template string MDLL_ClientConnect (bot, "fakeclient", FormatBuffer ("192.168.1.%d", ENTINDEX (bot) + 100), rejectReason); if (!IsNullString (rejectReason)) { AddLogEntry (true, LOG_WARNING, "Server refused '%s' connection (%s)", STRING (bot->v.netname), rejectReason); ServerCommand ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it bot->v.flags |= FL_KILLME; } if (IsDedicatedServer () && engine->GetDeveloperLevel () > 0) { if (engine->GetDeveloperLevel () == 2) { ServerPrint ("Server requiring authentication"); ServerPrint ("Client '%s' connected", STRING (bot->v.netname)); ServerPrint ("Adr: 127.0.0.%d:27005", ENTINDEX (bot) + 100); } ServerPrint ("Verifying and uploading resources..."); ServerPrint ("Custom resources total 0 bytes"); ServerPrint (" Decals: 0 bytes"); ServerPrint ("----------------------"); ServerPrint ("Resources to request: 0 bytes"); } MDLL_ClientPutInServer (bot); bot->v.flags = 0; bot->v.flags |= FL_FAKECLIENT | FL_CLIENT; // set this player as fakeclient // initialize all the variables for this bot... m_notStarted = true; // hasn't joined game yet m_startAction = CMENU_IDLE; m_moneyAmount = 0; m_logotypeIndex = engine->RandomInt (0, 5); // initialize msec value m_msecNum = m_msecDel = 0.0f; m_msecInterval = engine->GetTime (); m_msecVal = static_cast <uint8_t> (g_pGlobals->frametime * 1000.0f); m_msecBuiltin = engine->RandomInt (1, 4); // assign how talkative this bot will be m_sayTextBuffer.chatDelay = engine->RandomFloat (3.8f, 10.0f); m_sayTextBuffer.chatProbability = engine->RandomInt (1, 100); m_notKilled = false; m_skill = skill; m_weaponBurstMode = BURST_DISABLED; m_lastThinkTime = engine->GetTime (); m_frameInterval = engine->GetTime (); bot->v.idealpitch = bot->v.v_angle.x; bot->v.ideal_yaw = bot->v.v_angle.y; bot->v.yaw_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed); bot->v.pitch_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed); switch (personality) { case 1: m_personality = PERSONALITY_RUSHER; m_baseAgressionLevel = engine->RandomFloat (0.7f, 1.0f); m_baseFearLevel = engine->RandomFloat (0.0f, 0.4f); break; case 2: m_personality = PERSONALITY_CAREFUL; m_baseAgressionLevel = engine->RandomFloat (0.0f, 0.4f); m_baseFearLevel = engine->RandomFloat (0.7f, 1.0f); break; default: m_personality = PERSONALITY_NORMAL; m_baseAgressionLevel = engine->RandomFloat (0.4f, 0.7f); m_baseFearLevel = engine->RandomFloat (0.4f, 0.7f); break; } memset (&m_ammoInClip, 0, sizeof (m_ammoInClip)); memset (&m_ammo, 0, sizeof (m_ammo)); m_currentWeapon = 0; // current weapon is not assigned at start m_voicePitch = engine->RandomInt (166, 250) / 2; // assign voice pitch // copy them over to the temp level variables m_agressionLevel = m_baseAgressionLevel; m_fearLevel = m_baseFearLevel; m_nextEmotionUpdate = engine->GetTime () + 0.5f; // just to be sure m_actMessageIndex = 0; m_pushMessageIndex = 0; // assign team and class m_wantedTeam = team; m_wantedClass = member; NewRound (); }
void NetworkMsg::Execute (void *p) { if (m_message == NETMSG_UNDEFINED) return; // no message or not for bot, return // some needed variables static uint8_t r, g, b; static uint8_t enabled; static int damageArmor, damageTaken, damageBits; static int killerIndex, victimIndex, playerIndex; static int index, numPlayers; static int state, id, clip; static Vector damageOrigin; static WeaponProperty weaponProp; // now starts of netmessage execution switch (m_message) { case NETMSG_VGUI: // this message is sent when a VGUI menu is displayed. if (m_state == 0) { switch (PTR_TO_INT (p)) { case GMENU_TEAM: m_bot->m_startAction = CMENU_TEAM; break; case GMENU_TERRORIST: case GMENU_COUNTER: m_bot->m_startAction = CMENU_CLASS; break; } } break; case NETMSG_SHOWMENU: // this message is sent when a text menu is displayed. if (m_state < 3) // ignore first 3 fields of message break; if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select? m_bot->m_startAction = CMENU_CLASS; else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu? m_bot->m_startAction = CMENU_CLASS; break; case NETMSG_WLIST: // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used. switch (m_state) { case 0: strcpy (weaponProp.className, PTR_TO_STR (p)); break; case 1: weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1 break; case 2: weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1 break; case 5: weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon break; case 6: weaponProp.position = PTR_TO_INT (p); // position in slot break; case 7: weaponProp.id = PTR_TO_INT (p); // weapon ID break; case 8: weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???) g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information... break; } break; case NETMSG_CURWEAPON: // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased switch (m_state) { case 0: state = PTR_TO_INT (p); // state of the current weapon (WTF???) break; case 1: id = PTR_TO_INT (p); // weapon ID of current weapon break; case 2: clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon if (id <= 31) { if (state != 0) m_bot->m_currentWeapon = id; // ammo amount decreased ? must have fired a bullet... if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip) { // time fired with in burst firing time ? if (m_bot->m_timeLastFired + 1.0f > engine->GetTime ()) m_bot->m_burstShotsFired++; m_bot->m_timeLastFired = engine->GetTime (); // remember the last bullet time } m_bot->m_ammoInClip[id] = clip; } break; } break; case NETMSG_AMMOX: // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable! switch (m_state) { case 0: index = PTR_TO_INT (p); // ammo index (for type of ammo) break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away break; } break; case NETMSG_AMMOPICK: // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots // don't really need pictures since they don't have any eyes anyway. switch (m_state) { case 0: index = PTR_TO_INT (p); break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); break; } break; case NETMSG_DAMAGE: // this message gets sent when the bots are getting damaged. switch (m_state) { case 0: damageArmor = PTR_TO_INT (p); break; case 1: damageTaken = PTR_TO_INT (p); break; case 2: damageBits = PTR_TO_INT (p); if (damageArmor > 0 || damageTaken > 0) m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits); break; } break; case NETMSG_MONEY: // this message gets sent when the bots money amount changes if (m_state == 0) m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money break; case NETMSG_STATUSICON: switch (m_state) { case 0: enabled = PTR_TO_BYTE (p); break; case 1: if (strcmp (PTR_TO_STR (p), "defuser") == 0) m_bot->m_hasDefuser = (enabled != 0); else if (strcmp (PTR_TO_STR (p), "buyzone") == 0) { m_bot->m_inBuyZone = (enabled != 0); // try to equip in buyzone m_bot->EquipInBuyzone (0); } else if (strcmp (PTR_TO_STR (p), "vipsafety") == 0) m_bot->m_inVIPZone = (enabled != 0); else if (strcmp (PTR_TO_STR (p), "c4") == 0) m_bot->m_inBombZone = (enabled == 2); break; } break; case NETMSG_DEATH: // this message sends on death switch (m_state) { case 0: killerIndex = PTR_TO_INT (p); break; case 1: victimIndex = PTR_TO_INT (p); break; case 2: if (killerIndex != 0 && killerIndex != victimIndex) { edict_t *killer = INDEXENT (killerIndex); edict_t *victim = INDEXENT (victimIndex); if (FNullEnt (killer) || FNullEnt (victim)) break; // need to send congrats on well placed shot for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ()) && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == GetTeam (bot->GetEntity ()) && GetTeam (killer) != GetTeam (victim)) { if (killer == g_hostEntity) bot->HandleChatterMessage ("#Bot_NiceShotCommander"); else bot->HandleChatterMessage ("#Bot_NiceShotPall"); break; } } // SyPB Pro P.15 if (GetGameMod () == 0) { // notice nearby to victim teammates, that attacker is near for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && FNullEnt (bot->m_enemy) && GetTeam (killer) != GetTeam (victim)) { bot->m_actualReactionTime = 0.0f; bot->m_seeEnemyTime = engine->GetTime (); bot->m_enemy = killer; bot->m_lastEnemy = killer; bot->m_lastEnemyOrigin = killer->v.origin; } } } Bot *bot = g_botManager->GetBot (killer); // is this message about a bot who killed somebody? if (bot != null) bot->m_lastVictim = victim; else // did a human kill a bot on his team? { Bot *iter = g_botManager->GetBot (victim); if (iter != null) { if (GetTeam (killer) == GetTeam (victim)) iter->m_voteKickIndex = killerIndex; iter->m_notKilled = false; } } } break; } break; case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang) switch (m_state) { case 3: r = PTR_TO_BYTE (p); break; case 4: g = PTR_TO_BYTE (p); break; case 5: b = PTR_TO_BYTE (p); break; case 6: m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p)); break; } break; case NETMSG_HLTV: // round restart in steam cs switch (m_state) { case 0: numPlayers = PTR_TO_INT (p); break; case 1: if (numPlayers == 0 && PTR_TO_INT (p) == 0) RoundInit (); break; } break; case NETMSG_RESETHUD: #if 0 if (m_bot != null) m_bot->NewRound (); #endif break; case NETMSG_TEXTMSG: if (m_state == 1) { if (FStrEq (PTR_TO_STR (p), "#CTs_Win") || FStrEq (PTR_TO_STR (p), "#Bomb_Defused") || FStrEq (PTR_TO_STR (p), "#Terrorists_Win") || FStrEq (PTR_TO_STR (p), "#Round_Draw") || FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") || FStrEq (PTR_TO_STR (p), "#Target_Saved") || FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") || FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") || FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") || FStrEq (PTR_TO_STR (p), "#VIP_Escaped") || FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") || FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") || FStrEq (PTR_TO_STR (p), "#Target_Bombed") || FStrEq (PTR_TO_STR (p), "#Game_Commencing") || FStrEq (PTR_TO_STR (p), "#Game_will_restart_in")) { g_roundEnded = true; if (FStrEq (PTR_TO_STR (p), "#Game_Commencing")) g_isCommencing = true; if (FStrEq (PTR_TO_STR (p), "#CTs_Win")) g_botManager->SetLastWinner (TEAM_COUNTER); // update last winner for economics if (FStrEq (PTR_TO_STR (p), "#Terrorists_Win")) g_botManager->SetLastWinner (TEAM_TERRORIST); // update last winner for economics g_waypoint->SetBombPosition (true); } else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted")) { g_bombPlanted = true; g_bombSayString = true; g_timeBombPlanted = engine->GetTime (); for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ())) { bot->DeleteSearchNodes (); bot->ResetTasks (); if (engine->RandomInt (0, 100) < 85 && GetTeam (bot->GetEntity ()) == TEAM_COUNTER) bot->ChatterMessage (Chatter_WhereIsTheBomb); } } g_waypoint->SetBombPosition (); } else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire")) m_bot->m_weaponBurstMode = BURST_ENABLED; else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto")) m_bot->m_weaponBurstMode = BURST_DISABLED; } break; case NETMSG_SCOREINFO: switch (m_state) { case 0: playerIndex = PTR_TO_INT (p); break; case 4: if (playerIndex >= 0 && playerIndex <= engine->GetMaxClients ()) { if (PTR_TO_INT (p) == 1) g_clients[playerIndex - 1].realTeam = TEAM_TERRORIST; else if (PTR_TO_INT (p) == 2) g_clients[playerIndex - 1].realTeam = TEAM_COUNTER; g_clients[playerIndex - 1].team = g_clients[playerIndex - 1].realTeam; } break; } break; case NETMSG_BARTIME: if (m_state == 0) { if (PTR_TO_INT (p) > 0) m_bot->m_hasProgressBar = true; // the progress bar on a hud else if (PTR_TO_INT (p) == 0) m_bot->m_hasProgressBar = false; // no progress bar or disappeared } break; default: AddLogEntry (true, LOG_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message); } m_state++; // and finally update network message state }
__declspec(dllexport) BOOL SoaronModuleFunc(void) { SQLHDBC hdbc; HSTMT hstmt; unsigned int NumOfLinks, LinkID; WSADATA wd; SQLRETURN sqlret; HANDLE hHeap; FTNAddr LinkAddr; wchar_t Ip[256]; lpLinksCheckInfo LinksTable; WSAEVENT * EventsTable; WSANETWORKEVENTS evt; unsigned int i, j; int res; ADDRINFOW *result = NULL; ADDRINFOW hints; wchar_t LogStr[255]; memset(&hints, 0, sizeof(hints)); LinkAddr.point = 0; NumOfLinks = 0; SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); return FALSE;//fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); AddLogEntry(L"Checking binkp links alive"); //get links info SQLExecDirectW(hstmt, L"update Links set DialOut=0 where datediff(minute,LastSessionTime,GetDate())>40 and LinkType=1", SQL_NTS); sqlret = SQLExecDirectW(hstmt, L"select count(*) from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_ULONG, &NumOfLinks, 0, NULL); } } SQLCloseCursor(hstmt); if (NumOfLinks == 0) goto exit; hHeap = HeapCreate(HEAP_NO_SERIALIZE, 8192, 0); LinksTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, NumOfLinks*sizeof(LinksCheckInfo)); EventsTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(WSAEVENT)*NumOfLinks); i = 0; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; WSAStartup(MAKEWORD(2, 2), &wd); sqlret = SQLExecDirectW(hstmt, L"select LinkID,Zone,Net,Node, Ip from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLBindCol(hstmt, 1, SQL_C_ULONG, &LinkID, 0, NULL); SQLBindCol(hstmt, 2, SQL_C_USHORT, &(LinkAddr.zone), 0, NULL); SQLBindCol(hstmt, 3, SQL_C_USHORT, &(LinkAddr.net), 0, NULL); SQLBindCol(hstmt, 4, SQL_C_USHORT, &(LinkAddr.node), 0, NULL); SQLBindCol(hstmt, 5, SQL_C_WCHAR, Ip, 512, NULL); sqlret = SQLFetch(hstmt); while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { // res = GetAddrInfoW(Ip, L"24554", &hints, &result); if (res == 0) { memcpy(&(LinksTable[i].sa), result->ai_addr, sizeof(struct sockaddr_in)); // printf("%u %u %S %u.%u.%u.%u\n", i,LinkID, Ip, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b1, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b2, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b3, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b4); LinksTable[i].LinkID = LinkID; LinksTable[i].LinkAddr.FullAddr = LinkAddr.FullAddr; LinksTable[i].s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); EventsTable[i] = WSACreateEvent(); WSAEventSelect(LinksTable[i].s, EventsTable[i], FD_CONNECT); FreeAddrInfoW(result); ++i; } else { wsprintfW(LogStr,L"%u:%u/%u: Ip address %s cannot be resolved", LinkAddr.zone, LinkAddr.net, LinkAddr.node,Ip); AddLogEntry(LogStr); } sqlret = SQLFetch(hstmt); } } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_UNBIND); NumOfLinks = i; for (i = 0; i < NumOfLinks; i++) { connect(LinksTable[i].s, (struct sockaddr *)&(LinksTable[i].sa), sizeof(struct sockaddr_in)); } j = 0; SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); SQLPrepareW(hstmt, L"Update Links set DialOut=1 where LinkID=?", SQL_NTS); while (j < NumOfLinks) { res = WSAWaitForMultipleEvents(NumOfLinks, EventsTable, FALSE, WSA_INFINITE, FALSE); WSAEnumNetworkEvents(LinksTable[res].s, EventsTable[res], &evt); shutdown(LinksTable[res].s, SD_BOTH); closesocket(LinksTable[res].s); if (evt.iErrorCode[FD_CONNECT_BIT] == 0) { wsprintfW(LogStr, L"%u:%u/%u: OK", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); LinkID = LinksTable[res].LinkID; SQLExecute(hstmt); } else { switch (evt.iErrorCode[FD_CONNECT_BIT]) { case WSAECONNREFUSED: wsprintfW(LogStr, L"%u:%u/%u: Connection refused", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; case WSAETIMEDOUT: wsprintfW(LogStr, L"%u:%u/%u: Connection timed out", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; default:wsprintfW(LogStr, L"%u:%u/%u: Unknown connection error", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); } } AddLogEntry(LogStr); ++j; } // for (j = 0; j < NumOfLinks; j++) { WSACloseEvent(EventsTable[j]); } SQLFreeStmt(hstmt, SQL_RESET_PARAMS); // WSACleanup(); HeapDestroy(hHeap); exit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); AddLogEntry(L"Links alive check done"); SetEvent(cfg.hLinksUpdateEvent); return TRUE; }
void LogSessionAndSendNetmailToLink(lpFTNAddr lpLinkAddr, unsigned char SoftwareCode) { SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN sqlret; SQLLEN cb; HANDLE hHeap; HANDLE hPktFile; wchar_t tmpPktFileName[MAX_PATH], finalPktFileName[MAX_PATH], FileboxDirName[MAX_PATH]; wchar_t LogStr[255]; unsigned int PktNumber; unsigned int LinkID; NetmailOutQueue NOQ; char PktPwd[9]; hHeap = HeapCreate(HEAP_NO_SERIALIZE, 16384, 0); SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); return; //fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->zone), 0, NULL); SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->net), 0, NULL); SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->node), 0, NULL); SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->point), 0, NULL); SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_UTINYINT , SQL_TINYINT, 0, 0, &SoftwareCode, 0, NULL); SQLExecDirectW(hstmt, L"{?=call sp_GetLinkIdForNetmailRouting(?,?,?,?,?)}", SQL_NTS); NOQ.First = NULL; NOQ.Last = NULL; SQLFreeStmt(hstmt, SQL_RESET_PARAMS); if (SoftwareCode != 1) goto exit; if (LinkID != 0) { //netmail out// memset(PktPwd, 0, 9); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); sqlret = SQLExecDirectW(hstmt, L"select PktPassword from Links where LinkID=?", SQL_NTS);// if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb); } } SQLCloseCursor(hstmt); EnterCriticalSection(&NetmailRouteCritSect); sqlret = SQLExecDirectW(hstmt, L"select Netmail.MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,NetmailOutbound where Netmail.MessageID=NetmailOutbound.MessageID and NetmailOutbound.ToLinkID=? order by Netmail.MessageID", SQL_NTS);// if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NOQ); } SQLFreeStmt(hstmt, SQL_RESET_PARAMS); if (NOQ.First != NULL) { PktNumber = GetPktNumber(hstmt); wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.0", cfg.FileboxesDir, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node); wsprintfW(tmpPktFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber); wsprintfW(finalPktFileName, L"%s\\%08X.PKT", FileboxDirName, PktNumber); hPktFile = CreateFileW(tmpPktFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); WritePktHeader(hPktFile, &(cfg.MyAddr),lpLinkAddr, PktPwd); // while (NOQ.First != NULL) { lpNetmailMessage lpTmp; // wsprintfW(LogStr, L"Dynamic netmail %u:%u/%u.%u -> %u:%u/%u.%u thru %u:%u/%u", NOQ.First->FromAddr.zone, NOQ.First->FromAddr.net, NOQ.First->FromAddr.node, NOQ.First->FromAddr.point, NOQ.First->ToAddr.zone, NOQ.First->ToAddr.net, NOQ.First->ToAddr.node, NOQ.First->ToAddr.point, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node); AddLogEntry(LogStr); WriteNetmailMessage(hPktFile, hHeap, NOQ.First); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &(NOQ.First->MessageID), 0, NULL); sqlret = SQLExecDirectW(hstmt, L"{call sp_NetmailMessageSent(?)}", SQL_NTS); SQLFreeStmt(hstmt, SQL_RESET_PARAMS); // lpTmp = NOQ.First->NextMsg; HeapFree(hHeap, 0, NOQ.First->MsgText); if (NOQ.First->ReplyTo != NULL) HeapFree(hHeap, 0, NOQ.First->ReplyTo); if (NOQ.First->MsgId != NULL) HeapFree(hHeap, 0, NOQ.First->MsgId); HeapFree(hHeap, 0, NOQ.First->Subject); HeapFree(hHeap, 0, NOQ.First->ToName); HeapFree(hHeap, 0, NOQ.First->FromName); HeapFree(hHeap, 0, NOQ.First); NOQ.First = lpTmp; } if (hPktFile != INVALID_HANDLE_VALUE) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName, NULL); MoveFileExW(tmpPktFileName, finalPktFileName, MOVEFILE_COPY_ALLOWED); } // } LeaveCriticalSection(&NetmailRouteCritSect); } exit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); HeapDestroy(hHeap); }
DWORD WINAPI NetmailOutThread(LPVOID param) { SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN sqlret; SQLLEN cb; HANDLE hHeap; FTNAddr LastAddr; HANDLE hPktFile; wchar_t tmpFileName[MAX_PATH], finalPktFileName[MAX_PATH],FileboxDirName[MAX_PATH]; wchar_t LogStr[255]; unsigned int PktNumber; char PktPwd[9]; NetmailOutQueue NDOQ; int WaitTime; int result; HANDLE hEvent[2]; InterlockedIncrement(&(cfg.ThreadCount)); WaitTime=INFINITE; hEvent[0]=cfg.hExitEvent; hEvent[1]=cfg.hNetmailOutEvent; AddLogEntry(L"Netmail out thread started"); loop: result=WaitForMultipleObjects(2,hEvent,FALSE,WaitTime); if (result==WAIT_TIMEOUT) { SQLFreeHandle(SQL_HANDLE_STMT,hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC,hdbc); WaitTime=INFINITE; HeapDestroy(hHeap); goto loop; } if (WaitTime==INFINITE) { hHeap=HeapCreate(HEAP_NO_SERIALIZE,16384,0); SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret=SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); goto threadexit; //fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); WaitTime=10000; } switch(result) { case (WAIT_OBJECT_0): { goto threadexit; } case (WAIT_OBJECT_0+1): { NDOQ.First=NULL; NDOQ.Last=NULL; EnterCriticalSection(&NetmailRouteCritSect); SQLExecDirectW(hstmt, L"execute sp_DirectNetmail", SQL_NTS); // обработать директный нетмейл для использующих FTN Service линков LeaveCriticalSection(&NetmailRouteCritSect); sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail where direct=1 and sent=0 and Locked=0 order by ToZone,ToNet,ToNode,MessageID",SQL_NTS); if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt,hHeap,&NDOQ); } sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,MyAka where direct=0 and sent=0 and Locked=0 and MyAka.Point=0 and Netmail.ToPoint<>0 and Netmail.ToZone=MyAka.Zone and Netmail.ToNet=MyAka.Net and Netmail.ToNode=MyAka.Node order by ToPoint,MessageID",SQL_NTS); if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NDOQ); } sqlret = SQLExecDirectW(hstmt, L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,Links where direct=0 and sent=0 and Locked=0 and Netmail.ToZone=Links.Zone and Netmail.ToNet=Links.Net and Netmail.ToNode=Links.Node and Links.NetmailDirect<>0 and Links.LinkType=2 order by Links.LinkID,MessageID", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NDOQ); } LastAddr.FullAddr=0; hPktFile=INVALID_HANDLE_VALUE; while (NDOQ.First!=NULL) { lpNetmailMessage lpTmp; wsprintfW(LogStr,L"Direct netmail From %u:%u/%u.%u To %u:%u/%u.%u",NDOQ.First->FromAddr.zone,NDOQ.First->FromAddr.net,NDOQ.First->FromAddr.node,NDOQ.First->FromAddr.point,NDOQ.First->ToAddr.zone,NDOQ.First->ToAddr.net,NDOQ.First->ToAddr.node,NDOQ.First->ToAddr.point); AddLogEntry(LogStr); if (LastAddr.FullAddr!=NDOQ.First->ToAddr.FullAddr) { if(LastAddr.FullAddr!=0) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName,NULL); MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED); } LastAddr.FullAddr=NDOQ.First->ToAddr.FullAddr; //create file PktNumber=GetPktNumber(hstmt); wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.%u", cfg.FileboxesDir, NDOQ.First->ToAddr.zone, NDOQ.First->ToAddr.net, NDOQ.First->ToAddr.node, NDOQ.First->ToAddr.point); wsprintfW(tmpFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber); wsprintfW(finalPktFileName,L"%s\\%08X.PKT",FileboxDirName,PktNumber); hPktFile=CreateFileW(tmpFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL); memset(PktPwd, 0, 9); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.zone), 0, NULL); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.net), 0, NULL); SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.node), 0, NULL); SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.point), 0, NULL); sqlret = SQLExecDirectW(hstmt, L"Select PktPassword from Links where Zone=? and Net=? and Node=? and Point=?", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb); } } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_RESET_PARAMS); WritePktHeader(hPktFile,&(cfg.MyAddr),&(NDOQ.First->ToAddr),PktPwd); } // WriteNetmailMessage(hPktFile,hHeap,NDOQ.First); // SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&(NDOQ.First->MessageID),0,NULL); sqlret=SQLExecDirectW(hstmt,L"{call sp_NetmailMessageSent(?)}",SQL_NTS); SQLFreeStmt(hstmt,SQL_RESET_PARAMS); // lpTmp=NDOQ.First->NextMsg; HeapFree(hHeap,0,NDOQ.First->MsgText); if (NDOQ.First->ReplyTo!=NULL) HeapFree(hHeap,0,NDOQ.First->ReplyTo); if (NDOQ.First->MsgId!=NULL) HeapFree(hHeap,0,NDOQ.First->MsgId); HeapFree(hHeap,0,NDOQ.First->Subject); HeapFree(hHeap,0,NDOQ.First->ToName); HeapFree(hHeap,0,NDOQ.First->FromName); HeapFree(hHeap,0,NDOQ.First); NDOQ.First=lpTmp; } if (hPktFile!=INVALID_HANDLE_VALUE) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName,NULL); MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED); } // EnterCriticalSection(&NetmailRouteCritSect); SQLExecDirectW(hstmt, L"EXECUTE sp_RouteNetmail",SQL_NTS); LeaveCriticalSection(&NetmailRouteCritSect); SetEvent(cfg.hMailerCallGeneratingEvent); //make polls sqlret = SQLExecDirectW(hstmt, L"select Zone,Net,Node from Links,NetmailOutbound,Netmail where Links.LinkID=NetmailOutbound.ToLinkID and Netmail.MessageID=NetmailOutbound.MessageID and Netmail.Locked=0 and Links.DialOut<>0 and Links.LinkType<=2 and Links.Point=0", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { unsigned short zone, net, node; SQLBindCol(hstmt, 1, SQL_C_USHORT, &zone, 0, NULL); SQLBindCol(hstmt, 2, SQL_C_USHORT, &net, 0, NULL); SQLBindCol(hstmt, 3, SQL_C_USHORT, &node, 0, NULL); sqlret = SQLFetch(hstmt); while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { if (zone == cfg.MyAddr.zone) { wsprintfW(LogStr,L"Creating poll to %u:%u/%u", zone, net, node); AddLogEntry(LogStr); swprintf_s(tmpFileName, MAX_PATH, L"%s\\%04hX%04hX.CLO", cfg.BinkOutboundDir, net, node); hPktFile = CreateFileW(tmpFileName, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); CloseHandle(hPktFile); // } sqlret = SQLFetch(hstmt); } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_UNBIND); } } } goto loop; threadexit: _InterlockedDecrement(&(cfg.ThreadCount)); SetEvent(cfg.hThreadEndEvent); return 0; }