/* Plugin Template generated by Pawn Studio */ #include #include #define LP_VERSION "2.1" new sql_id[MAXPLAYERS]; new Handle:g_NextMap = INVALID_HANDLE; new Handle:g_ChangeMap = INVALID_HANDLE; new Handle:g_NominationMap = INVALID_HANDLE; new Handle:cv_serverid, Handle:cv_price_snomination, Handle:cv_price_mapvote, Handle:cv_price_nextmap, Handle:cv_price_changelevel; new Handle:cv_price_rs_1day, Handle:cv_price_rs_7day, Handle:cv_price_rs_14day, Handle:cv_price_rs_30day; new Handle:cv_quaterplayers, Handle:cv_halfplayers, Handle:cv_morethenhalf; new Handle:cv_snomination, Handle:cv_mapvote, Handle:cv_nextmap, Handle:cv_changelevel; new Handle:cv_rsflags, Handle:cv_immu; //new Handle:cv_removeall; new price_snomination, price_mapvote, price_nextmap, price_changelevel; new price_rs_1day, price_rs_7day, price_rs_14day, price_rs_30day; new quaterplayers, halfplayers, morethenhalf; new bool:en_snomination = true; new bool:en_mapvote = true; new bool:en_nextmap = true; new bool:en_changelevel = true; new String:rsflags[50]; //new bool:removeflags; new rsimmunity; new String:MapchangeTo[100]; new serverid; new Handle:dbcon = INVALID_HANDLE; public Plugin:myinfo = { name = "Loyalty System", author = "Chefe", description = "System that gives players points for their playtime.", version = LP_VERSION, url = "http://forums.alliedmods.net/showthread.php?t=154296" } public OnPluginStart() { CreateTimer(300.0, ForgivePoints, _, TIMER_REPEAT); CreateTimer(86400.0, CleanDatabase, _, TIMER_REPEAT); RegConsoleCmd("sm_lp", CommandLP, "Shows you your loyalty points!"); RegAdminCmd("sm_lp_refresh", CommandRefresh, ADMFLAG_CONFIG, "Refresh lp-settings"); CreateConVar("sm_lp_version", LP_VERSION, "Shows current plugin version.", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD); cv_serverid = CreateConVar("sm_lp_serverid", "0", "Unique serverid if you run the plugin on multipe servers. If not, ignore this."); cv_price_snomination = CreateConVar("sm_lp_price_snomination", "25", "Set the price clients must pay for a super-nomination."); cv_price_mapvote = CreateConVar("sm_lp_price_mapvote", "100", "Set the price clients must pay for forcing a mapvote."); cv_price_nextmap = CreateConVar("sm_lp_price_nextmap", "150", "Set the price clients must pay for setting the nextmap."); cv_price_changelevel = CreateConVar("sm_lp_price_changelevel", "200", "Set the price clients must pay to change the map."); cv_price_rs_1day = CreateConVar("sm_lp_rs_price_1day", "100", "Set the price clients have to pay for 1 day reserved slot access."); cv_price_rs_7day = CreateConVar("sm_lp_rs_price_7day", "450", "Set the price clients have to pay for 7 day reserved slot access."); cv_price_rs_14day = CreateConVar("sm_lp_rs_price_14day", "900", "Set the price clients have to pay for 14 day reserved slot access."); cv_price_rs_30day = CreateConVar("sm_lp_rs_price_30day", "1500", "Set the price clients have to pay for 30 day reserved slot access."); cv_quaterplayers = CreateConVar("sm_lp_quaterplayers", "3", "Set points if playercount <= quater of maxclients."); cv_halfplayers = CreateConVar("sm_lp_halfplayers", "2", "Set points if playercount between quater and half of maxclients."); cv_morethenhalf = CreateConVar("sm_lp_morethenhalf", "1", "Set points if playercount more then half of maxclients."); cv_snomination = CreateConVar("sm_lp_snomination", "1", "Enable/disable snomination option in lp menu."); cv_mapvote = CreateConVar("sm_lp_mapvote", "1", "Enable/disable mapvote option in lp menu."); cv_nextmap = CreateConVar("sm_lp_nextmap", "1", "Enable/disable nextmap option in lp menu."); cv_changelevel = CreateConVar("sm_lp_changelevel", "1", "Enable/disable changelevel option in lp menu."); cv_rsflags = CreateConVar("sm_lp_flags", "a", "Flags a player get if he buys a reserved slot. Make sure that the flags are correct, they wont get checked!"); //cv_removeall = CreateConVar("sm_lp_removeallflags", "0", "Enable/disable that only the flags set in sm_lp_flags or all flags get removed when the reserved slot expire."); cv_immu = CreateConVar("sm_lp_immunity", "5", "Set the immunity the reserved slot player will have"); AutoExecConfig(true); SQL_TConnect(DBInit, "default"); } public DBInit(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE) { LogError("[LP] Database connection failed: %s", error); SetFailState("Unable to connect to database, look for more infos in the error logs!"); return; } dbcon = hndl; } public OnConfigsExecuted() { price_snomination = GetConVarInt(cv_price_snomination); price_mapvote = GetConVarInt(cv_price_mapvote); price_nextmap = GetConVarInt(cv_price_nextmap); price_changelevel = GetConVarInt(cv_price_changelevel); price_rs_1day = GetConVarInt(cv_price_rs_1day); price_rs_7day = GetConVarInt(cv_price_rs_7day); price_rs_14day = GetConVarInt(cv_price_rs_14day); price_rs_30day = GetConVarInt(cv_price_rs_30day); quaterplayers = GetConVarInt(cv_quaterplayers); halfplayers = GetConVarInt(cv_halfplayers); morethenhalf = GetConVarInt(cv_morethenhalf); serverid = GetConVarInt(cv_serverid); en_snomination = GetConVarBool(cv_snomination); en_mapvote = GetConVarBool(cv_mapvote); en_nextmap = GetConVarBool(cv_nextmap); en_changelevel = GetConVarBool(cv_changelevel); GetConVarString(cv_rsflags, rsflags, sizeof(rsflags)); //removeflags = GetConVarBool(cv_removeall); rsimmunity = GetConVarInt(cv_immu); } public OnMapStart() { MapchangeTo = NULL_STRING; g_NextMap = BuildMapMenu(Menu_NextMap); g_ChangeMap = BuildMapMenu(Menu_ChangeMap); g_NominationMap = BuildMapMenu(Menu_NominateMap); } public OnMapEnd() { if (g_NextMap != INVALID_HANDLE) { CloseHandle(g_NextMap); g_NextMap = INVALID_HANDLE; } if (g_ChangeMap != INVALID_HANDLE) { CloseHandle(g_ChangeMap); g_ChangeMap = INVALID_HANDLE; } if (g_NominationMap != INVALID_HANDLE) { CloseHandle(g_NominationMap); g_NominationMap = INVALID_HANDLE; } } Handle:BuildMapMenu(MenuHandler:handel) { new Handle:file = OpenFile("mapcycle.txt", "rt"); if (file == INVALID_HANDLE) { return INVALID_HANDLE; } new Handle:menu = CreateMenu(handel); new String:mapname[255]; while (!IsEndOfFile(file) && ReadFileLine(file, mapname, sizeof(mapname))) { if (mapname[0] == ';' || !IsCharAlpha(mapname[0])) { continue; } new len = strlen(mapname); for (new i=0; i 0) { LogError("LP Query error: %s", error); return; } if (IsClientConnected(data)) { if (SQL_GetRowCount(hndl) == 0) { new String:auth[100]; GetClientAuthString(data, auth, sizeof(auth)); new String:createsql[250]; Format(createsql, sizeof(createsql), "INSERT INTO lp(steamid, points, ingameid, ingame) VALUES ('%s',0,%i,1)", auth, serverid); SQL_TQuery(dbcon, InitDBCheck2, createsql, data); } else { SQL_FetchRow(hndl); sql_id[data] = SQL_FetchInt(hndl, 0); new String:updatesql[255]; Format(updatesql, sizeof(updatesql), "UPDATE lp SET ingame = 1, ingameid = %i WHERE id = %i", serverid, sql_id[data]); SQL_TQuery(dbcon, EmptyResultSet, updatesql); } } } public InitDBCheck2(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE || strlen(error) > 0) { LogError("LP Query error: %s", error); return; } if (IsClientConnected(data)) { new String:auth[100]; GetClientAuthString(data, auth, sizeof(auth)); new String:sqlstring[255]; Format(sqlstring, sizeof(sqlstring), "SELECT id FROM lp WHERE steamid = '%s'", auth); SQL_TQuery(dbcon, InitDBCheck3, sqlstring, data); } } public InitDBCheck3(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE || strlen(error) > 0) { LogError("LP Query error: %s", error); return; } if (IsClientConnected(data)) { SQL_FetchRow(hndl); sql_id[data] = SQL_FetchInt(hndl, 0); } } public OnClientDisconnect(client) { new String:sqlstring[255]; Format(sqlstring, sizeof(sqlstring), "UPDATE lp SET ingame = 0 WHERE id = %i", sql_id[client]); SQL_TQuery(dbcon, EmptyResultSet, sqlstring); sql_id[client] = -1; } public Action:CommandRefresh(client, args) { RefreshSet(); ReplyToCommand(client, "[LP] Settings refreshed"); return Plugin_Handled; } public Action:CommandLP(client, args) { new String:s_menu1[100]; Format(s_menu1, sizeof(s_menu1), "SNomination (%i lp)", price_snomination); new String:s_menu2[100]; Format(s_menu2, sizeof(s_menu2), "Force Mapvote (%i lp)", price_mapvote); new String:s_menu3[100]; Format(s_menu3, sizeof(s_menu3), "Set Nextmap (%i lp)", price_nextmap); new String:s_menu4[100]; Format(s_menu4, sizeof(s_menu4), "Change Map (%i lp)", price_changelevel); new Handle:menu = CreateMenu(MenuHandler); SetMenuTitle(menu, "Loyalty Point System"); AddMenuItem(menu, "1", "Show LP"); if (en_snomination) { AddMenuItem(menu, "2", s_menu1); } if (en_mapvote) { AddMenuItem(menu, "3", s_menu2); } if (en_nextmap) { AddMenuItem(menu, "4", s_menu3); } if (en_changelevel) { AddMenuItem(menu, "5", s_menu4); } if (HaveClientRS(client)) { new String:s_menu5[100]; new client_rsmin = GetRSMIN(client); if (client_rsmin <= 60) { Format(s_menu5, sizeof(s_menu5), "Your RS access end in %i min", GetRSMIN(client)); } else if (client_rsmin <= 1440) { Format(s_menu5, sizeof(s_menu5), "Your RS access end in %i h", GetRSMIN(client)/60); } else { Format(s_menu5, sizeof(s_menu5), "Your RS access end in %i d", GetRSMIN(client)/1440); } AddMenuItem(menu, "6", s_menu5, ITEMDRAW_DISABLED); } else { AddMenuItem(menu, "7", "Reserved Slot"); } DisplayMenu(menu, client, MENU_TIME_FOREVER); return Plugin_Handled; } public MenuHandler(Handle:menu, MenuAction:action, param1, param2) { if (action == MenuAction_Select) { new String:info[32]; GetMenuItem(menu, param2, info, sizeof(info)); switch(StringToInt(info)) { case 1: { new lp = GetLP(param1); PrintToChat(param1, "\x04[LP]\x01 %N, you have %i LP!", param1, lp); } case 2: { new lp = GetLP(param1); if (lp >= price_snomination) { DisplayMenu(g_NominationMap, param1, MENU_TIME_FOREVER); } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i to nominate!", lp, price_snomination); } } case 3: { new lp = GetLP(param1); if (lp >= price_mapvote) { RemoveLP(param1, price_mapvote); PrintToChatAll("\x04[LP]\x01 %N forced Mapvote!", param1) InitiateMapChooserVote(MapChange_Instant); } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i to force Mapvote!", lp, price_mapvote); } } case 4: { new lp = GetLP(param1); if (lp >= price_nextmap) { DisplayMenu(g_NextMap, param1, MENU_TIME_FOREVER); } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i to set Nextmap!", lp, price_nextmap); } } case 5: { new lp = GetLP(param1); if (lp >= price_changelevel) { DisplayMenu(g_ChangeMap, param1, MENU_TIME_FOREVER); } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i to change the Map!", lp, price_changelevel); } } case 7: { new String:rs_menu1[100]; Format(rs_menu1, sizeof(rs_menu1), "1 Day (%i lp)", price_rs_1day); new String:rs_menu2[100]; Format(rs_menu2, sizeof(rs_menu2), "7 Days (%i lp)", price_rs_7day); new String:rs_menu3[100]; Format(rs_menu3, sizeof(rs_menu3), "14 Days (%i lp)", price_rs_14day); new String:rs_menu4[100]; Format(rs_menu4, sizeof(rs_menu4), "30 Days (%i lp)", price_rs_30day); new Handle:menu2 = CreateMenu(MenuRS); SetMenuTitle(menu2, "Select RS-time"); AddMenuItem(menu2, "1", rs_menu1); AddMenuItem(menu2, "2", rs_menu2); AddMenuItem(menu2, "3", rs_menu3); AddMenuItem(menu2, "4", rs_menu4); DisplayMenu(menu2, param1, MENU_TIME_FOREVER); } } } else if (action == MenuAction_End) { CloseHandle(menu); } } public Menu_NextMap(Handle:menu, MenuAction:action, param1, param2) { if (action == MenuAction_Select) { new String:info[32]; GetMenuItem(menu, param2, info, sizeof(info)); RemoveLP(param1, price_nextmap); PrintToChatAll("\x04[LP]\x01 %N changed the nextmap to %s!", param1, info); SetNextMap(info); } else if (action == MenuAction_End) { CloseHandle(menu); g_NextMap = BuildMapMenu(Menu_NextMap); } } public Menu_ChangeMap(Handle:menu, MenuAction:action, param1, param2) { if (action == MenuAction_Select) { new String:info[32]; GetMenuItem(menu, param2, info, sizeof(info)); RemoveLP(param1, price_changelevel); PrintToChatAll("\x04[LP]\x01 %N forced mapchange to %s!", param1, info); if (!strcmp(MapchangeTo, NULL_STRING, false)) { MapchangeTo = info; CreateTimer(5.0, Timer_Changelevel); } else { PrintToChat(param1, "\x04[LP]\x01 Mapchange already in progress"); } } else if (action == MenuAction_End) { CloseHandle(menu); g_ChangeMap = BuildMapMenu(Menu_ChangeMap); } } public Action:Timer_Changelevel(Handle:timer) { ForceChangeLevel(MapchangeTo, "LP"); } public Menu_NominateMap(Handle:menu, MenuAction:action, param1, param2) { if (action == MenuAction_Select) { new String:info[32]; GetMenuItem(menu, param2, info, sizeof(info)); RemoveLP(param1, price_snomination); PrintToChatAll("\x04[LP]\x01 %N nominated %s!", param1, info); NominateMap(info, true, 0); } else if (action == MenuAction_End) { CloseHandle(menu); g_NominationMap = BuildMapMenu(Menu_NominateMap); } } public MenuRS(Handle:menu, MenuAction:action, param1, param2) { if (action == MenuAction_Select) { new String:info[32]; GetMenuItem(menu, param2, info, sizeof(info)); new lp = GetLP(param1) switch(StringToInt(info)) { case 1: { if (lp >= price_rs_1day) { RemoveLP(param1, price_rs_1day) GiveRS(param1, 1440); if (IsClientInGame(param1)) { PrintToChat(param1, "\x04[LP]\x01 You have bought RS! If Server is full, connect by console to use your reserved slot.") } } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i for 1 Day RS!", lp, price_rs_1day); } } case 2: { if (lp >= price_rs_7day) { RemoveLP(param1, price_rs_7day) GiveRS(param1, 10080); if (IsClientInGame(param1)) { PrintToChat(param1, "\x04[LP]\x01 You have bought RS! If server is full, connect via console to use your reserved slot.") } } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i for 7 Days RS!", lp, price_rs_7day); } } case 3: { if (lp >= price_rs_14day) { RemoveLP(param1, price_rs_14day) GiveRS(param1, 20160); if (IsClientInGame(param1)) { PrintToChat(param1, "\x04[LP]\x01 You have bought RS! If Server is full, connect by console to use your reserved slot.") } } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i for 14 Days RS!", lp, price_rs_14day); } } case 4: { if (lp >= price_rs_30day) { RemoveLP(param1, price_rs_30day) GiveRS(param1, 43200); if (IsClientInGame(param1)) { PrintToChat(param1, "\x04[LP]\x01 You have bought RS! If Server is full, connect by console to use your reserved slot.") } } else { PrintToChat(param1, "\x04[LP]\x01 You have %i lp, but you need %i for 30 Days RS!", lp, price_rs_30day); } } } } else if (action == MenuAction_End) { CloseHandle(menu); } } public Action:ForgivePoints(Handle:timer) { new players = GetClientCount(false); new players_max = GetMaxClients(); if (players <= (players_max / 4)) { GiveLP(quaterplayers); } else if (players <= (players_max / 2)) { GiveLP(halfplayers); } else { GiveLP(morethenhalf); } RemoveRSMIN(5); PrintToChatAll("\x04[LP]\x01 This Server is running the \x04LP\x01 System to reward Players. Type \x04!lp\x01 to get up the LP menu with more options."); } public Action:CleanDatabase(Handle:timer) { RemoveInaktivePlayers(); } GetLP(client) { new String:sqlstring[255]; Format(sqlstring, sizeof(sqlstring), "SELECT points FROM lp WHERE id = %i", sql_id[client]); SQL_LockDatabase(dbcon); new Handle:sql = SQL_Query(dbcon, sqlstring); SQL_FetchRow(sql); new lp = SQL_FetchInt(sql, 0); CloseHandle(sql); SQL_UnlockDatabase(dbcon); return lp; } GiveLP(amount) { new String:sqlstring[256]; Format(sqlstring, sizeof(sqlstring), "UPDATE lp SET points = points + %i WHERE ingame = 1 AND ingameid = %i", amount, serverid); SQL_TQuery(dbcon, EmptyResultSet, sqlstring); } RemoveLP(client, amount) { if (IsClientInGame(client)) { new String:steamid[50]; GetClientAuthString(client, steamid, sizeof(steamid)) new String:sqlstring[256]; Format(sqlstring, sizeof(sqlstring), "UPDATE lp SET points = points - %i WHERE id = %i", amount, sql_id[client]); SQL_TQuery(dbcon, EmptyResultSet, sqlstring); } } GiveRS(client, min) { if (IsClientInGame(client)) { // In die lp-Datenbank eintragen (Step 1) new String:steamid[50]; GetClientAuthString(client, steamid, sizeof(steamid)) new String:sqlstring[256]; Format(sqlstring, sizeof(sqlstring), "UPDATE lp SET rs = 1, rsmin = %i, serverid = %i WHERE steamid = '%s'", min, serverid, steamid); SQL_TQuery(dbcon, EmptyResultSet, sqlstring); // In die sm-Admin Datenbank eintragen (Step 2) new String:sqlstring2[256]; Format(sqlstring2, sizeof(sqlstring2), "INSERT INTO sm_admins(authtype, identity, flags, name, immunity) VALUES ('steam' ,'%s', '%s', '%N', %i)", steamid, rsflags, client, rsimmunity); SQL_TQuery(dbcon, EmptyResultSet, sqlstring2); ServerCommand("sm_reloadadmins"); } } bool:HaveClientRS(client) { if (IsClientInGame(client)) { new String:sqlstring[255]; Format(sqlstring, sizeof(sqlstring), "SELECT id FROM lp WHERE id = %i AND rs = '1'", sql_id[client]); SQL_LockDatabase(dbcon); new Handle:sql = SQL_Query(dbcon, sqlstring); new rs_bool = SQL_GetRowCount(sql); CloseHandle(sql); SQL_UnlockDatabase(dbcon); if (rs_bool) { return true; } else { return false; } } return true; } GetRSMIN(client) { new String:steamid[50]; GetClientAuthString(client, steamid, sizeof(steamid)); new String:sqlstring[200]; Format(sqlstring, sizeof(sqlstring), "SELECT rsmin FROM lp WHERE steamid = '%s'", steamid); SQL_LockDatabase(dbcon); new Handle:sql = SQL_Query(dbcon, sqlstring); SQL_UnlockDatabase(dbcon); SQL_FetchRow(sql); new rsmin = SQL_FetchInt(sql, 0); CloseHandle(sql); return rsmin; } RemoveRSMIN(min) { new String:sqlstring[150]; Format(sqlstring, sizeof(sqlstring), "UPDATE lp SET rsmin = rsmin - %i WHERE rs = 1 AND serverid = %i", min, serverid); SQL_TQuery(dbcon, EmptyResultSet, sqlstring); new String:sqlstring2[150]; Format(sqlstring2, sizeof(sqlstring2), "SELECT steamid FROM lp WHERE rs = 1 AND serverid = %i AND rsmin <= 0", serverid); SQL_TQuery(dbcon, RemoveInPl1, sqlstring2); } public RemoveInPl1(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE || strlen(error) > 0) { LogError("LP Query error: %s", error); return; } new number = SQL_GetRowCount(hndl); if (number != 0) { for (new a = 0; a != number; a++) { new String:steamid[256]; SQL_FetchRow(hndl); SQL_FetchString(hndl, 0, steamid, sizeof(steamid)); // Aus der LP-Datenbank austragen (Step 1) new String:sqlstr[256]; Format(sqlstr, sizeof(sqlstr), "UPDATE lp SET rs = 0, rsmin = 0, serverid = 0 WHERE steamid = '%s'", steamid); SQL_TQuery(dbcon, EmptyResultSet, sqlstr); // Aus der SM-Admin Datenbank austragen (Step 2) new String:sqlstr2[150]; /* if (removeflags) { Format(sqlstr2, sizeof(sqlstr2), "DELETE FROM sm_admins WHERE identity = '%s'", steamid); } else { Format(sqlstr3, sizeof(sqlstr3), "UPDATE sm_admins SET flags = replace(flags, '%s' WHERE identity = '%s'", steamid); } */ Format(sqlstr2, sizeof(sqlstr2), "DELETE FROM sm_admins WHERE identity = '%s'", steamid); SQL_TQuery(dbcon, EmptyResultSet, sqlstr2); } ServerCommand("sm_reloadadmins"); } } RemoveInaktivePlayers() { new String:sqlstr[150]; Format(sqlstr, sizeof(sqlstr), "DELETE FROM lp WHERE points <= 0 AND ingame = 0 AND rs = 0"); SQL_TQuery(dbcon, EmptyResultSet, sqlstr); } RefreshSet() { price_snomination = GetConVarInt(cv_price_snomination); price_mapvote = GetConVarInt(cv_price_mapvote); price_nextmap = GetConVarInt(cv_price_nextmap); price_changelevel = GetConVarInt(cv_price_changelevel); price_rs_1day = GetConVarInt(cv_price_rs_1day); price_rs_7day = GetConVarInt(cv_price_rs_7day); price_rs_14day = GetConVarInt(cv_price_rs_14day); price_rs_30day = GetConVarInt(cv_price_rs_30day); quaterplayers = GetConVarInt(cv_quaterplayers); halfplayers = GetConVarInt(cv_halfplayers); morethenhalf = GetConVarInt(cv_morethenhalf); serverid = GetConVarInt(cv_serverid); en_snomination = GetConVarBool(cv_snomination); en_mapvote = GetConVarBool(cv_mapvote); en_nextmap = GetConVarBool(cv_nextmap); en_changelevel = GetConVarBool(cv_changelevel); GetConVarString(cv_rsflags, rsflags, sizeof(rsflags)); //removeflags = GetConVarBool(cv_removeall); rsimmunity = GetConVarInt(cv_immu); } public EmptyResultSet(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE || strlen(error) > 0) { LogError("LP Query error: %s", error); return; } }