hackersrage
Member
- Joined
- Nov 18, 2012
- Messages
- 342
[Plugin] Recruit-A-Friend
Recruit-A-Friend *placeholder*
This plugin will allow for at minimum two bots running for questing, granting levels, summoning, and ideally party mounting. Initially, this will support only two bots linked to each other.
Release Status - Alpha: Framework has been written, and plugin starts/stops without error.
DOWNLOAD INSTRUCTIONS
SVN Location
** Current team members are listed below **
C# CORE WRAPPER
Real World Example of Some Features
Some of the features will be ported from the Recruit-A-Friend LUA plugin (included in this post at the bottom for reference only )
THE LUA CODE BELOW IS FOR REFERENCE ONLY
Recruit-A-Friend WoW LUA Plugin
Recruit-A-Friend *placeholder*
This plugin will allow for at minimum two bots running for questing, granting levels, summoning, and ideally party mounting. Initially, this will support only two bots linked to each other.
Release Status - Alpha: Framework has been written, and plugin starts/stops without error.
DOWNLOAD INSTRUCTIONS
SVN Location
Code:
https://subversion.assembla.com/svn/recruitafriend/trunk
- Download and install the latest version of TortoiseSVN for your operating system
- Create a new folder named RecruitAFriend in your HonorBuddy/Plugins directory.
- Right click the new folder you just created, and select SVN Checkout.... If you have the above SVN URL in your clipboard, it will be automatically filled in, if not, then copy/paste the SVN Location above into the box under URL Repository.
- Make sure Fully Recursive, and HEAD Revision are selected, then click [ OK ]
- Launch WoW, and sign in.
- Launch HonorBuddy
- In HonorBuddy - Click Plugins, and put a checkmark beside RecruitAFriend. If you do not see this option, click on the Recompile.. button at the bottom of the Plugins window, and then you should be able to.
- Launch another session of WoW and sign in, and do the same for HonorBuddy.
- Make sure that each HonorBuddy session is set to QuestBuddy, and have the same quest profiles loaded.
- Click start on each session of HonorBuddy and enjoy the Recruit-A-Friend bonus experience on Quest turn ins.
** Current team members are listed below **
C# CORE WRAPPER
Code:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;
using System.Linq;
using Styx;
using Styx.Common;
using Styx.Plugins;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
namespace RecruitAFriend
{
enum EnumLootThreshold
{
Uncommon =1,
Rare = 2,
Epic = 3
}
enum EnumLootMethod
{
Group,
FreeForAll,
Master,
NeedBeforeGreed,
RoundRobin
}
struct StructureLootMethod
{
EnumLootMethod lootmethod;
dynamic masterlooterPartyID;
dynamic masterlooterRaidID;
}
// Battle.Net Structures
struct StructureBattleNetInfo {
int presenceID;
int toonID;
string currentBroadcast;
bool bnetAFK;
bool bnetDND;
}
struct StructureBattleNetFriendInfo
{
int presenceID;
string givenName;
string surname;
string toonName;
int toonID;
string client;
bool isOnline;
}
struct StructureBattleNetFriendInfoFromID
{
int presenceID;
string givenName;
string surname;
string toonName;
int toonID;
string client;
bool isOnline;
DateTime lastOnline;
bool isAFK;
bool isDND;
string messageText;
string noteText;
}
struct StructureBattleNetToonInfo
{
dynamic unused1;
dynamic unused2;
string gameName;
string realmName;
string faction;
dynamic unused3;
string race;
string charclass;
dynamic unused4;
string zoneName;
int level;
}
// ******************************
// ** PLUGIN CORE **
// ******************************
public class RecruitAFriend : HBPlugin
{
// Name of the plugin
public override string Name
{
get { return "RecruitAFriend"; }
}
// Give credits to the developer(s)
public override string Author
{
get { return "RecruitAFriend Team"; }
}
// What is the version
public override Version Version
{
get { return new Version(0, 0, 0, 0); }
}
// Enable plugin "settings" button
public override bool WantButton
{
get { return false; }
}
// Set caption of "settings" button
public override string ButtonText
{
get { return "Settings"; }
}
// What happens when a user clicks the "settings" button
public override void OnButtonPress()
{
MessageBox.Show("Configuration options will be here later","Settings ...",MessageBoxButtons.YesNo);
}
// Code to run when the plugin is enabled in HonorBuddy
public override void OnEnable()
{
try
{
// Battle.Net
Lua.Events.AttachEvent("BN_CONNECTED", Events.BN_CONNECTED);
Lua.Events.AttachEvent("BN_FRIEND_ACCOUNT_ONLINE", Events.BN_FRIEND_ACCOUNT_ONLINE);
// Party
Lua.Events.AttachEvent("PARTY_INVITE_REQUEST", Events.PARTY_INVITE_REQUEST);
Lua.Events.AttachEvent("PARTY_MEMBERS_CHANGED", Events.PARTY_MEMBERS_CHANGED);
// Recruit-A-Friend
Lua.Events.AttachEvent("CONFIRM_SUMMON", Events.CONFIRM_SUMMON);
Lua.Events.AttachEvent("LEVEL_GRANT_PROPOSED", Events.LEVEL_GRANT_PROPOSED);
Lua.Events.AttachEvent("PLAYER_LEVEL_UP", Events.PLAYER_LEVEL_UP);
base.OnEnable();
}
catch (Exception e)
{
// Exception handling
}
finally
{
// Command completed properly
}
}
// Code to run when the plugin is disabled in HonorBuddy
public override void OnDisable()
{
try
{
// Battle.Net
Lua.Events.DetachEvent("BN_CONNECTED", Events.BN_CONNECTED);
Lua.Events.DetachEvent("BN_FRIEND_ACCOUNT_ONLINE", Events.BN_FRIEND_ACCOUNT_ONLINE);
// Party
Lua.Events.DetachEvent("PARTY_INVITE_REQUEST", Events.PARTY_INVITE_REQUEST);
Lua.Events.DetachEvent("PARTY_MEMBERS_CHANGED", Events.PARTY_MEMBERS_CHANGED);
// Recruit-A-Friend
Lua.Events.DetachEvent("CONFIRM_SUMMON", Events.CONFIRM_SUMMON);
Lua.Events.DetachEvent("LEVEL_GRANT_PROPOSED", Events.LEVEL_GRANT_PROPOSED);
Lua.Events.DetachEvent("PLAYER_LEVEL_UP", Events.PLAYER_LEVEL_UP);
base.OnDisable();
}
catch (Exception e)
{
// Exception handling
}
finally
{
// Command completed properly
}
}
// Code to run when HonorBuddy pings the plugin (on heartbeat return pulse)
public override void Pulse()
{
}
}
// ******************************
// ** LUA EVENTS **
// ******************************
public class Events
{
public static LocalPlayer Me = StyxWoW.Me;
// Battle.net Events
public static void BN_CONNECTED(object sender, LuaEventArgs args)
{
}
public static void BN_FRIEND_ACCOUNT_ONLINE(object sender, LuaEventArgs args)
{
}
// Party Events
public static void PARTY_MEMBERS_CHANGED(object sender, LuaEventArgs args)
{
}
public static void PARTY_INVITE_REQUEST(object sender, LuaEventArgs args)
{
dynamic partyInviteSender = args.Args[0].ToString();
Lua.DoString("AcceptInvite()");
}
// Recruit-A-Friend Events
public static void CONFIRM_SUMMON(object sender, LuaEventArgs args)
{
}
public static void LEVEL_GRANT_PROPOSED(object sender, LuaEventArgs args)
{
}
public static void PLAYER_LEVEL_UP(object sender, LuaEventArgs args)
{
}
}
// ******************************
// ** LUA FUNCTIONS **
// ******************************
public class Functions
{
// Battle.Net Functions
public static StructureBattleNetInfo BNGetInfo()
{
return new StructureBattleNetInfo();
}
public static StructureBattleNetToonInfo BNGetToonInfo(string presence) // This may require a structure to be passed instead of a string
{
return new StructureBattleNetToonInfo();
}
public static int BNGetNumFriends()
{
return 0;
}
public static StructureBattleNetFriendInfo BNGetFriendInfo(int index)
{
return new StructureBattleNetFriendInfo();
}
public static StructureBattleNetFriendInfoFromID BNGetFriendInfoByID(int presence)
{
return new StructureBattleNetFriendInfoFromID();
}
public static bool CanCooperateWithToon(StructureBattleNetInfo info)
{
return false;
}
// Party Functions
public static bool IsPartyLeader()
{
return false;
}
public static void InviteUnit(string name)
{
return;
}
public static StructureLootMethod GetLootMethod()
{
return new StructureLootMethod();
}
public static void SetLootMethod(EnumLootMethod method)
{
switch (method)
{
case EnumLootMethod.FreeForAll:
break;
case EnumLootMethod.Group:
break;
case EnumLootMethod.Master:
break;
case EnumLootMethod.NeedBeforeGreed:
break;
case EnumLootMethod.RoundRobin:
break;
}
}
public static void SetLootThreshold(EnumLootThreshold threshold)
{
}
// Recruit-A-Friend Functions
public static bool IsReferAFriendLinked(string name)
{
return false;
}
public static int GetSummonFriendCooldown()
{
return 3600; // 1 Hour
}
public static void SummonFriend(string name)
{
}
public static void ConfirmSummon()
{
}
public static void CancelSummon()
{
}
public static void GrantLevel(string name)
{
}
public static void AcceptLevelGrant()
{
}
public static void DeclineLevelGrant()
{
}
public static int CheckInteractDistance(string name, int distance)
{
return 100;
}
}
}
Real World Example of Some Features
Some of the features will be ported from the Recruit-A-Friend LUA plugin (included in this post at the bottom for reference only )
THE LUA CODE BELOW IS FOR REFERENCE ONLY
Recruit-A-Friend WoW LUA Plugin
- Custom friends list for RaF auto-invite/etc
- Auto accept level grants from players on custom friends list --- this is toggleable
- Auto accept summons from players on custom friends list --- this is toggleable
- Auto accept level grants from players on custom friends list --- this is toggleable
- Detect when a friend has come online and if RaF and on custom friends list, automatically invite to party if not in a party, or if you are party leader and party is not full, and the friend is friendly, and the friend is in WoW (aka... not Starcraft)
- -- ditto -- for Battle.net status change.
- Automatically confirm Bind-on-Equip, Ressurrections, and LFG ready checks
- Check the distance between chars and alerts player if it's safe to hand in quests. This part is buggy, couldn't get the UI to show.
Code:
local frame = CreateFrame("FRAME", "RecruitAFriendFrame");
local rafTarget = nil;
local rafLevelGranted = nil;
local maxcount = 3;
frame:RegisterEvent("PARTY_INVITE_REQUEST");
frame:RegisterEvent("CONFIRM_SUMMON");
frame:RegisterEvent("ADDON_LOADED");
frame:RegisterEvent("LFG_PROPOSAL_SHOW");
frame:RegisterEvent("LEVEL_GRANT_PROPOSED");
frame:RegisterEvent("AUTOEQUIP_BIND_CONFIRM");
frame:RegisterEvent("PLAYER_TARGET_CHANGED");
frame:RegisterEvent("PLAYER_LEVEL_UP");
frame:RegisterEvent("BN_FRIEND_ACCOUNT_ONLINE");
frame:RegisterEvent("BN_CONNECTED");
frame:RegisterEvent("UNIT_TARGET");
frame:RegisterEvent("PARTY_MEMBERS_CHANGED");
frame:RegisterEvent("PLAYER_DEAD");
frame:RegisterEvent("CORPSE_IN_RANGE");
SLASH_RECRUITAFRIEND1, SLASH_RECRUITAFRIEND2 = '/raf', '/recruitafriend';
local function RecruitAFriendCommands(command, msg, arg1, arg2)
if string.find(command, " ") == nil then
RecruitAFriendForm:Show();
else
var = { strsplit(" ", command) }
if var[1]=="summon" then
start, duration = GetSummonFriendCooldown();
name, realm = UnitName("target");
if duration==0 then
if name==nil then
if var[2]==nil then
else
SummonFriend(var[2])
end
else
SummonFriend(name)
end
else
print("Your last summon was at "..SecondsToTime(start).." which is "..SecondsToTime(duration).." ago")
end
elseif var[1]=="invite" then
name, realm = UnitName("target");
if name==nil then
if var[2]==nil then
else
InviteUnit(var[2])
end
else
InviteUnit(name)
end
elseif var[1]=="grant" then
name, realm = UnitName("target");
if name==nil then
if var[2]==nil then
else
GrantLevel(var[2],1)
end
else
GrantLevel(name,1)
end
elseif var[1]=="acceptlevels" then
if var[2]=="1" then
var[2]="Allow";
raAcceptLevels = 1;
elseif var[2]=="on" then
var[2]="Allow";
raAcceptLevels = 1;
elseif var[2]=="enabled" then
var[2]="Allow";
raAcceptLevels = 1;
elseif var[2]=="yes" then
var[2]="Allow";
raAcceptLevels = 1;
elseif var[2]=="allow" then
var[2]="Allow";
raAcceptLevels = 1;
else
var[2]="Do Not Allow";
raAcceptLevels = 0;
end
print(var[2].." automatic levels to be granted to this character")
elseif var[1]=="acceptsummons" then
if var[2]=="1" then
var[2]="Allow";
raAcceptSummons = 1;
elseif var[2]=="on" then
var[2]="Allow";
raAcceptSummons = 1;
elseif var[2]=="enabled" then
var[2]="Allow";
raAcceptSummons = 1;
elseif var[2]=="yes" then
var[2]="Allow";
raAcceptSummons = 1;
elseif var[2]=="allow" then
var[2]="Allow";
raAcceptSummons = 1;
else
var[2]="Do Not Allow";
raAcceptSummons = 0;
end
print(var[2].." automatic summons to be sent to this character")
elseif var[1]=="acceptinvites" then
if var[2]=="1" then
var[2]="Allow";
raAcceptInvites = 1;
elseif var[2]=="on" then
var[2]="Allow";
raAcceptInvites = 1;
elseif var[2]=="enabled" then
var[2]="Allow";
raAcceptInvites = 1;
elseif var[2]=="yes" then
var[2]="Allow";
raAcceptInvites = 1;
elseif var[2]=="allow" then
var[2]="Allow";
raAcceptInvites = 1;
else
var[2]="Do Not Allow";
raAcceptInvites = 0;
end
print(var[2].." automatic group invitations to be sent to this character")
elseif var[1]=="add" then
RAFriendAdd(var[2])
elseif var[1]=="friends" then
for k,v in pairs(raFriends) do
print("RAF Buddy: "..v)
end
else
print("Recruit-A-Friend 4.2a Command List")
print("/raf summon [friend]")
print("/raf invite [friend]")
print("/raf grant [friend]")
print("/raf acceptlevels on/off")
print("/raf acceptsummons on/off")
print("/raf acceptinvites on/off")
print("/raf add friend")
print("/raf friends")
end
end
end
local function eventHandler(info, event, sender, name)
if event=="PARTY_INVITE_REQUEST" then
if sender==nil then
isLinked=nil
else
isLinked = IsReferAFriendLinked(sender);
rafToonName = sender;
end
if isLinked==nil then
isLinked=RAFriendExists(sender);
end
if isLinked==1 then
if raAcceptInvites==1 then
AcceptGroup();
-- frame:RegisterEvent("PARTY_MEMBERS_CHANGED");
end
end
elseif event=="CONFIRM_SUMMON" then
-- GetSummonConfirmSummoner()
-- isLinked = IsReferAFriendLinked(sender);
-- isLinked=nil;
-- print("you are being summoned by "..name);
-- if isLinked==nil then
-- isLinked=RAFriendExists(sender);
-- end
isLinked=1;
if isLinked==1 then
if raAcceptSummons==1 then
ConfirmSummon();
else
-- print(sender);
CancelSummon();
end
else
CancelSummon();
end
elseif event=="UNIT_TARGET" then
if(GetNumPartyMembers() > 0) then
local numBNetTotal, numBNetOnline = BNGetNumFriends();
for i = 1, numBNetTotal do
local presenceID, givenName, surname, toonName, toonID, client, isOnline = BNGetFriendInfo(i);
_, _, gameName, realmName, faction, _, race, class, _, zoneName, level = BNGetToonInfo(presenceID);
if (isOnline) and (client == "WoW") then
if (CanCooperateWithToon(BNGetInfo(toonID))) then
if (UnitInParty(toonName)) then
if (IsReferAFriendLinked(toonName)) then
rafToonName = toonName;
rafLinkActive = "[RAF]";
inRange = CheckInteractDistance(toonName, 4);
if (inRange) then
RecruitAFriendDistance:Hide();
-- print(rafLinkActive .. givenName .. " [FULL RAF BENEFITS]");
else
if(UnitInRange(toonName)) then
RecruitAFriendDistance:Show();
-- print(rafLinkActive .. givenName .. " [DO NOT HAND IN QUESTS]");
else
RecruitAFriendDistance:Show();
RecruitAFriendSummonForm:Show();
-- print(rafLinkActive .. givenName .. " [DO NOT HAND IN QUESTS OR KILL MONSTERS]");
end
end
end
else
if(RAFriendExists(toonName) == 1) then
InviteUnit(toonName);
end
end
end
end
end
end
elseif event=="LEVEL_GRANT_PROPOSED" then
isLinked = IsReferAFriendLinked(sender);
if isLinked==nil then
isLinked=RAFriendExists(sender);
end
if isLinked==1 then
if raAcceptLevels==1 then
rafLevelGranted=sender;
AcceptLevelGrant()
print(sender);
else
DeclineLevelGrant();
end
else
DeclineLevelGrant();
end
elseif event=="ADDON_LOADED" then
if sender=="Recruit-A-Friend" then
local presenceIDl, toonIDl, currentBroadcastl, bnetAFKl, bnetDNDl = BNGetInfo();
_, _, gameNamel, realmNamel, factionl, _, racel, classl, _, zoneNamel, levell = BNGetToonInfo(presenceIDl);
if not ( raFriends ) then
raFriends = { }
end
if not ( raAcceptLevels ) then
raAcceptLevels = 0
end
if not ( raAcceptSummons ) then
raAcceptSummons = 1
end
if not ( raAcceptInvites ) then
raAcceptInvites = 1
end
print("Recruit-A-Friend Addon Loaded")
print("You have "..#raFriends.." friend(s) on your Recruit-A-Friend buddy list")
print("You are on " .. realmNamel .. " on your level " .. levell .. " " .. racel .. " " .. classl);
if raAcceptLevels==1 then
print("Accepting granted levels")
end
if raAcceptSummons==1 then
print("Accepting summons")
end
if raAcceptInvites==1 then
print("Accepting party invitations")
end
end
elseif event=="BN_CONNECTED" then
local presenceIDl, toonIDl, currentBroadcastl, bnetAFKl, bnetDNDl = BNGetInfo();
_, _, gameNamel, realmNamel, factionl, _, racel, classl, _, zoneNamel, levell = BNGetToonInfo(presenceIDl);
local numBNetTotal, numBNetOnline = BNGetNumFriends();
for i = 1, numBNetTotal do
local presenceID, givenName, surname, toonName, toonID, client, isOnline = BNGetFriendInfo(i);
_, _, gameName, realmName, faction, _, race, class, _, zoneName, level = BNGetToonInfo(presenceID);
if (isOnline) and (client == "WoW") then
if (CanCooperateWithToon(BNGetInfo(toonID))) then
if(RAFriendExists(toonName) == 1) then
rafToonName = toonName;
if tonumber(level) > tonumber(levell) then
leveldifference = tonumber(level) - tonumber(level);
elseif tonumber(levell) > tonumber(level) then
leveldifference = tonumber(levell) - tonumber(level);
else
leveldifference = 0;
end
if leveldifference < 5 then
if (UnitInParty(toonName)) or (realmName ~= realmNamel) then
print(givenName .. " just came online at " .. realmName .. " on their level " .. level .. " " .. race .. " " .. class );
else
InviteUnit(toonName);
end
end
end
end
end
end
elseif event=="BN_FRIEND_ACCOUNT_ONLINE" then
local presenceIDl, toonIDl, currentBroadcastl, bnetAFKl, bnetDNDl = BNGetInfo();
_, _, gameNamel, realmNamel, factionl, _, racel, classl, _, zoneNamel, levell = BNGetToonInfo(presenceIDl);
local presenceId = select(1, sender);
local presenceID, givenName, surname, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText = BNGetFriendInfoByID(presenceId);
_, _, gameName, realmName, faction, _, race, class, _, zoneName, level = BNGetToonInfo(presenceID);
if (isOnline) and (client == "WoW") then
if (CanCooperateWithToon(BNGetInfo(toonID))) then
if(RAFriendExists(toonName) == 1) then
rafToonName = toonName;
if tonumber(level) > tonumber(levell) then
leveldifference = tonumber(level) - tonumber(level);
elseif tonumber(levell) > tonumber(level) then
leveldifference = tonumber(levell) - tonumber(level);
else
leveldifference = 0;
end
if (leveldifference < 6) then
if (UnitInParty(toonName)) or (realmName ~= realmNamel) then
print(givenName .. " just came online at " .. realmName .. " on their level " .. level .. " " .. race .. " " .. class );
else
InviteUnit(toonName);
rafToonName = toonName;
end
end
end
end
end
elseif event=="LFG_PROPOSAL_SHOW" then
AcceptProposal();
elseif event=="PLAYER_DEAD" then
frame:RegisterEvent("RESURRECT_REQUEST","acceptResurrection");
frame:RegisterEvent("PLAYER_UNGHOST","acceptResurrection");
elseif event=="CORPSE_IN_RANGE" then
RetrieveCorpse();
elseif event=="AUTOEQUIP_BIND_CONFIRM" then
ConfirmBindOnUse();
elseif event=="PLAYER_TARGET_CHANGED" then
rafTarget = name
elseif event=="PLAYER_LEVEL_UP" then
local newlevel = sender
local togo = MAX_PLAYER_LEVEL - newlevel
rafLevelGranted = nil
elseif event=="PARTY_MEMBERS_CHANGED" then
StaticPopup_Hide("PARTY_INVITE");
--frame:UnregisterEvent("PARTY_MEMBERS_CHANGED");
if (rafToonName) then
if (UnitInParty(rafToonName)) then
RecruitAFriendSummonForm:Show();
local start, duration = GetSummonFriendCooldown();
local timeleft = start + duration - GetTime();
if(timeleft <= 0) then
rafCaptionSummonFriend:Hide();
rafButtonSummonFriend:Show();
else
rafButtonSummonFriend:Hide();
rafCaptionSummonFriend:Show();
rafCaptionSummonFriend:SetText(SecondsToTime(timeleft));
end
if (IsPartyLeader()) then
lootmethod, masterlooterPartyID, masterlooterRaidID = GetLootMethod();
if (lootmethod == "freeforall") then
else
SetLootMethod("freeforall");
SetLootThreshold(3);
end
end
end
else
print("rafToonName is empty");
end
end
end
function rafClosePartyPopup()
StaticPopup_Hide("PARTY_INVITE");
-- frame:UnregisterEvent("PARTY_MEMBERS_CHANGED");
end
function acceptResurrection(info, event, sender)
AcceptResurrect();
frame:UnregisterEvent("RESURRECT_REQUEST");
frame:UnregisterEvent("PLAYER_UNGHOST");
end
function RAFriendAdd(friend)
if RAFriendExists(friend)==0 then
table.insert(raFriends,friend)
print(friend.." was added to your Recruit-A-Friend buddy list")
else
print(friend.." already exists on your Recruit-A-Friend buddy list")
end
end
function RAFriendExists(friend)
myreturn=0;
if (#raFriends==0) then
myreturn=0;
else
for k,v in pairs(raFriends) do
if strlower(v)==strlower(friend) then
myreturn=1;
end
end
end
return myreturn;
end
frame:SetScript("OnEvent", eventHandler);
SlashCmdList["RECRUITAFRIEND"] = RecruitAFriendCommands;
Last edited: