Advertisement
Guest User

Untitled

a guest
Jan 19th, 2015
385
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.35 KB | None | 0 0
  1. local lootCmd = "char loot";
  2.  
  3. -- Maximum loot shown on use of the loot command.
  4. local MAX_LOOT_VALUE = 20;
  5. -- Maximum results the loot table may contain, default: 500.
  6. -- NOTE: This is the lua table, so everything will be stored as normal.
  7. local MAX_RESULTS = 500;
  8.  
  9. -- Player events.
  10. local PLAYER_EVENT_ON_USE_COMMAND = 42;
  11. local PLAYER_EVENT_ON_LOOT_ITEM = 32;
  12.  
  13. -- Userdata types.
  14. local USERDATA_TYPE_PLAYER = 4;
  15.  
  16. -- Pre-set queries.
  17. local QUERY_SELECT_DEFAULT = 1;
  18. local QUERY_SELECT_SPECIFIC = 2;
  19. local QUERY_INSERT_DEFAULT = 3;
  20. local QUERY_SELECT_COUNT = 4;
  21. local query = {
  22.     [[ 
  23.         SELECT date_time, player, item_id, item_count
  24.         FROM player_loots
  25.         WHERE player = '%s';
  26.     ]],
  27.     [[ 
  28.         SELECT date_time, player, item_id, item_count
  29.         FROM player_loots
  30.         WHERE player = '%s' AND item_id = '%d';
  31.     ]],
  32.     [[ 
  33.         INSERT INTO player_loots
  34.         VALUES ('%d', '%s', '%d', '%d', '%d', '0');
  35.     ]],
  36.     [[     
  37.         SELECT count(*)
  38.         FROM player_loots
  39.     ]],
  40.     __call = function (tab, n, ...)
  41.         return CharDBQuery(tab[n]:format(...));
  42.     end
  43. };
  44. setmetatable(query, query);
  45. -- We need the length of the player_loots table.
  46. local tableLength = query(QUERY_SELECT_COUNT):GetUInt32(0)+1;
  47.  
  48. -- Function to convert the time from the
  49. -- database to an actual date.
  50. local function getDate(date_time)
  51.     return os.date("%x [%X]", date_time);
  52. end
  53.  
  54. -- Table that will hold the loot information.
  55. local mtLoot = {
  56.     -- Function that will keep the table clean,
  57.     -- we don't want to many entries ...
  58.     __newindex = function (tab, key, value)
  59.         if #tab >= MAX_RESULTS then
  60.             collectgarbage();
  61.         end
  62.         rawset(tab, key, value);
  63.     end,
  64.     -- Weak table so collectgarbage() can do its job.
  65.     __mode = 'kv',
  66.     -- Should we notify that we are cleaning the table?
  67.     __gc = function() print"Wiping the loot table." end,
  68.     __len = function (t)
  69.         local length = 0;
  70.         for _, tab in pairs(t) do
  71.             length = length + #tab;
  72.         end
  73.         return length;
  74.     end
  75. };
  76. local lootTable = setmetatable({}, mtLoot);
  77. local function prepareResult(result)
  78.     -- If the result is nil, we should return it
  79.     -- right away to prevent errors.
  80.     if result == nil then  return {}; end
  81.     -- Result isn't nil so we can process the results.
  82.     local lootTable = {};
  83.     for i=1, result:GetRowCount() do
  84.         lootTable[i] = {
  85.             getDate(result:GetUInt32(0)),       -- date_time
  86.             result:GetString(1),                -- player
  87.             GetItemLink(result:GetUInt32(2)),   -- item_id
  88.             result:GetUInt8(3)                  -- item_count
  89.         };
  90.         -- No point in loading data we won't use ...
  91.         if #lootTable == MAX_LOOT_VALUE then
  92.             break;
  93.         end
  94.         result:NextRow();
  95.     end
  96.     return lootTable;
  97. end
  98. -- Function to properly load the result. We will check if the result
  99. -- exists already first, if not, then and only then we will run a query
  100. -- to get the results we need.
  101. local function loadResult(player, item)
  102.     local key = player .. (item or "");
  103.     local result = lootTable[key];
  104.     if type(result) ~= "table" then
  105.         -- Which query shall we use?
  106.         local q;
  107.         if type(item) == "number" then
  108.             q = QUERY_SELECT_SPECIFIC;
  109.         else -- No item so default select query.
  110.             q = QUERY_SELECT_DEFAULT;
  111.         end
  112.         -- Grabbing and assigning the result.
  113.         result = prepareResult(query(q, player, item));
  114.         lootTable[key] = result;
  115.     end
  116.     return result;
  117. end
  118.  
  119. local function getLoot(target, item, ...)
  120.     local result;
  121.     if tonumber(item) then
  122.         result = loadResult(target, tonumber(item));
  123.     elseif select(1, ...) then
  124.         return {}; -- If there are arguments in ... then we have to many arguments.
  125.     else -- No extra arguments ...
  126.         result = loadResult(target);
  127.     end
  128.     return type(result) == "table" and result or {};
  129. end
  130. -- Function that will handle the command.
  131. local lootMsg = "%s: %s has looted item: %s, count: %d";
  132. local function handleLootCommand(plr, msg)
  133.     local arguments = {};
  134.     if msg:find(lootCmd .. " ") == 1 then
  135.         -- Grabbing the words and processing them.
  136.         msg:gsub(lootCmd .. " ", ""):gsub("(%w+)", function (w) table.insert(arguments, w) end);
  137.     end
  138.     -- We want to run this if there aren't any extra arguments but also
  139.     -- if the only argument is an item id.
  140.     if msg:find(lootCmd .. " ") ~= 1 or #arguments == 1 and tonumber(arguments[1]) then
  141.         local target = plr:GetSelection();
  142.         -- Making sure we have a target, and that target
  143.         -- is a player .. creatures don't loot >.>.
  144.         if type(target) ~= "userdata" then
  145.             return plr:SendAreaTriggerMessage("No target selected.");
  146.         elseif target:GetTypeId() ~= USERDATA_TYPE_PLAYER then
  147.             return plr:SendAreaTriggerMessage("Invalid target selected, expecting a player.");
  148.         end
  149.         table.insert(arguments, 1, target:GetName());
  150.     end
  151.     -- Search for loot, if any..., and send the information
  152.     -- to the requester.
  153.     local loot = getLoot(table.unpack(arguments));
  154.     if next(loot) == nil then
  155.         return plr:SendAreaTriggerMessage("No results found.");
  156.     end
  157.     for index, value in ipairs(loot) do
  158.         plr:SendBroadcastMessage(lootMsg:format(table.unpack(value)));
  159.         -- Letting the requester know there is more loot, we
  160.         -- just won't show it.
  161.         if index == MAX_LOOT_VALUE then
  162.             plr:SendBroadcastMessage(("More than %d results found, aborting."):format(MAX_LOOT_VALUE));
  163.         end
  164.     end
  165.     return false;
  166. end
  167. -- A separate function to handle the command,
  168. -- so we only have to use 'return false' once.
  169. local function onLootCommand(_, plr, msg)
  170.     if msg:find(lootCmd) == 1 then
  171.         if plr:GetGMRank() > 0 then
  172.             handleLootCommand(plr, msg);
  173.         end
  174.         return false;
  175.     end
  176.     -- We don't want any message displaying now,
  177.     -- do we?
  178. end
  179.  
  180. -- Function to catch every item that is looted
  181. -- and put the information in the database.
  182. local function registerPlayerLoot(_, plr, item, count)
  183.     local date_time = os.time();
  184.     local player = plr:GetName();
  185.     local entry = item:GetEntry();
  186.     -- Gotta add it to the existing table aswell.
  187.     if lootTable[player] ~= nil then
  188.         table.insert(lootTable[player], {getDate(date_time), player, GetItemLink(entry), count});
  189.     end
  190.     if lootTable[player .. entry] ~= nil then
  191.         table.insert(lootTable[player .. entry], {getDate(date_time), player, GetItemLink(entry), count});
  192.     end
  193.     -- Insert the data into the database and incrementing tableLength
  194.     -- by one so it stays valid.
  195.     query(QUERY_INSERT_DEFAULT, tableLength, player, date_time, entry, count);
  196.     tableLength = tableLength + 1;
  197. end
  198.  
  199. RegisterPlayerEvent(PLAYER_EVENT_ON_USE_COMMAND, onLootCommand);
  200. RegisterPlayerEvent(PLAYER_EVENT_ON_LOOT_ITEM, registerPlayerLoot);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement