atom0s
8 years ago
14 changed files with 2911 additions and 0 deletions
@ -0,0 +1,221 @@
@@ -0,0 +1,221 @@
|
||||
# ---> VisualStudio |
||||
## Ignore Visual Studio temporary files, build results, and |
||||
## files generated by popular Visual Studio add-ons. |
||||
|
||||
# User-specific files |
||||
*.suo |
||||
*.user |
||||
*.userosscache |
||||
*.sln.docstates |
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio) |
||||
*.userprefs |
||||
|
||||
# Build results |
||||
[Dd]ebug/ |
||||
[Dd]ebugPublic/ |
||||
[Rr]elease/ |
||||
[Rr]eleases/ |
||||
x64/ |
||||
x86/ |
||||
build/ |
||||
bld/ |
||||
[Bb]in/ |
||||
[Oo]bj/ |
||||
|
||||
# Visual Studio 2015 cache/options directory |
||||
.vs/ |
||||
# Uncomment if you have tasks that create the project's static files in wwwroot |
||||
#wwwroot/ |
||||
|
||||
# MSTest test Results |
||||
[Tt]est[Rr]esult*/ |
||||
[Bb]uild[Ll]og.* |
||||
|
||||
# NUNIT |
||||
*.VisualState.xml |
||||
TestResult.xml |
||||
|
||||
# Build Results of an ATL Project |
||||
[Dd]ebugPS/ |
||||
[Rr]eleasePS/ |
||||
dlldata.c |
||||
|
||||
# DNX |
||||
project.lock.json |
||||
artifacts/ |
||||
|
||||
*_i.c |
||||
*_p.c |
||||
*_i.h |
||||
*.ilk |
||||
*.meta |
||||
*.obj |
||||
*.pch |
||||
*.pdb |
||||
*.pgc |
||||
*.pgd |
||||
*.rsp |
||||
*.sbr |
||||
*.tlb |
||||
*.tli |
||||
*.tlh |
||||
*.tmp |
||||
*.tmp_proj |
||||
*.log |
||||
*.vspscc |
||||
*.vssscc |
||||
.builds |
||||
*.pidb |
||||
*.svclog |
||||
*.scc |
||||
|
||||
# Chutzpah Test files |
||||
_Chutzpah* |
||||
|
||||
# Visual C++ cache files |
||||
ipch/ |
||||
*.aps |
||||
*.ncb |
||||
*.opensdf |
||||
*.sdf |
||||
*.cachefile |
||||
|
||||
# Visual Studio profiler |
||||
*.psess |
||||
*.vsp |
||||
*.vspx |
||||
*.sap |
||||
|
||||
# TFS 2012 Local Workspace |
||||
$tf/ |
||||
|
||||
# Guidance Automation Toolkit |
||||
*.gpState |
||||
|
||||
# ReSharper is a .NET coding add-in |
||||
_ReSharper*/ |
||||
*.[Rr]e[Ss]harper |
||||
*.DotSettings.user |
||||
|
||||
# JustCode is a .NET coding add-in |
||||
.JustCode |
||||
|
||||
# TeamCity is a build add-in |
||||
_TeamCity* |
||||
|
||||
# DotCover is a Code Coverage Tool |
||||
*.dotCover |
||||
|
||||
# NCrunch |
||||
_NCrunch_* |
||||
.*crunch*.local.xml |
||||
nCrunchTemp_* |
||||
|
||||
# MightyMoose |
||||
*.mm.* |
||||
AutoTest.Net/ |
||||
|
||||
# Web workbench (sass) |
||||
.sass-cache/ |
||||
|
||||
# Installshield output folder |
||||
[Ee]xpress/ |
||||
|
||||
# DocProject is a documentation generator add-in |
||||
DocProject/buildhelp/ |
||||
DocProject/Help/*.HxT |
||||
DocProject/Help/*.HxC |
||||
DocProject/Help/*.hhc |
||||
DocProject/Help/*.hhk |
||||
DocProject/Help/*.hhp |
||||
DocProject/Help/Html2 |
||||
DocProject/Help/html |
||||
|
||||
# Click-Once directory |
||||
publish/ |
||||
|
||||
# Publish Web Output |
||||
*.[Pp]ublish.xml |
||||
*.azurePubxml |
||||
# TODO: Comment the next line if you want to checkin your web deploy settings |
||||
# but database connection strings (with potential passwords) will be unencrypted |
||||
*.pubxml |
||||
*.publishproj |
||||
|
||||
# NuGet Packages |
||||
*.nupkg |
||||
# The packages folder can be ignored because of Package Restore |
||||
**/packages/* |
||||
# except build/, which is used as an MSBuild target. |
||||
!**/packages/build/ |
||||
# Uncomment if necessary however generally it will be regenerated when needed |
||||
#!**/packages/repositories.config |
||||
|
||||
# Windows Azure Build Output |
||||
csx/ |
||||
*.build.csdef |
||||
|
||||
# Windows Store app package directory |
||||
AppPackages/ |
||||
|
||||
# Visual Studio cache files |
||||
# files ending in .cache can be ignored |
||||
*.[Cc]ache |
||||
# but keep track of directories ending in .cache |
||||
!*.[Cc]ache/ |
||||
|
||||
# Others |
||||
ClientBin/ |
||||
[Ss]tyle[Cc]op.* |
||||
~$* |
||||
*~ |
||||
*.dbmdl |
||||
*.dbproj.schemaview |
||||
*.pfx |
||||
*.publishsettings |
||||
node_modules/ |
||||
orleans.codegen.cs |
||||
|
||||
# RIA/Silverlight projects |
||||
Generated_Code/ |
||||
|
||||
# Backup & report files from converting an old project file |
||||
# to a newer Visual Studio version. Backup files are not needed, |
||||
# because we have git ;-) |
||||
_UpgradeReport_Files/ |
||||
Backup*/ |
||||
UpgradeLog*.XML |
||||
UpgradeLog*.htm |
||||
|
||||
# SQL Server files |
||||
*.mdf |
||||
*.ldf |
||||
|
||||
# Business Intelligence projects |
||||
*.rdl.data |
||||
*.bim.layout |
||||
*.bim_*.settings |
||||
|
||||
# Microsoft Fakes |
||||
FakesAssemblies/ |
||||
|
||||
# Node.js Tools for Visual Studio |
||||
.ntvs_analysis.dat |
||||
|
||||
# Visual Studio 6 build log |
||||
*.plg |
||||
|
||||
# Visual Studio 6 workspace options file |
||||
*.opt |
||||
|
||||
# Visual Studio LightSwitch build output |
||||
**/*.HTMLClient/GeneratedArtifacts |
||||
**/*.DesktopClient/GeneratedArtifacts |
||||
**/*.DesktopClient/ModelManifest.xml |
||||
**/*.Server/GeneratedArtifacts |
||||
**/*.Server/ModelManifest.xml |
||||
_Pvt_Extensions |
||||
|
||||
/Ashita.exp |
||||
/Ashita.lib |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
#include "Chat.hpp" |
||||
|
||||
namespace Chat{ |
||||
void Log::putAutoTransOpen() |
||||
{ |
||||
s.put('\xFF'); |
||||
s.put('\xEF'); |
||||
s.put('\x27'); |
||||
} |
||||
|
||||
void Log::putAutoTransClose() |
||||
{ |
||||
s.put('\xFF'); |
||||
s.put('\xEF'); |
||||
s.put('\x28'); |
||||
} |
||||
|
||||
IAutoTrans Log::Region(unsigned char RegionID) |
||||
{ |
||||
IAutoTrans i; |
||||
i.x = m_Ashita->GetResourceManager()->GetString("regions", RegionID, 0); |
||||
return i; |
||||
} |
||||
|
||||
IAutoTrans Log::Zone(unsigned int ZoneID) |
||||
{ |
||||
IAutoTrans i; |
||||
i.x = m_Ashita->GetResourceManager()->GetString("areas",ZoneID,0); |
||||
return i; |
||||
} |
||||
|
||||
IAutoTrans Log::Keyitem(unsigned int ID) |
||||
{ |
||||
IAutoTrans i; |
||||
i.x = m_Ashita->GetResourceManager()->GetString("keyitems",ID,0); |
||||
return i; |
||||
} |
||||
|
||||
Log::Log() : m_Ashita(NULL) |
||||
{ |
||||
mode = RecvdSay; |
||||
s = std::ostringstream(); |
||||
} |
||||
Log::~Log() |
||||
{ |
||||
} |
||||
|
||||
void Log::SetCore(IAshitaCore* mAshitaCore) |
||||
{ |
||||
m_Ashita = mAshitaCore; |
||||
} |
||||
}; |
@ -0,0 +1,438 @@
@@ -0,0 +1,438 @@
|
||||
#include <stdint.h> |
||||
#include <sstream> |
||||
#include <string> |
||||
#include "G:/Code/git.ashita.atom0s.com/Ashita v3/Ashita-src/build/plugins/ADK/Ashita.h" |
||||
|
||||
#include <iostream> |
||||
|
||||
namespace Chat |
||||
{ |
||||
//typedef const char* IAutoTrans;
|
||||
struct IAutoTrans{ |
||||
const char* x; |
||||
}; |
||||
|
||||
enum Mode : short |
||||
{ |
||||
// Info mostly taken from http://www.ffevo.net/wiki/index.php/ChatIDs
|
||||
|
||||
//----------------------
|
||||
// Common "Chat" Modes
|
||||
//----------------------
|
||||
Unknown = 0, // Catch all. Do not use...it sometimes breaks the chat log.
|
||||
SentSay = 0x1, // Outgoing Say
|
||||
SentSay2 = 0x2, // Outgoing Say
|
||||
SentTell = 0x4, // Outgoing Tell
|
||||
SentParty = 0x5, // Outgoing Party
|
||||
SentLinkShell = 0x6, // Outgoing Linkshell
|
||||
SentEmote = 0x7, // Outgoing Emote, untargetted
|
||||
RecvdSay = 0x9, // Incoming Say
|
||||
RecvdSay2 = 0xA, // Incoming Say
|
||||
RcvdTell = 0xC, // Incoming Tell
|
||||
RcvdParty = 0xD, // Incoming Party (thanks Vanion for the correction!)
|
||||
RcvdLinkShell = 0xE, // Incoming Linkshell
|
||||
SentEmoteTo = 0xF, // Outgoing Emote, targeted
|
||||
Echo = 0xCE, // Echo
|
||||
|
||||
//----------------------
|
||||
// Action Modes
|
||||
//----------------------
|
||||
|
||||
ActCallHelp = 0x10, // Call for Help!
|
||||
ActFriendReq = 0x12, // Sent Friend Request
|
||||
ActCastMagic = 0x13, //
|
||||
ActHitDamage = 0x14, //
|
||||
ActMiss = 0x15, //
|
||||
ActDrained = 0x16, //
|
||||
ActPTHitAbsorbed = 0x17, //
|
||||
ActPTRecoverHP = 0x18, //
|
||||
ActPTHitDamage = 0x19, //
|
||||
ActPTMiss = 0x1A, //
|
||||
ActPTDrained = 0x1B, //
|
||||
ActDamaged = 0x1C, //
|
||||
ActAvoidDamage = 0x1D, //
|
||||
ActRecoverHealth = 0x1E, //
|
||||
ActRecoverHP = 0x1F, //
|
||||
ActPTDamaged = 0x20, //
|
||||
ActPTAvoidDamage = 0x21, //
|
||||
ActPCGainHealth = 0x22, //
|
||||
ActPTHealedOther = 0x23, //
|
||||
ActDefeats = 0x24, //
|
||||
ActPCDeath = 0x25, //
|
||||
ActDeath = 0x26, //
|
||||
ActPTDeath = 0x27, //
|
||||
ActPCDamage = 0x28, //
|
||||
ActPCMiss = 0x29, //
|
||||
ActPCRecoverHealth = 0x2A, //
|
||||
ActPCHealsPC = 0x2B, //
|
||||
ActPCDefeated = 0x2C, //
|
||||
|
||||
//----------------------
|
||||
// Special Action Modes
|
||||
//----------------------
|
||||
|
||||
SAct = 0x32, //
|
||||
SActPT = 0x33, //
|
||||
SActPC = 0x34, //
|
||||
SActRecvdBenefit = 0x38, //
|
||||
SActRecvdDetriment = 0x39, //
|
||||
SActNoEffect = 0x3B, //
|
||||
SActPTRecvdBenefit = 0x3C, //
|
||||
SActPTRecvdDetriment = 0x3D,//
|
||||
SActPTNoEffect = 0x3F, // Needs confirmation
|
||||
SActPCRecvdBenefit = 0x40, //
|
||||
SActPCRecvdDetriment = 0x41,//
|
||||
SActPCNoEffect = 0x43, //
|
||||
SActPTResisted = 0x44, //
|
||||
SActOtherResisted = 0x45, //
|
||||
|
||||
SActSAttUse = 0x65, //
|
||||
SActOtherBenefit = 0x6F, //
|
||||
SActOtherDetriment = 0x70, //
|
||||
SActOtherMissed = 0x72, //
|
||||
|
||||
SActSpellEffect = 0xBB, //
|
||||
|
||||
//----------------------
|
||||
// Item Modes
|
||||
//----------------------
|
||||
|
||||
ItemRecvdEffect = 0x51, //
|
||||
ItemPCUsed = 0x55, //
|
||||
ItemPCUsed2 = 0x5A, //
|
||||
ItemLearnedSpell = 0x5B, //
|
||||
|
||||
//----------------------
|
||||
// Mob Special Action Modes
|
||||
//----------------------
|
||||
|
||||
MobActSAttUse = 0x64, //
|
||||
MobActDetriment = 0x66, //
|
||||
MobActSAttEvaded = 0x68, //
|
||||
MobActSAttAoE = 0x69, //
|
||||
MobActSupport = 0x6A, //
|
||||
MobActDrain = 0x6B, //
|
||||
MobActRAttMissed = 0x6D, //
|
||||
MobActSAttInit = 0x6E, //
|
||||
|
||||
//----------------------
|
||||
// System Message Modes
|
||||
//----------------------
|
||||
|
||||
Sys1 = 0x79, // Target out of range, AH & synth feedback, Item feedback, trade feedback
|
||||
Sys2 = 0x7A, // Entity chasing out of range, entity intimidated, raise, paralyzed, cannot see entity,
|
||||
// casting interrupted, cannot attack, target already claimed, no exp gained
|
||||
Sys3 = 0x7B, // Sneak/invis wearing, wait longer to perform action, chat not sent/recvd
|
||||
SysObtainedItem = 0x7F, //
|
||||
SysSkillGained = 0x81, //
|
||||
SysExpLvlMerit = 0x83, //
|
||||
SysInvitedToParty = 0x87, //
|
||||
SysLogoutCountdown = 0x88, //
|
||||
SysBazaar = 0x8A, //
|
||||
SysTimePlayed = 0x8B, //
|
||||
SysClock = 0x8C, //
|
||||
SysDynamisWarning = 0x8D, //
|
||||
SysTaunts = 0x8E, //
|
||||
SysTutorialMoogle = 0x90, //
|
||||
SysCaughtFish = 0x92, //
|
||||
Sys4 = 0x94, // Digging/Fishing/Door/Ballista Feedback, Mission Gil Reward, Accepted Mission, Receive
|
||||
// Mission Key Item, Gained Conquest Points
|
||||
SysTimeRestriction = 0x95, //
|
||||
SysTutorialNPC = 0x98, //
|
||||
SysCommandError = 0x9D, // Also /help output
|
||||
SysConquestUpdate = 0xA1, //
|
||||
|
||||
SysNeedKey = 0xBE, //
|
||||
Sys5 = 0xBF, // Effect wears off, Detriment wears off, no longer stunned, fall to level
|
||||
SysMOTD = 0xC8, // Also recast times (but not /recast feedback)
|
||||
SysSearchComment = 0xCC, //
|
||||
SysLinkshellMOTD = 0xCD, //
|
||||
SysExamined = 0xD0, //
|
||||
|
||||
//----------------------
|
||||
// Alliance Action Modes
|
||||
//----------------------
|
||||
|
||||
AllyHealAlly = 0xA2, //
|
||||
AllyDamage = 0xA3, //
|
||||
AllyMiss = 0xA4, //
|
||||
AllyDefeats = 0xA6, //
|
||||
AllyDefeated = 0xA7, //
|
||||
AllySAct = 0xA8, //
|
||||
AllyNoEffect = 0xAA, //
|
||||
AllyItemUse = 0xAB, //
|
||||
AllyRecvdDetriment = 0xAE, //
|
||||
AllyRecvdBenefit = 0xAF, //
|
||||
|
||||
AllyRecvdDetrimentAoE = 0xB6,//
|
||||
AllyDamaged = 0xB9, //
|
||||
AllyEvades = 0xBA, //
|
||||
|
||||
//----------------------
|
||||
// NPC Action Modes
|
||||
//----------------------
|
||||
|
||||
NPCSAct = 0xB1, //
|
||||
|
||||
NPCActDetriment = 0xB5, //
|
||||
|
||||
//----------------------
|
||||
// Unknown or Unused Modes
|
||||
//----------------------
|
||||
|
||||
SentYell = 0x03, |
||||
RecvdYell = 0x11, |
||||
//0x3
|
||||
//0x8
|
||||
//0xB
|
||||
//0x11
|
||||
//0x2D-0x31
|
||||
//0x35-0x37
|
||||
//0x3A
|
||||
//0x3E
|
||||
//0x42
|
||||
//0x46-0x50
|
||||
//0x52-0x54
|
||||
//0x56-0x59
|
||||
//0x5C-0x63
|
||||
//0x67
|
||||
//0x6C
|
||||
//0x71
|
||||
//0x73-0x78
|
||||
//0x7C-0x7E
|
||||
//0x80
|
||||
//0x82
|
||||
//0x84-0x86
|
||||
//0x89
|
||||
//0x8F
|
||||
//0x91
|
||||
//0x93
|
||||
//0x96
|
||||
//0x97
|
||||
//0x99-0x9C
|
||||
//0x9E-0xA0
|
||||
//0xA5
|
||||
//0xA9
|
||||
//0xAC
|
||||
//0xAD
|
||||
//0xB0
|
||||
//0xB2-0xB4
|
||||
//0xB7
|
||||
//0xB8
|
||||
//0xBC
|
||||
//0xBD
|
||||
//0xC0-0xC7
|
||||
//0xC9-0xCB
|
||||
//0xCF
|
||||
//0xD1-0xFF
|
||||
}; |
||||
|
||||
enum Format { |
||||
LineBreak,// = 0x07, // Inserts an inline line break (does not flush)
|
||||
Reset,// = 0x1E01,
|
||||
Green,// = 0x1E02,
|
||||
Blue,// = 0x1E03,
|
||||
Purple,// = 0x1E05,
|
||||
Aqua,// = 0x1E06,
|
||||
Peach,// = 0x1E07,
|
||||
White,// = 0x1E1A,
|
||||
Gray,// = 0x1E1B,
|
||||
Lilac,// = 0x1E3A,
|
||||
BlueWhite,// = 0x1E3C,
|
||||
InvisibleBlue,// = 0x1E62, // Ridiculously hard to read
|
||||
Red,// = 0x1E69,
|
||||
Yellow,// = 0x1E6E,
|
||||
RoyalBlue,// = 0x1E71,
|
||||
Invisible,// = 0x1E86, // This one really is invisible as far as I can tell
|
||||
GreenWhite,// = 0x1E96,
|
||||
SageGreen,// = 0x1EA0,
|
||||
AutoTransOpen,// = 0xFFEF27,
|
||||
AutoTransClose,// = 0xFFEF28,
|
||||
EnterToContinue,// = 0x7F3101 // Waits one second before making prompt available. Can alter the last byte to change the timing.
|
||||
}; |
||||
|
||||
enum Control |
||||
{ |
||||
flush, //Flush the output to chat log and clears the buffer
|
||||
clear, //Clears the buffer without writing it out
|
||||
}; |
||||
|
||||
class Log{ |
||||
private: |
||||
Mode mode; |
||||
std::ostringstream s; |
||||
IAshitaCore* m_Ashita; |
||||
|
||||
void putAutoTransOpen(); |
||||
void putAutoTransClose(); |
||||
public: |
||||
Log &operator<<(Chat::Mode x) |
||||
{ |
||||
mode = x; |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(Chat::Format x) |
||||
{ |
||||
switch (x) |
||||
{ |
||||
case LineBreak: |
||||
s.put('\x07'); |
||||
break; |
||||
case Reset: |
||||
s.put('\x1E'); |
||||
s.put('\x01'); |
||||
break; |
||||
case Green: |
||||
s.put('\x1E'); |
||||
s.put('\x02'); |
||||
break; |
||||
case Blue: |
||||
s.put('\x1E'); |
||||
s.put('\x03'); |
||||
break; |
||||
case Purple: |
||||
s.put('\x1E'); |
||||
s.put('\x05'); |
||||
break; |
||||
case Aqua: |
||||
s.put('\x1E'); |
||||
s.put('\x06'); |
||||
break; |
||||
case Peach: |
||||
s.put('\x1E'); |
||||
s.put('\x07'); |
||||
break; |
||||
case White: |
||||
s.put('\x1E'); |
||||
s.put('\x1A'); |
||||
break; |
||||
case Gray: |
||||
s.put('\x1E'); |
||||
s.put('\x1B'); |
||||
break; |
||||
case Lilac: |
||||
s.put('\x1E'); |
||||
s.put('\x3A'); |
||||
break; |
||||
case BlueWhite: |
||||
s.put('\x1E'); |
||||
s.put('\x3C'); |
||||
break; |
||||
case InvisibleBlue: |
||||
s.put('\x1E'); |
||||
s.put('\x62'); |
||||
break; |
||||
case Red: |
||||
s.put('\x1E'); |
||||
s.put('\x69'); |
||||
break; |
||||
case Yellow: |
||||
s.put('\x1E'); |
||||
s.put('\x6E'); |
||||
break; |
||||
case RoyalBlue: |
||||
s.put('\x1E'); |
||||
s.put('\x71'); |
||||
break; |
||||
case Invisible: |
||||
s.put('\x1E'); |
||||
s.put('\x86'); |
||||
break; |
||||
case GreenWhite: |
||||
s.put('\x1E'); |
||||
s.put('\x96'); |
||||
break; |
||||
case SageGreen: |
||||
s.put('\x1E'); |
||||
s.put('\xA0'); |
||||
break; |
||||
case AutoTransOpen: |
||||
putAutoTransOpen(); |
||||
break; |
||||
case AutoTransClose: |
||||
putAutoTransClose(); |
||||
break; |
||||
case EnterToContinue: |
||||
s.put('\x7F'); |
||||
s.put('\x31'); |
||||
s.put('\x01'); |
||||
break; |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(ISpell* x) |
||||
{ |
||||
putAutoTransOpen(); |
||||
s << x->Name; |
||||
putAutoTransClose(); |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(IAbility* x) |
||||
{ |
||||
putAutoTransOpen(); |
||||
s << x->Name; |
||||
putAutoTransClose(); |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(IItem* x) |
||||
{ |
||||
putAutoTransOpen(); |
||||
s << x->Name; |
||||
putAutoTransClose(); |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(Chat::IAutoTrans x) |
||||
{ |
||||
putAutoTransOpen(); |
||||
s << x.x; |
||||
putAutoTransClose(); |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(Chat::Control x) |
||||
{ |
||||
switch(x) |
||||
{ |
||||
case Control::flush: |
||||
m_Ashita->GetChatManager()->AddChatMessage(mode,s.str().c_str()); |
||||
case Control::clear: |
||||
s = std::ostringstream(); |
||||
break; |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(const char* &x) |
||||
{ |
||||
s << x; |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(std::string &x) |
||||
{ |
||||
s << x; |
||||
return *this; |
||||
} |
||||
|
||||
Log &operator<<(const char x[]) |
||||
{ |
||||
s << x; |
||||
return *this; |
||||
} |
||||
|
||||
Log(); |
||||
~Log(); |
||||
|
||||
IAutoTrans Region(unsigned char RegionID); |
||||
IAutoTrans Zone(unsigned int ZoneID); |
||||
IAutoTrans Keyitem(unsigned int ID); |
||||
|
||||
void SetCore(IAshitaCore* mAshitaCore); |
||||
}; |
||||
|
||||
}; |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
#include <vector> |
||||
#include <stdint.h> |
||||
|
||||
class CommandParser |
||||
{ |
||||
private: |
||||
std::vector<char*> thisList; |
||||
uint8_t argC; |
||||
uint8_t argIdx; |
||||
public: |
||||
CommandParser() |
||||
{} |
||||
~CommandParser() |
||||
{} |
||||
|
||||
void InputCommand(const char* szBuffer); |
||||
bool GetFirstCommand(std::string*); |
||||
bool GetCommandAt(unsigned int,std::string*); |
||||
bool GetNextCommand(std::string*); |
||||
bool GetRemainingCommands(std::string*); |
||||
unsigned int GetArgCount(); |
||||
}; |
||||
|
||||
void CommandParser::InputCommand(const char* szBuffer) |
||||
{ |
||||
thisList.clear(); |
||||
argIdx = 0; |
||||
argC = 0; |
||||
uint8_t span = 0; |
||||
char* szTemp = const_cast<char*>(szBuffer); |
||||
char* tokenBuf; |
||||
for(char* substr = strtok_s(szTemp, " ",&tokenBuf);substr; substr = strtok_s(NULL, " ",&tokenBuf)) |
||||
{ |
||||
thisList.push_back(substr); |
||||
argC += 1; |
||||
} |
||||
} |
||||
|
||||
bool CommandParser::GetFirstCommand(std::string* sReturn) |
||||
{ |
||||
argIdx = 0; |
||||
return GetNextCommand(&*sReturn); |
||||
} |
||||
|
||||
bool CommandParser::GetCommandAt(unsigned int idx, std::string* sReturn) |
||||
{ |
||||
argIdx = idx; |
||||
return GetNextCommand(&*sReturn); |
||||
} |
||||
|
||||
bool CommandParser::GetNextCommand(std::string* sReturn) |
||||
{ |
||||
if(argIdx < argC) |
||||
{ |
||||
*sReturn = thisList[argIdx]; |
||||
argIdx += 1; |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool CommandParser::GetRemainingCommands(std::string* sReturn) |
||||
{ |
||||
bool retVal = false; |
||||
*sReturn = ""; |
||||
while(argIdx < argC) |
||||
{ |
||||
sReturn->append(thisList[argIdx]); |
||||
sReturn->append(1,'\x20'); |
||||
argIdx += 1; |
||||
retVal = true; |
||||
} |
||||
return retVal; |
||||
} |
||||
|
||||
unsigned int CommandParser::GetArgCount() |
||||
{ |
||||
return argC; |
||||
} |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
LIBRARY "Servo" |
||||
EXPORTS |
||||
GetInterfaceVersion |
||||
CreatePluginInfo |
||||
CreatePlugin |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
#ifndef __ASHITA_SERVO_H_INCLUDED__ |
||||
#define __ASHITA_SERVO_H_INCLUDED__ |
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1020) |
||||
#pragma once |
||||
#endif |
||||
|
||||
#include <deque> |
||||
#include <atomic> |
||||
#include <thread> |
||||
#include <mutex> |
||||
#include "zmq.hpp" |
||||
#include "G:/Code/git.ashita.atom0s.com/Ashita v3/Ashita-src/build/plugins/ADK/Ashita.h" |
||||
#include "CommandParser.h" |
||||
#include "Chat.hpp" |
||||
|
||||
plugininfo_t* g_PluginInfo = NULL; |
||||
|
||||
#pragma comment(lib,"libzmq.lib") |
||||
|
||||
struct auto_follow |
||||
{ |
||||
unsigned int unknown_ptr; |
||||
unsigned int TargetIndex; |
||||
unsigned int TargetID; |
||||
float DirectionX; |
||||
float DirectionY; |
||||
float DirectionZ; |
||||
float unknown_float; // 1 -- Deals with collision (CXiCollisionActor)
|
||||
unsigned int unknown_ptr2; |
||||
unsigned int FollowIndex; |
||||
unsigned int FollowID; |
||||
unsigned char CameraMode; // 0 = third-person - 1 = first-person
|
||||
unsigned char AutoRun; |
||||
|
||||
}; |
||||
|
||||
namespace ServoMode { |
||||
enum Mode { Standby, Server, Client }; |
||||
}; |
||||
|
||||
class Servo : IPlugin |
||||
{ |
||||
private: |
||||
IAshitaCore* m_AshitaCore; |
||||
Chat::Log log; |
||||
std::string me; |
||||
|
||||
auto_follow* StructPointer; |
||||
|
||||
zmq::context_t zContext; |
||||
|
||||
std::mutex lock; |
||||
std::atomic_bool connected; |
||||
std::atomic_bool follow; |
||||
std::atomic_bool zoning; |
||||
std::vector<std::string> groups; |
||||
std::thread conn; |
||||
std::thread pos; |
||||
std::deque<std::string> buffer; |
||||
|
||||
std::atomic<ServoMode::Mode> state; |
||||
std::string servAddr; |
||||
|
||||
std::mutex lservAddr; |
||||
|
||||
std::string StringSub(std::string, std::string, std::string); |
||||
|
||||
CommandParser* cmdParse; |
||||
void formatCommand(std::string* command); |
||||
void SendCommand(std::string command); |
||||
void RecvCommand(std::string* command); |
||||
void SetState(ServoMode::Mode mode); |
||||
void Sync(std::string host); |
||||
|
||||
void WalkTo(float x, float y); |
||||
|
||||
//Threads
|
||||
void Serv(); |
||||
void ServPos(); |
||||
void Client(); |
||||
void Follow(); |
||||
public: |
||||
Servo() {} |
||||
~Servo() {} |
||||
plugininfo_t GetPluginInfo(void) override; |
||||
|
||||
bool Initialize(IAshitaCore* ashitaCore, ILogManager* log, uint32_t dwPluginId) override; |
||||
void Release(void) override; |
||||
bool HandleCommand(const char* pszCommand, int nCommandType) override; |
||||
bool Direct3DInitialize(IDirect3DDevice8* lpDevice) override; |
||||
void Direct3DRender(void) override; |
||||
bool HandleIncomingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) override; |
||||
bool HandleOutgoingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) override; |
||||
}; |
||||
|
||||
#endif //__ASHITA_SERVO_H_INCLUDED__
|
@ -0,0 +1,202 @@
@@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?> |
||||
<VisualStudioProject |
||||
ProjectType="Visual C++" |
||||
Version="9.00" |
||||
Name="Servo" |
||||
ProjectGUID="{EA36DE2F-4E69-4FF6-A007-AA919DBD6E43}" |
||||
RootNamespace="Servo" |
||||
Keyword="Win32Proj" |
||||
TargetFrameworkVersion="196613" |
||||
> |
||||
<Platforms> |
||||
<Platform |
||||
Name="Win32" |
||||
/> |
||||
</Platforms> |
||||
<ToolFiles> |
||||
</ToolFiles> |
||||
<Configurations> |
||||
<Configuration |
||||
Name="Debug|Win32" |
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
||||
IntermediateDirectory="$(ConfigurationName)" |
||||
ConfigurationType="2" |
||||
CharacterSet="1" |
||||
> |
||||
<Tool |
||||
Name="VCPreBuildEventTool" |
||||
/> |
||||
<Tool |
||||
Name="VCCustomBuildTool" |
||||
/> |
||||
<Tool |
||||
Name="VCXMLDataGeneratorTool" |
||||
/> |
||||
<Tool |
||||
Name="VCWebServiceProxyGeneratorTool" |
||||
/> |
||||
<Tool |
||||
Name="VCMIDLTool" |
||||
/> |
||||
<Tool |
||||
Name="VCCLCompilerTool" |
||||
Optimization="0" |
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SERVO_EXPORTS" |
||||
MinimalRebuild="true" |
||||
BasicRuntimeChecks="3" |
||||
RuntimeLibrary="3" |
||||
UsePrecompiledHeader="0" |
||||
WarningLevel="3" |
||||
DebugInformationFormat="4" |
||||
/> |
||||
<Tool |
||||
Name="VCManagedResourceCompilerTool" |
||||
/> |
||||
<Tool |
||||
Name="VCResourceCompilerTool" |
||||
/> |
||||
<Tool |
||||
Name="VCPreLinkEventTool" |
||||
/> |
||||
<Tool |
||||
Name="VCLinkerTool" |
||||
LinkIncremental="2" |
||||
ModuleDefinitionFile="exports.def" |
||||
GenerateDebugInformation="true" |
||||
SubSystem="2" |
||||
TargetMachine="1" |
||||
/> |
||||
<Tool |
||||
Name="VCALinkTool" |
||||
/> |
||||
<Tool |
||||
Name="VCManifestTool" |
||||
/> |
||||
<Tool |
||||
Name="VCXDCMakeTool" |
||||
/> |
||||
<Tool |
||||
Name="VCBscMakeTool" |
||||
/> |
||||
<Tool |
||||
Name="VCFxCopTool" |
||||
/> |
||||
<Tool |
||||
Name="VCAppVerifierTool" |
||||
/> |
||||
<Tool |
||||
Name="VCPostBuildEventTool" |
||||
/> |
||||
</Configuration> |
||||
<Configuration |
||||
Name="Release|Win32" |
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
||||
IntermediateDirectory="$(ConfigurationName)" |
||||
ConfigurationType="2" |
||||
CharacterSet="1" |
||||
WholeProgramOptimization="1" |
||||
> |
||||
<Tool |
||||
Name="VCPreBuildEventTool" |
||||
/> |
||||
<Tool |
||||
Name="VCCustomBuildTool" |
||||
/> |
||||
<Tool |
||||
Name="VCXMLDataGeneratorTool" |
||||
/> |
||||
<Tool |
||||
Name="VCWebServiceProxyGeneratorTool" |
||||
/> |
||||
<Tool |
||||
Name="VCMIDLTool" |
||||
/> |
||||
<Tool |
||||
Name="VCCLCompilerTool" |
||||
Optimization="2" |
||||
EnableIntrinsicFunctions="true" |
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SERVO_EXPORTS" |
||||
RuntimeLibrary="2" |
||||
EnableFunctionLevelLinking="true" |
||||
UsePrecompiledHeader="0" |
||||
WarningLevel="3" |
||||
DebugInformationFormat="3" |
||||
/> |
||||
<Tool |
||||
Name="VCManagedResourceCompilerTool" |
||||
/> |
||||
<Tool |
||||
Name="VCResourceCompilerTool" |
||||
/> |
||||
<Tool |
||||
Name="VCPreLinkEventTool" |
||||
/> |
||||
<Tool |
||||
Name="VCLinkerTool" |
||||
LinkIncremental="1" |
||||
GenerateDebugInformation="true" |
||||
SubSystem="2" |
||||
OptimizeReferences="2" |
||||
EnableCOMDATFolding="2" |
||||
TargetMachine="1" |
||||
/> |
||||
<Tool |
||||
Name="VCALinkTool" |
||||
/> |
||||
<Tool |
||||
Name="VCManifestTool" |
||||
/> |
||||
<Tool |
||||
Name="VCXDCMakeTool" |
||||
/> |
||||
<Tool |
||||
Name="VCBscMakeTool" |
||||
/> |
||||
<Tool |
||||
Name="VCFxCopTool" |
||||
/> |
||||
<Tool |
||||
Name="VCAppVerifierTool" |
||||
/> |
||||
<Tool |
||||
Name="VCPostBuildEventTool" |
||||
/> |
||||
</Configuration> |
||||
</Configurations> |
||||
<References> |
||||
</References> |
||||
<Files> |
||||
<Filter |
||||
Name="Source Files" |
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" |
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" |
||||
> |
||||
<File |
||||
RelativePath=".\Exports.def" |
||||
> |
||||
</File> |
||||
<File |
||||
RelativePath=".\main.cpp" |
||||
> |
||||
</File> |
||||
</Filter> |
||||
<Filter |
||||
Name="Header Files" |
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd" |
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" |
||||
> |
||||
<File |
||||
RelativePath=".\Servo.h" |
||||
> |
||||
</File> |
||||
</Filter> |
||||
<Filter |
||||
Name="Resource Files" |
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" |
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" |
||||
> |
||||
</Filter> |
||||
</Files> |
||||
<Globals> |
||||
</Globals> |
||||
</VisualStudioProject> |
Binary file not shown.
@ -0,0 +1,594 @@
@@ -0,0 +1,594 @@
|
||||
#include "Servo.h" |
||||
#include <sstream> |
||||
|
||||
#pragma comment(lib, "Psapi.lib") |
||||
#include <Psapi.h> |
||||
|
||||
#include <algorithm> |
||||
#include <functional> |
||||
#include <cctype> |
||||
#include <locale> |
||||
|
||||
// trim from start (in place)
|
||||
static inline void ltrim(std::string &s) { |
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), |
||||
std::not1(std::ptr_fun<int, int>(std::isspace)))); |
||||
} |
||||
|
||||
// trim from end (in place)
|
||||
static inline void rtrim(std::string &s) { |
||||
s.erase(std::find_if(s.rbegin(), s.rend(), |
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); |
||||
} |
||||
|
||||
// trim from both ends (in place)
|
||||
static inline void trim(std::string &s) { |
||||
ltrim(s); |
||||
rtrim(s); |
||||
} |
||||
|
||||
// trim from start (copying)
|
||||
static inline std::string ltrimmed(std::string s) { |
||||
ltrim(s); |
||||
return s; |
||||
} |
||||
|
||||
// trim from end (copying)
|
||||
static inline std::string rtrimmed(std::string s) { |
||||
rtrim(s); |
||||
return s; |
||||
} |
||||
|
||||
// trim from both ends (copying)
|
||||
static inline std::string trimmed(std::string s) { |
||||
trim(s); |
||||
return s; |
||||
} |
||||
|
||||
|
||||
|
||||
std::string Servo::StringSub(std::string instring, std::string subin, std::string subout) |
||||
{ |
||||
if (instring.find(subin) != std::string::npos) |
||||
return(instring.replace(instring.find(subin), subin.length(), subout)); |
||||
else |
||||
return instring; |
||||
} |
||||
|
||||
void Servo::formatCommand(std::string* command) |
||||
{ |
||||
std::stringstream id; |
||||
id << m_AshitaCore->GetDataManager()->GetTarget()->GetTargetServerId(); |
||||
|
||||
*command = StringSub(*command, "[me]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(0)); |
||||
*command = StringSub(*command, "[p0]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(0)); |
||||
*command = StringSub(*command, "[p1]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(1)); |
||||
*command = StringSub(*command, "[p2]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(2)); |
||||
*command = StringSub(*command, "[p3]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(3)); |
||||
*command = StringSub(*command, "[p4]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(4)); |
||||
*command = StringSub(*command, "[p5]", m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(5)); |
||||
*command = StringSub(*command, "[t]", id.str()); |
||||
} |
||||
|
||||
void Servo::SendCommand(std::string command) |
||||
{ |
||||
while (!lock.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); |
||||
buffer.push_back(command); |
||||
lock.unlock(); |
||||
} |
||||
|
||||
void Servo::WalkTo(float x, float z) |
||||
{ |
||||
if (zoning) |
||||
return; |
||||
|
||||
auto myX = m_AshitaCore->GetDataManager()->GetEntity()->GetLocalX(m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)); |
||||
auto myZ = m_AshitaCore->GetDataManager()->GetEntity()->GetLocalZ(m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)); |
||||
auto myStatus = m_AshitaCore->GetDataManager()->GetEntity()->GetStatus(m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)); |
||||
float dist = sqrt(pow((myX - x), 2.0f) + pow((myZ - z), 2.0f)); |
||||
if (dist > 1.5f && (myStatus == 0 || myStatus == 5)) |
||||
{ |
||||
if (StructPointer->AutoRun != 1) |
||||
StructPointer->AutoRun = 1; |
||||
StructPointer->DirectionX = x - myX; |
||||
StructPointer->DirectionZ = z - myZ; |
||||
StructPointer->DirectionY = 0; |
||||
} |
||||
else |
||||
StructPointer->AutoRun = 0; |
||||
} |
||||
|
||||
void Servo::RecvCommand(std::string* command) |
||||
{ |
||||
command->erase(); |
||||
if (lock.try_lock()) |
||||
{ |
||||
if (!buffer.empty()) |
||||
{ |
||||
command->swap(buffer.front()); |
||||
buffer.pop_front(); |
||||
} |
||||
lock.unlock(); |
||||
} |
||||
} |
||||
|
||||
void Servo::SetState(ServoMode::Mode mode) |
||||
{ |
||||
ServoMode::Mode prevState = state; |
||||
state = ServoMode::Mode::Standby; |
||||
follow = false; |
||||
zoning = false; |
||||
connected = false; |
||||
if (prevState != ServoMode::Mode::Standby) |
||||
{ |
||||
conn.join(); |
||||
pos.join(); |
||||
} |
||||
while (!buffer.empty()) |
||||
buffer.pop_front(); |
||||
state = mode; |
||||
} |
||||
|
||||
void Servo::Sync(std::string host) |
||||
{ |
||||
me = m_AshitaCore->GetDataManager()->GetParty()->GetMemberName(0); |
||||
log << Chat::Format::RoyalBlue << "Servo started in client mode, connected to: "; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (host != "") |
||||
{ |
||||
servAddr = host; |
||||
log << servAddr; |
||||
} |
||||
else |
||||
{ |
||||
servAddr = ""; |
||||
log << "localhost"; |
||||
} |
||||
lservAddr.unlock(); |
||||
|
||||
SetState(ServoMode::Mode::Client); |
||||
conn.swap(std::thread(&Servo::Client, this)); |
||||
pos.swap(std::thread(&Servo::Follow, this)); |
||||
log << Chat::Control::flush; |
||||
} |
||||
|
||||
bool Servo::Initialize(IAshitaCore* ashitaCore, ILogManager* logManager, uint32_t dwPluginId) |
||||
{ |
||||
this->m_AshitaCore = ashitaCore; |
||||
this->m_PluginId = dwPluginId; |
||||
|
||||
// Obtain the base module information..
|
||||
MODULEINFO mod = { 0 }; |
||||
if (!::GetModuleInformation(::GetCurrentProcess(), ::GetModuleHandle("FFXiMain.dll"), &mod, sizeof(MODULEINFO))) |
||||
return false; |
||||
|
||||
// Cast the data and scan for the pattern..
|
||||
std::vector<uint8_t> data((uint8_t*)(uintptr_t)mod.lpBaseOfDll, (uint8_t*)(uintptr_t)mod.lpBaseOfDll + mod.SizeOfImage); |
||||
|
||||
unsigned char* Pointer = (unsigned char*)Ashita::Memory::FindPattern(std::ref(data), (uintptr_t)mod.lpBaseOfDll, "8BCDE87F7????F8B0D7F7F7F7FE87F7F7F7F8BF885??750CB9", 0, 0); |
||||
StructPointer = NULL; |
||||
if (Pointer != NULL) |
||||
{ |
||||
|
||||
Pointer += 25; |
||||
StructPointer = (auto_follow*)(*((DWORD*)Pointer)); |
||||
} |
||||
|
||||
if (StructPointer) |
||||
{ |
||||
StructPointer->DirectionX; |
||||
StructPointer->DirectionZ; |
||||
StructPointer->AutoRun; |
||||
} |
||||
|
||||
cmdParse = new CommandParser; |
||||
state = ServoMode::Mode::Standby; |
||||
lservAddr.lock(); |
||||
servAddr = ""; |
||||
lservAddr.unlock(); |
||||
me = ""; |
||||
follow = false; |
||||
zoning = false; |
||||
|
||||
zContext = zmq::context_t(1); |
||||
conn = std::thread(); |
||||
pos = std::thread(); |
||||
|
||||
log.SetCore(m_AshitaCore); |
||||
log << Chat::Mode::Echo; |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
void Servo::Serv() |
||||
{ |
||||
zmq::socket_t publisher(zContext, ZMQ_PUB); |
||||
std::string hostmask = "tcp://"; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (!servAddr.empty()) |
||||
hostmask.append(servAddr); |
||||
else |
||||
hostmask.append("127.0.0.1"); |
||||
lservAddr.unlock(); |
||||
hostmask.append(":56556"); |
||||
publisher.bind(hostmask.c_str()); |
||||
|
||||
connected = true; |
||||
|
||||
while (connected) { |
||||
while (!lock.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (!buffer.empty()) |
||||
{ |
||||
auto it = buffer.begin(); |
||||
zmq::message_t message(it->length() + 1); |
||||
strcpy_s((char*)message.data(), (size_t)(it->length() + 1), it->c_str()); |
||||
buffer.pop_front(); |
||||
lock.unlock(); |
||||
publisher.send(message, ZMQ_DONTWAIT); |
||||
} |
||||
else |
||||
lock.unlock(); |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); |
||||
} |
||||
publisher.close(); |
||||
} |
||||
|
||||
void Servo::ServPos() |
||||
{ |
||||
zmq::socket_t publisher(zContext, ZMQ_PUB); |
||||
std::string hostmask = "tcp://"; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (!servAddr.empty()) |
||||
hostmask.append(servAddr); |
||||
else |
||||
hostmask.append("127.0.0.1"); |
||||
lservAddr.unlock(); |
||||
hostmask.append(":56557"); |
||||
publisher.bind(hostmask.c_str()); |
||||
|
||||
if (!connected) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
||||
|
||||
while (connected) { |
||||
if (!zoning && m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)) |
||||
{ |
||||
auto myX = m_AshitaCore->GetDataManager()->GetEntity()->GetLocalX(m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)); |
||||
auto myZ = m_AshitaCore->GetDataManager()->GetEntity()->GetLocalZ(m_AshitaCore->GetDataManager()->GetParty()->GetMemberTargetIndex(0)); |
||||
|
||||
std::stringstream ss; |
||||
ss << m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0) << " " << myX << " " << myZ; |
||||
zmq::message_t message(strlen(ss.str().c_str()) + 1); |
||||
strcpy_s((char*)message.data(), strlen(ss.str().c_str()) + 1, ss.str().c_str()); |
||||
publisher.send(message, ZMQ_DONTWAIT); |
||||
} |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200)); |
||||
} |
||||
publisher.close(); |
||||
} |
||||
|
||||
void Servo::Client() |
||||
{ |
||||
std::string host = "tcp://"; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (!servAddr.empty()) |
||||
host.append(servAddr); |
||||
else |
||||
host.append("localhost"); |
||||
lservAddr.unlock(); |
||||
host.append(":56556"); |
||||
zmq::socket_t subscriber(zContext, ZMQ_SUB); |
||||
subscriber.connect(host.c_str()); |
||||
subscriber.setsockopt(ZMQ_SUBSCRIBE, me.c_str(), me.size()); |
||||
for (auto it = groups.begin(); it != groups.end(); ++it) |
||||
subscriber.setsockopt(ZMQ_SUBSCRIBE, it->c_str(), it->size()); |
||||
subscriber.setsockopt(ZMQ_SUBSCRIBE, "::", 2); |
||||
subscriber.setsockopt(ZMQ_SUBSCRIBE, ":SERVOFUNC:", 11); |
||||
connected = true; |
||||
|
||||
while (connected) |
||||
{ |
||||
zmq::message_t update; |
||||
|
||||
while (subscriber.recv(&update, ZMQ_DONTWAIT) == false) |
||||
{ |
||||
if (connected) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); |
||||
else |
||||
break; |
||||
} |
||||
|
||||
std::string s(static_cast<char*>(update.data())); |
||||
if (!s.empty()) |
||||
{ |
||||
while (!lock.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
buffer.push_back(s); |
||||
lock.unlock(); |
||||
} |
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); |
||||
} |
||||
subscriber.close(); |
||||
} |
||||
|
||||
void Servo::Follow() |
||||
{ |
||||
std::string host = "tcp://"; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (!servAddr.empty()) |
||||
host.append(servAddr); |
||||
else |
||||
host.append("localhost"); |
||||
lservAddr.unlock(); |
||||
host.append(":56557"); |
||||
zmq::socket_t subscriber(zContext, ZMQ_SUB); |
||||
subscriber.connect(host.c_str()); |
||||
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0); |
||||
|
||||
if (!connected) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
||||
|
||||
while (connected) |
||||
{ |
||||
zmq::message_t update; |
||||
while (follow) |
||||
{ |
||||
update = zmq::message_t(); |
||||
while (subscriber.recv(&update, ZMQ_DONTWAIT) == false) |
||||
{ |
||||
if (connected) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
else |
||||
break; |
||||
} |
||||
std::stringstream ss(static_cast<char*>(update.data())); |
||||
if (!ss.str().empty()) |
||||
{ |
||||
float WARPX, WARPY; |
||||
short zoneid; |
||||
ss >> zoneid >> WARPX >> WARPY; |
||||
if (zoneid == m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)) |
||||
WalkTo(WARPX, WARPY); |
||||
else |
||||
StructPointer->AutoRun = 0; // If no longer sharing the same zone, stop running (will trigger after the server char has arrived in the new area, so there is some delay)
|
||||
} |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
} |
||||
|
||||
while (subscriber.recv(&update, ZMQ_DONTWAIT) == false) |
||||
{ |
||||
if (connected & !follow) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
else |
||||
break; |
||||
} |
||||
|
||||
update.data(); // Discard data when not following.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
||||
} |
||||
subscriber.close(); |
||||
} |
||||
|
||||
void Servo::Release() |
||||
{ |
||||
SetState(ServoMode::Mode::Standby); |
||||
zContext.close(); |
||||
delete cmdParse; |
||||
} |
||||
|
||||
plugininfo_t Servo::GetPluginInfo(void) |
||||
{ |
||||
return (*g_PluginInfo); |
||||
} |
||||
|
||||
bool Servo::HandleCommand(const char* szCommand, int iType) |
||||
{ |
||||
if (iType == 0) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
char szClean[1024]; |
||||
if (iType != -2) |
||||
m_AshitaCore->GetChatManager()->ParseAutoTranslate(szCommand, szClean, 1024, false); |
||||
else |
||||
strncpy_s(szClean, szCommand, 1024); |
||||
|
||||
std::string arg; |
||||
|
||||
cmdParse->InputCommand(szClean); |
||||
cmdParse->GetFirstCommand(&arg); |
||||
|
||||
if (arg == "/servo") |
||||
{ |
||||
cmdParse->GetNextCommand(&arg); |
||||
if (arg == "on") |
||||
{ |
||||
log << Chat::Format::RoyalBlue << "Servo started in server mode, with a hostmask of: "; |
||||
while (!lservAddr.try_lock()) |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
||||
if (cmdParse->GetNextCommand(&arg)) |
||||
{ |
||||
servAddr = arg; |
||||
log << servAddr; |
||||
} |
||||
else |
||||
{ |
||||
servAddr = ""; |
||||
log << "localhost"; |
||||
} |
||||
lservAddr.unlock(); |
||||
|
||||
SetState(ServoMode::Mode::Server); |
||||
conn.swap(std::thread(&Servo::Serv, this)); |
||||
pos.swap(std::thread(&Servo::ServPos, this)); |
||||
log << Chat::Control::flush; |
||||
} |
||||
else if (arg == "sync") |
||||
{ |
||||
if (!cmdParse->GetNextCommand(&arg)) |
||||
arg = ""; |
||||
Sync(arg); |
||||
} |
||||
else if (arg == "off") |
||||
{ |
||||
SetState(ServoMode::Mode::Standby); |
||||
log << Chat::Format::RoyalBlue << "Servo set to standy!" << Chat::Control::flush; |
||||
} |
||||
else if (arg == "command" || arg == "send") |
||||
{ |
||||
if (cmdParse->GetRemainingCommands(&arg)) |
||||
{ |
||||
arg = ":: " + arg; |
||||
formatCommand(&arg); |
||||
SendCommand(arg); |
||||
} |
||||
|
||||
} |
||||
else if (arg == "sendto") |
||||
{ |
||||
if (cmdParse->GetRemainingCommands(&arg)) |
||||
{ |
||||
formatCommand(&arg); |
||||
SendCommand(arg); |
||||
} |
||||
|
||||
} |
||||
else if (arg == "followme") |
||||
{ |
||||
if (state.load() == ServoMode::Mode::Server) |
||||
{ |
||||
if (!cmdParse->GetNextCommand(&arg)) |
||||
{ |
||||
if (arg == "on") |
||||
SendCommand(":SERVOFUNC: FOLLOWON"); |
||||
else if (arg == "off") |
||||
SendCommand(":SERVOFUNC: FOLLOWOFF"); |
||||
} |
||||
else |
||||
SendCommand(":SERVOFUNC: FOLLOW"); |
||||
} |
||||
} |
||||
else if (arg == "follow") |
||||
{ |
||||
if (state.load() == ServoMode::Mode::Client) |
||||
{ |
||||
if (!cmdParse->GetNextCommand(&arg)) |
||||
{ |
||||
if (arg == "on") |
||||
follow = true; |
||||
else if (arg == "off") |
||||
follow = false; |
||||
} |
||||
else |
||||
follow = follow ? false : true; |
||||
} |
||||
} |
||||
else if (arg == "addgroup") |
||||
{ |
||||
std::string group; |
||||
cmdParse->GetNextCommand(&group); |
||||
groups.push_back(group); |
||||
if (state == ServoMode::Mode::Client) |
||||
Sync(servAddr); |
||||
} |
||||
else if (arg == "delgroup") |
||||
{ |
||||
bool changed = false; |
||||
std::string group; |
||||
cmdParse->GetNextCommand(&group); |
||||
for (auto it = groups.begin(); it != groups.end();) |
||||
{ |
||||
if (*it == group) |
||||
{ |
||||
changed = true; |
||||
it = groups.erase(it); |
||||
} |
||||
else |
||||
++it; |
||||
} |
||||
if (state == ServoMode::Mode::Client && changed) |
||||
Sync(servAddr); |
||||
} |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool Servo::Direct3DInitialize(IDirect3DDevice8* mDevice) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
void Servo::Direct3DRender() |
||||
{ |
||||
if (state.load() == ServoMode::Mode::Client) |
||||
{ |
||||
std::string commandtype; |
||||
std::string incommand; |
||||
RecvCommand(&incommand); |
||||
if (!incommand.empty()) |
||||
{ |
||||
commandtype = incommand.substr(0, incommand.find_first_of(" ")); |
||||
incommand = incommand.substr(incommand.find_first_of(" ") + 1); |
||||
if (commandtype != ":SERVOFUNC:") |
||||
{ |
||||
auto cmd = incommand; |
||||
trim(cmd); |
||||
m_AshitaCore->GetChatManager()->QueueCommand(cmd.c_str(), (int32_t)Ashita::CommandInputType::Menu); |
||||
} |
||||
else |
||||
{ |
||||
if (incommand == "FOLLOWON") |
||||
follow = true; |
||||
else if (incommand == "FOLLOWOFF") |
||||
follow = false; |
||||
else if (incommand == "FOLLOW") |
||||
follow = follow ? false : true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool Servo::HandleOutgoingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) |
||||
{ |
||||
if (id == 0x5E) |
||||
zoning = true; |
||||
return false; |
||||
} |
||||
|
||||
bool Servo::HandleIncomingPacket(uint16_t id, uint32_t size, void* data, void* modified, bool blocked) |
||||
{ |
||||
if (id == 0x0A) |
||||
zoning = false; |
||||
return false; |
||||
} |
||||
|
||||
__declspec(dllexport) double __stdcall GetInterfaceVersion(void) |
||||
{ |
||||
return ASHITA_INTERFACE_VERSION; |
||||
} |
||||
|
||||
__declspec(dllexport) void __stdcall CreatePluginInfo(plugininfo_t* lpBuffer) |
||||
{ |
||||
g_PluginInfo = lpBuffer; |
||||
|
||||
strcpy_s(g_PluginInfo->Name, sizeof(g_PluginInfo->Name), "Servo"); |
||||
strcpy_s(g_PluginInfo->Author, sizeof(g_PluginInfo->Author), "bluekirby0"); |
||||
|
||||
g_PluginInfo->InterfaceVersion = ASHITA_INTERFACE_VERSION; |
||||
g_PluginInfo->PluginVersion = 3.00f; |
||||
g_PluginInfo->Priority = 0; |
||||
} |
||||
|
||||
__declspec(dllexport) IPlugin* __stdcall CreatePlugin(void) |
||||
{ |
||||
return (IPlugin*)new Servo(); |
||||
} |
@ -0,0 +1,416 @@
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file |
||||
|
||||
This file is part of 0MQ. |
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under |
||||
the terms of the GNU Lesser General Public License as published by |
||||
the Free Software Foundation; either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
0MQ is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU Lesser General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
************************************************************************* |
||||
NOTE to contributors. This file comprises the principal public contract |
||||
for ZeroMQ API users (along with zmq_utils.h). Any change to this file |
||||
supplied in a stable release SHOULD not break existing applications. |
||||
In practice this means that the value of constants must not change, and |
||||
that old values may not be reused for new constants. |
||||
************************************************************************* |
||||
*/ |
||||
|
||||
#ifndef __ZMQ_H_INCLUDED__ |
||||
#define __ZMQ_H_INCLUDED__ |
||||
|
||||
/* Version macros for compile-time API version detection */ |
||||
#define ZMQ_VERSION_MAJOR 4 |
||||
#define ZMQ_VERSION_MINOR 0 |
||||
#define ZMQ_VERSION_PATCH 3 |
||||
|
||||
#define ZMQ_MAKE_VERSION(major, minor, patch) \ |
||||
((major) * 10000 + (minor) * 100 + (patch)) |
||||
#define ZMQ_VERSION \ |
||||
ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#if !defined _WIN32_WCE |
||||
#include <errno.h> |
||||
#endif |
||||
#include <stddef.h> |
||||
#include <stdio.h> |
||||
#if defined _WIN32 |
||||
#include <winsock2.h> |
||||
#endif |
||||
|
||||
/* Handle DSO symbol visibility */ |
||||
#if defined _WIN32 |
||||
# if defined ZMQ_STATIC |
||||
# define ZMQ_EXPORT |
||||
# elif defined DLL_EXPORT |
||||
# define ZMQ_EXPORT __declspec(dllexport) |
||||
# else |
||||
# define ZMQ_EXPORT __declspec(dllimport) |
||||
# endif |
||||
#else |
||||
# if defined __SUNPRO_C || defined __SUNPRO_CC |
||||
# define ZMQ_EXPORT __global |
||||
# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER |
||||
# define ZMQ_EXPORT __attribute__ ((visibility("default"))) |
||||
# else |
||||
# define ZMQ_EXPORT |
||||
# endif |
||||
#endif |
||||
|
||||
/* Define integer types needed for event interface */ |
||||
#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS |
||||
# include <inttypes.h> |
||||
#elif defined _MSC_VER && _MSC_VER < 1600 |
||||
# ifndef int32_t |
||||
typedef __int32 int32_t; |
||||
# endif |
||||
# ifndef uint16_t |
||||
typedef unsigned __int16 uint16_t; |
||||
# endif |
||||
# ifndef uint8_t |
||||
typedef unsigned __int8 uint8_t; |
||||
# endif |
||||
#else |
||||
# include <stdint.h> |
||||
#endif |
||||
|
||||
|
||||
/******************************************************************************/ |
||||
/* 0MQ errors. */ |
||||
/******************************************************************************/ |
||||
|
||||
/* A number random enough not to collide with different errno ranges on */ |
||||
/* different OSes. The assumption is that error_t is at least 32-bit type. */ |
||||
#define ZMQ_HAUSNUMERO 156384712 |
||||
|
||||
/* On Windows platform some of the standard POSIX errnos are not defined. */ |
||||
#ifndef ENOTSUP |
||||
#define ENOTSUP (ZMQ_HAUSNUMERO + 1) |
||||
#endif |
||||
#ifndef EPROTONOSUPPORT |
||||
#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) |
||||
#endif |
||||
#ifndef ENOBUFS |
||||
#define ENOBUFS (ZMQ_HAUSNUMERO + 3) |
||||
#endif |
||||
#ifndef ENETDOWN |
||||
#define ENETDOWN (ZMQ_HAUSNUMERO + 4) |
||||
#endif |
||||
#ifndef EADDRINUSE |
||||
#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) |
||||
#endif |
||||
#ifndef EADDRNOTAVAIL |
||||
#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) |
||||
#endif |
||||
#ifndef ECONNREFUSED |
||||
#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) |
||||
#endif |
||||
#ifndef EINPROGRESS |
||||
#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) |
||||
#endif |
||||
#ifndef ENOTSOCK |
||||
#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) |
||||
#endif |
||||
#ifndef EMSGSIZE |
||||
#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) |
||||
#endif |
||||
#ifndef EAFNOSUPPORT |
||||
#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) |
||||
#endif |
||||
#ifndef ENETUNREACH |
||||
#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) |
||||
#endif |
||||
#ifndef ECONNABORTED |
||||
#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) |
||||
#endif |
||||
#ifndef ECONNRESET |
||||
#define ECONNRESET (ZMQ_HAUSNUMERO + 14) |
||||
#endif |
||||
#ifndef ENOTCONN |
||||
#define ENOTCONN (ZMQ_HAUSNUMERO + 15) |
||||
#endif |
||||
#ifndef ETIMEDOUT |
||||
#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) |
||||
#endif |
||||
#ifndef EHOSTUNREACH |
||||
#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) |
||||
#endif |
||||
#ifndef ENETRESET |
||||
#define ENETRESET (ZMQ_HAUSNUMERO + 18) |
||||
#endif |
||||
|
||||
/* Native 0MQ error codes. */ |
||||
#define EFSM (ZMQ_HAUSNUMERO + 51) |
||||
#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) |
||||
#define ETERM (ZMQ_HAUSNUMERO + 53) |
||||
#define EMTHREAD (ZMQ_HAUSNUMERO + 54) |
||||
|
||||
/* Run-time API version detection */ |
||||
ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); |
||||
|
||||
/* This function retrieves the errno as it is known to 0MQ library. The goal */ |
||||
/* of this function is to make the code 100% portable, including where 0MQ */ |
||||
/* compiled with certain CRT library (on Windows) is linked to an */ |
||||
/* application that uses different CRT library. */ |
||||
ZMQ_EXPORT int zmq_errno (void); |
||||
|
||||
/* Resolves system errors and 0MQ errors to human-readable string. */ |
||||
ZMQ_EXPORT const char *zmq_strerror (int errnum); |
||||
|
||||
/******************************************************************************/ |
||||
/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ |
||||
/******************************************************************************/ |
||||
|
||||
/* New API */ |
||||
/* Context options */ |
||||
#define ZMQ_IO_THREADS 1 |
||||
#define ZMQ_MAX_SOCKETS 2 |
||||
|
||||
/* Default for new contexts */ |
||||
#define ZMQ_IO_THREADS_DFLT 1 |
||||
#define ZMQ_MAX_SOCKETS_DFLT 1023 |
||||
|
||||
ZMQ_EXPORT void *zmq_ctx_new (void); |
||||
ZMQ_EXPORT int zmq_ctx_term (void *context); |
||||
ZMQ_EXPORT int zmq_ctx_shutdown (void *ctx_); |
||||
ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval); |
||||
ZMQ_EXPORT int zmq_ctx_get (void *context, int option); |
||||
|
||||
/* Old (legacy) API */ |
||||
ZMQ_EXPORT void *zmq_init (int io_threads); |
||||
ZMQ_EXPORT int zmq_term (void *context); |
||||
ZMQ_EXPORT int zmq_ctx_destroy (void *context); |
||||
|
||||
|
||||
/******************************************************************************/ |
||||
/* 0MQ message definition. */ |
||||
/******************************************************************************/ |
||||
|
||||
typedef struct zmq_msg_t {unsigned char _ [32];} zmq_msg_t; |
||||
|
||||
typedef void (zmq_free_fn) (void *data, void *hint); |
||||
|
||||
ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg); |
||||
ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size); |
||||
ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data, |
||||
size_t size, zmq_free_fn *ffn, void *hint); |
||||
ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags); |
||||
ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags); |
||||
ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg); |
||||
ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); |
||||
ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); |
||||
ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg); |
||||
ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg); |
||||
ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg); |
||||
ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int option); |
||||
ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval); |
||||
|
||||
|
||||
/******************************************************************************/ |
||||
/* 0MQ socket definition. */ |
||||
/******************************************************************************/ |
||||
|
||||
/* Socket types. */ |
||||
#define ZMQ_PAIR 0 |
||||
#define ZMQ_PUB 1 |
||||
#define ZMQ_SUB 2 |
||||
#define ZMQ_REQ 3 |
||||
#define ZMQ_REP 4 |
||||
#define ZMQ_DEALER 5 |
||||
#define ZMQ_ROUTER 6 |
||||
#define ZMQ_PULL 7 |
||||
#define ZMQ_PUSH 8 |
||||
#define ZMQ_XPUB 9 |
||||
#define ZMQ_XSUB 10 |
||||
#define ZMQ_STREAM 11 |
||||
|
||||
/* Deprecated aliases */ |
||||
#define ZMQ_XREQ ZMQ_DEALER |
||||
#define ZMQ_XREP ZMQ_ROUTER |
||||
|
||||
/* Socket options. */ |
||||
#define ZMQ_AFFINITY 4 |
||||
#define ZMQ_IDENTITY 5 |
||||
#define ZMQ_SUBSCRIBE 6 |
||||
#define ZMQ_UNSUBSCRIBE 7 |
||||
#define ZMQ_RATE 8 |
||||
#define ZMQ_RECOVERY_IVL 9 |
||||
#define ZMQ_SNDBUF 11 |
||||
#define ZMQ_RCVBUF 12 |
||||
#define ZMQ_RCVMORE 13 |
||||
#define ZMQ_FD 14 |
||||
#define ZMQ_EVENTS 15 |
||||
#define ZMQ_TYPE 16 |
||||
#define ZMQ_LINGER 17 |
||||
#define ZMQ_RECONNECT_IVL 18 |
||||
#define ZMQ_BACKLOG 19 |
||||
#define ZMQ_RECONNECT_IVL_MAX 21 |
||||
#define ZMQ_MAXMSGSIZE 22 |
||||
#define ZMQ_SNDHWM 23 |
||||
#define ZMQ_RCVHWM 24 |
||||
#define ZMQ_MULTICAST_HOPS 25 |
||||
#define ZMQ_RCVTIMEO 27 |
||||
#define ZMQ_SNDTIMEO 28 |
||||
#define ZMQ_LAST_ENDPOINT 32 |
||||
#define ZMQ_ROUTER_MANDATORY 33 |
||||
#define ZMQ_TCP_KEEPALIVE 34 |
||||
#define ZMQ_TCP_KEEPALIVE_CNT 35 |
||||
#define ZMQ_TCP_KEEPALIVE_IDLE 36 |
||||
#define ZMQ_TCP_KEEPALIVE_INTVL 37 |
||||
#define ZMQ_TCP_ACCEPT_FILTER 38 |
||||
#define ZMQ_IMMEDIATE 39 |
||||
#define ZMQ_XPUB_VERBOSE 40 |
||||
#define ZMQ_ROUTER_RAW 41 |
||||
#define ZMQ_IPV6 42 |
||||
#define ZMQ_MECHANISM 43 |
||||
#define ZMQ_PLAIN_SERVER 44 |
||||
#define ZMQ_PLAIN_USERNAME 45 |
||||
#define ZMQ_PLAIN_PASSWORD 46 |
||||
#define ZMQ_CURVE_SERVER 47 |
||||
#define ZMQ_CURVE_PUBLICKEY 48 |
||||
#define ZMQ_CURVE_SECRETKEY 49 |
||||
#define ZMQ_CURVE_SERVERKEY 50 |
||||
#define ZMQ_PROBE_ROUTER 51 |
||||
#define ZMQ_REQ_CORRELATE 52 |
||||
#define ZMQ_REQ_RELAXED 53 |
||||
#define ZMQ_CONFLATE 54 |
||||
#define ZMQ_ZAP_DOMAIN 55 |
||||
|
||||
/* Message options */ |
||||
#define ZMQ_MORE 1 |
||||
|
||||
/* Send/recv options. */ |
||||
#define ZMQ_DONTWAIT 1 |
||||
#define ZMQ_SNDMORE 2 |
||||
|
||||
/* Security mechanisms */ |
||||
#define ZMQ_NULL 0 |
||||
#define ZMQ_PLAIN 1 |
||||
#define ZMQ_CURVE 2 |
||||
|
||||
/* Deprecated options and aliases */ |
||||
#define ZMQ_IPV4ONLY 31 |
||||
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE |
||||
#define ZMQ_NOBLOCK ZMQ_DONTWAIT |
||||
#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY |
||||
#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY |
||||
|
||||
/******************************************************************************/ |
||||
/* 0MQ socket events and monitoring */ |
||||
/******************************************************************************/ |
||||
|
||||
/* Socket transport events (tcp and ipc only) */ |
||||
#define ZMQ_EVENT_CONNECTED 1 |
||||
#define ZMQ_EVENT_CONNECT_DELAYED 2 |
||||
#define ZMQ_EVENT_CONNECT_RETRIED 4 |
||||
|
||||
#define ZMQ_EVENT_LISTENING 8 |
||||
#define ZMQ_EVENT_BIND_FAILED 16 |
||||
|
||||
#define ZMQ_EVENT_ACCEPTED 32 |
||||
#define ZMQ_EVENT_ACCEPT_FAILED 64 |
||||
|
||||
#define ZMQ_EVENT_CLOSED 128 |
||||
#define ZMQ_EVENT_CLOSE_FAILED 256 |
||||
#define ZMQ_EVENT_DISCONNECTED 512 |
||||
#define ZMQ_EVENT_MONITOR_STOPPED 1024 |
||||
|
||||
#define ZMQ_EVENT_ALL ( ZMQ_EVENT_CONNECTED | ZMQ_EVENT_CONNECT_DELAYED | \ |
||||
ZMQ_EVENT_CONNECT_RETRIED | ZMQ_EVENT_LISTENING | \ |
||||
ZMQ_EVENT_BIND_FAILED | ZMQ_EVENT_ACCEPTED | \ |
||||
ZMQ_EVENT_ACCEPT_FAILED | ZMQ_EVENT_CLOSED | \ |
||||
ZMQ_EVENT_CLOSE_FAILED | ZMQ_EVENT_DISCONNECTED | \ |
||||
ZMQ_EVENT_MONITOR_STOPPED) |
||||
|
||||
/* Socket event data */ |
||||
typedef struct { |
||||
uint16_t event; // id of the event as bitfield
|
||||
int32_t value ; // value is either error code, fd or reconnect interval
|
||||
} zmq_event_t; |
||||
|
||||
ZMQ_EXPORT void *zmq_socket (void *, int type); |
||||
ZMQ_EXPORT int zmq_close (void *s); |
||||
ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval, |
||||
size_t optvallen); |
||||
ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval, |
||||
size_t *optvallen); |
||||
ZMQ_EXPORT int zmq_bind (void *s, const char *addr); |
||||
ZMQ_EXPORT int zmq_connect (void *s, const char *addr); |
||||
ZMQ_EXPORT int zmq_unbind (void *s, const char *addr); |
||||
ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr); |
||||
ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags); |
||||
ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags); |
||||
ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags); |
||||
ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events); |
||||
|
||||
ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags); |
||||
ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags); |
||||
|
||||
/* Experimental */ |
||||
struct iovec; |
||||
|
||||
ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags); |
||||
ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags); |
||||
|
||||
/******************************************************************************/ |
||||
/* I/O multiplexing. */ |
||||
/******************************************************************************/ |
||||
|
||||
#define ZMQ_POLLIN 1 |
||||
#define ZMQ_POLLOUT 2 |
||||
#define ZMQ_POLLERR 4 |
||||
|
||||
typedef struct |
||||
{ |
||||
void *socket; |
||||
#if defined _WIN32 |
||||
SOCKET fd; |
||||
#else |
||||
int fd; |
||||
#endif |
||||
short events; |
||||
short revents; |
||||
} zmq_pollitem_t; |
||||
|
||||
#define ZMQ_POLLITEMS_DFLT 16 |
||||
|
||||
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); |
||||
|
||||
/* Built-in message proxy (3-way) */ |
||||
|
||||
ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture); |
||||
|
||||
/* Encode a binary key as printable text using ZMQ RFC 32 */ |
||||
ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size); |
||||
|
||||
/* Encode a binary key from printable text per ZMQ RFC 32 */ |
||||
ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string); |
||||
|
||||
/* Deprecated aliases */ |
||||
#define ZMQ_STREAMER 1 |
||||
#define ZMQ_FORWARDER 2 |
||||
#define ZMQ_QUEUE 3 |
||||
/* Deprecated method */ |
||||
ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend); |
||||
|
||||
#undef ZMQ_EXPORT |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file |
||||
|
||||
This file is part of 0MQ. |
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under |
||||
the terms of the GNU Lesser General Public License as published by |
||||
the Free Software Foundation; either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
0MQ is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU Lesser General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef __ZMQ_UTILS_H_INCLUDED__ |
||||
#define __ZMQ_UTILS_H_INCLUDED__ |
||||
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
|
||||
/* Define integer types needed for event interface */ |
||||
#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS |
||||
# include <inttypes.h> |
||||
#elif defined _MSC_VER && _MSC_VER < 1600 |
||||
# ifndef int32_t |
||||
typedef __int32 int32_t; |
||||
# endif |
||||
# ifndef uint16_t |
||||
typedef unsigned __int16 uint16_t; |
||||
# endif |
||||
#else |
||||
# include <stdint.h> |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Handle DSO symbol visibility */ |
||||
#if defined _WIN32 |
||||
# if defined ZMQ_STATIC |
||||
# define ZMQ_EXPORT |
||||
# elif defined DLL_EXPORT |
||||
# define ZMQ_EXPORT __declspec(dllexport) |
||||
# else |
||||
# define ZMQ_EXPORT __declspec(dllimport) |
||||
# endif |
||||
#else |
||||
# if defined __SUNPRO_C || defined __SUNPRO_CC |
||||
# define ZMQ_EXPORT __global |
||||
# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER |
||||
# define ZMQ_EXPORT __attribute__ ((visibility("default"))) |
||||
# else |
||||
# define ZMQ_EXPORT |
||||
# endif |
||||
#endif |
||||
|
||||
/* These functions are documented by man pages */ |
||||
|
||||
/* Encode data with Z85 encoding. Returns encoded data */ |
||||
ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size); |
||||
|
||||
/* Decode data with Z85 encoding. Returns decoded data */ |
||||
ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string); |
||||
|
||||
/* Generate z85-encoded public and private keypair with libsodium. */ |
||||
/* Returns 0 on success. */ |
||||
ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); |
||||
|
||||
typedef void (zmq_thread_fn) (void*); |
||||
|
||||
/* These functions are not documented by man pages */ |
||||
|
||||
/* Helper functions are used by perf tests so that they don't have to care */ |
||||
/* about minutiae of time-related functions on different OS platforms. */ |
||||
|
||||
/* Starts the stopwatch. Returns the handle to the watch. */ |
||||
ZMQ_EXPORT void *zmq_stopwatch_start (void); |
||||
|
||||
/* Stops the stopwatch. Returns the number of microseconds elapsed since */ |
||||
/* the stopwatch was started. */ |
||||
ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); |
||||
|
||||
/* Sleeps for specified number of seconds. */ |
||||
ZMQ_EXPORT void zmq_sleep (int seconds_); |
||||
|
||||
/* Start a thread. Returns a handle to the thread. */ |
||||
ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn* func, void* arg); |
||||
|
||||
/* Wait for thread to complete then free up resources. */ |
||||
ZMQ_EXPORT void zmq_threadclose (void* thread); |
||||
|
||||
#undef ZMQ_EXPORT |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
@ -0,0 +1,566 @@
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
Copyright (c) 2009-2011 250bpm s.r.o. |
||||
Copyright (c) 2011 Botond Ballo |
||||
Copyright (c) 2007-2009 iMatix Corporation |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to |
||||
deal in the Software without restriction, including without limitation the |
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
||||
sell copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||
IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#ifndef __ZMQ_HPP_INCLUDED__ |
||||
#define __ZMQ_HPP_INCLUDED__ |
||||
|
||||
#include <zmq.h> |
||||
|
||||
#include <algorithm> |
||||
#include <cassert> |
||||
#include <cstring> |
||||
#include <string> |
||||
#include <exception> |
||||
|
||||
// Detect whether the compiler supports C++11 rvalue references.
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || \ |
||||
(__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \ |
||||
defined(__GXX_EXPERIMENTAL_CXX0X__)) |
||||
#define ZMQ_HAS_RVALUE_REFS |
||||
#define ZMQ_DELETED_FUNCTION = delete |
||||
#elif defined(__clang__) |
||||
#if __has_feature(cxx_rvalue_references) |
||||
#define ZMQ_HAS_RVALUE_REFS |
||||
#endif |
||||
|
||||
#if __has_feature(cxx_deleted_functions) |
||||
#define ZMQ_DELETED_FUNCTION = delete |
||||
#else |
||||
#define ZMQ_DELETED_FUNCTION |
||||
#endif |
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1600) |
||||
#define ZMQ_HAS_RVALUE_REFS |
||||
#define ZMQ_DELETED_FUNCTION |
||||
#else |
||||
#define ZMQ_DELETED_FUNCTION |
||||
#endif |
||||
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) |
||||
#define ZMQ_NEW_MONITOR_EVENT_LAYOUT |
||||
#endif |
||||
|
||||
// In order to prevent unused variable warnings when building in non-debug
|
||||
// mode use this macro to make assertions.
|
||||
#ifndef NDEBUG |
||||
# define ZMQ_ASSERT(expression) assert(expression) |
||||
#else |
||||
# define ZMQ_ASSERT(expression) (void)(expression) |
||||
#endif |
||||
|
||||
namespace zmq |
||||
{ |
||||
|
||||
typedef zmq_free_fn free_fn; |
||||
typedef zmq_pollitem_t pollitem_t; |
||||
|
||||
class error_t : public std::exception |
||||
{ |
||||
public: |
||||
|
||||
error_t () : errnum (zmq_errno ()) {} |
||||
|
||||
virtual const char *what () const throw () |
||||
{ |
||||
return zmq_strerror (errnum); |
||||
} |
||||
|
||||
int num () const |
||||
{ |
||||
return errnum; |
||||
} |
||||
|
||||
private: |
||||
|
||||
int errnum; |
||||
}; |
||||
|
||||
inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1) |
||||
{ |
||||
int rc = zmq_poll (items_, nitems_, timeout_); |
||||
if (rc < 0) |
||||
throw error_t (); |
||||
return rc; |
||||
} |
||||
|
||||
inline void proxy (void *frontend, void *backend, void *capture) |
||||
{ |
||||
int rc = zmq_proxy (frontend, backend, capture); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void version (int *major_, int *minor_, int *patch_) |
||||
{ |
||||
zmq_version (major_, minor_, patch_); |
||||
} |
||||
|
||||
class message_t |
||||
{ |
||||
friend class socket_t; |
||||
|
||||
public: |
||||
|
||||
inline message_t () |
||||
{ |
||||
int rc = zmq_msg_init (&msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline explicit message_t (size_t size_) |
||||
{ |
||||
int rc = zmq_msg_init_size (&msg, size_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline message_t (void *data_, size_t size_, free_fn *ffn_, |
||||
void *hint_ = NULL) |
||||
{ |
||||
int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
#ifdef ZMQ_HAS_RVALUE_REFS |
||||
inline message_t (message_t &&rhs) : msg (rhs.msg) |
||||
{ |
||||
int rc = zmq_msg_init (&rhs.msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline message_t &operator = (message_t &&rhs) |
||||
{ |
||||
std::swap (msg, rhs.msg); |
||||
return *this; |
||||
} |
||||
#endif |
||||
|
||||
inline ~message_t () |
||||
{ |
||||
int rc = zmq_msg_close (&msg); |
||||
ZMQ_ASSERT (rc == 0); |
||||
} |
||||
|
||||
inline void rebuild () |
||||
{ |
||||
int rc = zmq_msg_close (&msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
rc = zmq_msg_init (&msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void rebuild (size_t size_) |
||||
{ |
||||
int rc = zmq_msg_close (&msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
rc = zmq_msg_init_size (&msg, size_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void rebuild (void *data_, size_t size_, free_fn *ffn_, |
||||
void *hint_ = NULL) |
||||
{ |
||||
int rc = zmq_msg_close (&msg); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void move (message_t *msg_) |
||||
{ |
||||
int rc = zmq_msg_move (&msg, &(msg_->msg)); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void copy (message_t *msg_) |
||||
{ |
||||
int rc = zmq_msg_copy (&msg, &(msg_->msg)); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline bool more () |
||||
{ |
||||
int rc = zmq_msg_more (&msg); |
||||
return rc != 0; |
||||
} |
||||
|
||||
inline void *data () |
||||
{ |
||||
return zmq_msg_data (&msg); |
||||
} |
||||
|
||||
inline const void* data () const |
||||
{ |
||||
return zmq_msg_data (const_cast<zmq_msg_t*>(&msg)); |
||||
} |
||||
|
||||
inline size_t size () const |
||||
{ |
||||
return zmq_msg_size (const_cast<zmq_msg_t*>(&msg)); |
||||
} |
||||
|
||||
private: |
||||
|
||||
// The underlying message
|
||||
zmq_msg_t msg; |
||||
|
||||
// Disable implicit message copying, so that users won't use shared
|
||||
// messages (less efficient) without being aware of the fact.
|
||||
message_t (const message_t&); |
||||
void operator = (const message_t&); |
||||
}; |
||||
|
||||
class context_t |
||||
{ |
||||
friend class socket_t; |
||||
|
||||
public: |
||||
inline context_t () |
||||
{ |
||||
ptr = zmq_ctx_new (); |
||||
if (ptr == NULL) |
||||
throw error_t (); |
||||
} |
||||
|
||||
|
||||
inline explicit context_t (int io_threads_) |
||||
{ |
||||
ptr = zmq_ctx_new (); |
||||
if (ptr == NULL) |
||||
throw error_t (); |
||||
|
||||
int rc = zmq_ctx_set (ptr, ZMQ_IO_THREADS, io_threads_); |
||||
ZMQ_ASSERT (rc == 0); |
||||
} |
||||
|
||||
#ifdef ZMQ_HAS_RVALUE_REFS |
||||
inline context_t (context_t &&rhs) : ptr (rhs.ptr) |
||||
{ |
||||
rhs.ptr = NULL; |
||||
} |
||||
inline context_t &operator = (context_t &&rhs) |
||||
{ |
||||
std::swap (ptr, rhs.ptr); |
||||
return *this; |
||||
} |
||||
#endif |
||||
|
||||
inline ~context_t () |
||||
{ |
||||
close(); |
||||
} |
||||
|
||||
inline void close() |
||||
{ |
||||
if (ptr == NULL) |
||||
return; |
||||
int rc = zmq_ctx_destroy (ptr); |
||||
ZMQ_ASSERT (rc == 0); |
||||
ptr = NULL; |
||||
} |
||||
|
||||
// Be careful with this, it's probably only useful for
|
||||
// using the C api together with an existing C++ api.
|
||||
// Normally you should never need to use this.
|
||||
inline operator void* () |
||||
{ |
||||
return ptr; |
||||
} |
||||
|
||||
private: |
||||
|
||||
void *ptr; |
||||
|
||||
context_t (const context_t&); |
||||
void operator = (const context_t&); |
||||
}; |
||||
|
||||
class socket_t |
||||
{ |
||||
friend class monitor_t; |
||||
public: |
||||
|
||||
inline socket_t (context_t &context_, int type_) |
||||
{ |
||||
ctxptr = context_.ptr; |
||||
ptr = zmq_socket (context_.ptr, type_); |
||||
if (ptr == NULL) |
||||
throw error_t (); |
||||
} |
||||
|
||||
#ifdef ZMQ_HAS_RVALUE_REFS |
||||
inline socket_t(socket_t&& rhs) : ptr(rhs.ptr) |
||||
{ |
||||
rhs.ptr = NULL; |
||||
} |
||||
inline socket_t& operator=(socket_t&& rhs) |
||||
{ |
||||
std::swap(ptr, rhs.ptr); |
||||
return *this; |
||||
} |
||||
#endif |
||||
|
||||
inline ~socket_t () |
||||
{ |
||||
close(); |
||||
} |
||||
|
||||
inline operator void* () |
||||
{ |
||||
return ptr; |
||||
} |
||||
|
||||
inline void close() |
||||
{ |
||||
if(ptr == NULL) |
||||
// already closed
|
||||
return ; |
||||
int rc = zmq_close (ptr); |
||||
ZMQ_ASSERT (rc == 0); |
||||
ptr = 0 ; |
||||
} |
||||
|
||||
inline void setsockopt (int option_, const void *optval_, |
||||
size_t optvallen_) |
||||
{ |
||||
int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void getsockopt (int option_, void *optval_, |
||||
size_t *optvallen_) |
||||
{ |
||||
int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void bind (const char *addr_) |
||||
{ |
||||
int rc = zmq_bind (ptr, addr_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void unbind (const char *addr_) |
||||
{ |
||||
int rc = zmq_unbind (ptr, addr_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void connect (const char *addr_) |
||||
{ |
||||
int rc = zmq_connect (ptr, addr_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline void disconnect (const char *addr_) |
||||
{ |
||||
int rc = zmq_disconnect (ptr, addr_); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline bool connected() |
||||
{ |
||||
return(ptr != NULL); |
||||
} |
||||
|
||||
inline size_t send (const void *buf_, size_t len_, int flags_ = 0) |
||||
{ |
||||
int nbytes = zmq_send (ptr, buf_, len_, flags_); |
||||
if (nbytes >= 0) |
||||
return (size_t) nbytes; |
||||
if (zmq_errno () == EAGAIN) |
||||
return 0; |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline bool send (message_t &msg_, int flags_ = 0) |
||||
{ |
||||
int nbytes = zmq_msg_send (&(msg_.msg), ptr, flags_); |
||||
if (nbytes >= 0) |
||||
return true; |
||||
if (zmq_errno () == EAGAIN) |
||||
return false; |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline size_t recv (void *buf_, size_t len_, int flags_ = 0) |
||||
{ |
||||
int nbytes = zmq_recv (ptr, buf_, len_, flags_); |
||||
if (nbytes >= 0) |
||||
return (size_t) nbytes; |
||||
if (zmq_errno () == EAGAIN) |
||||
return 0; |
||||
throw error_t (); |
||||
} |
||||
|
||||
inline bool recv (message_t *msg_, int flags_ = 0) |
||||
{ |
||||
int nbytes = zmq_msg_recv (&(msg_->msg), ptr, flags_); |
||||
if (nbytes >= 0) |
||||
return true; |
||||
if (zmq_errno () == EAGAIN) |
||||
return false; |
||||
throw error_t (); |
||||
} |
||||
|
||||
private: |
||||
void *ptr; |
||||
void *ctxptr; |
||||
|
||||
socket_t (const socket_t&) ZMQ_DELETED_FUNCTION; |
||||
void operator = (const socket_t&) ZMQ_DELETED_FUNCTION; |
||||
}; |
||||
|
||||
class monitor_t |
||||
{ |
||||
public: |
||||
monitor_t() : socketPtr(NULL) {} |
||||
virtual ~monitor_t() {} |
||||
|
||||
void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) |
||||
{ |
||||
int rc = zmq_socket_monitor(socket.ptr, addr_, events); |
||||
if (rc != 0) |
||||
throw error_t (); |
||||
|
||||
socketPtr = socket.ptr; |
||||
void *s = zmq_socket (socket.ctxptr, ZMQ_PAIR); |
||||
assert (s); |
||||
|
||||
rc = zmq_connect (s, addr_); |
||||
assert (rc == 0); |
||||
|
||||
on_monitor_started(); |
||||
|
||||
while (true) { |
||||
zmq_msg_t eventMsg; |
||||
zmq_msg_init (&eventMsg); |
||||
rc = zmq_recvmsg (s, &eventMsg, 0); |
||||
if (rc == -1 && zmq_errno() == ETERM) |
||||
break; |
||||
assert (rc != -1); |
||||
zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg)); |
||||
|
||||
#ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT |
||||
zmq_msg_t addrMsg; |
||||
zmq_msg_init (&addrMsg); |
||||
rc = zmq_recvmsg (s, &addrMsg, 0); |
||||
if (rc == -1 && zmq_errno() == ETERM) |
||||
break; |
||||
assert (rc != -1); |
||||
const char* str = static_cast<const char*>(zmq_msg_data (&addrMsg)); |
||||
std::string address(str, str + zmq_msg_size(&addrMsg)); |
||||
zmq_msg_close (&addrMsg); |
||||
#else |
||||
// Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types.
|
||||
std::string address = event->data.connected.addr; |
||||
#endif |
||||
|
||||
#ifdef ZMQ_EVENT_MONITOR_STOPPED |
||||
if (event->event == ZMQ_EVENT_MONITOR_STOPPED) |
||||
break; |
||||
#endif |
||||
|
||||
switch (event->event) { |
||||
case ZMQ_EVENT_CONNECTED: |
||||
on_event_connected(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_CONNECT_DELAYED: |
||||
on_event_connect_delayed(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_CONNECT_RETRIED: |
||||
on_event_connect_retried(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_LISTENING: |
||||
on_event_listening(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_BIND_FAILED: |
||||
on_event_bind_failed(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_ACCEPTED: |
||||
on_event_accepted(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_ACCEPT_FAILED: |
||||
on_event_accept_failed(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_CLOSED: |
||||
on_event_closed(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_CLOSE_FAILED: |
||||
on_event_close_failed(*event, address.c_str()); |
||||
break; |
||||
case ZMQ_EVENT_DISCONNECTED: |
||||
on_event_disconnected(*event, address.c_str()); |
||||
break; |
||||
default: |
||||
on_event_unknown(*event, address.c_str()); |
||||
break; |
||||
} |
||||
zmq_msg_close (&eventMsg); |
||||
} |
||||
zmq_close (s); |
||||
socketPtr = NULL; |
||||
} |
||||
|
||||
#ifdef ZMQ_EVENT_MONITOR_STOPPED |
||||
void abort() |
||||
{ |
||||
if (socketPtr) |
||||
zmq_socket_monitor(socketPtr, NULL, 0); |
||||
} |
||||
#endif |
||||
virtual void on_monitor_started() {} |
||||
virtual void on_event_connected(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_connect_delayed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_connect_retried(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_listening(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_bind_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_accepted(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_accept_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_closed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_close_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_disconnected(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
virtual void on_event_unknown(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } |
||||
private: |
||||
void* socketPtr; |
||||
}; |
||||
} |
||||
|
||||
#endif |
Loading…
Reference in new issue