c# pdf viewer open source : How to move pages around in pdf application control cloud windows azure winforms class World%20of%20Warcraft%20Programming%20(2nd%20Edition)34-part1832

Chapter 15
Taking Action with Secure Templates 299
Applying Action Buttons in Practice
At this point, all the fundamentals of the secure template system have been
covered. Now that you have a grasp of the various interactions among
attributes, suffixes, protected frames, and taint, you can put it into practice by
making changes to existing action buttons and creating new ones.
Modifying an Existing Frame
Thestandardbehaviorofa unit frame istotargetits unit when left-clicked.The
target frame also follows this convention, even though targeting your target
is not normally a useful action. You can reclaim some of that ‘‘click-space’’
by typing the following into WoWLua (if you’re over level 8 or so, substitute
whatever sort of bandage you’re currently using):
/run TargetFrame:SetAttribute(’item’, “Linen Bandage“)
/run TargetFrame:SetAttribute(’shift-type*’, 'item’)
/run TargetFrame:SetAttribute(’ctrl-type*’, 'item’)
/run TargetFrame:SetAttribute(’alt-type*’, 'item’)
The plain click is left as a
target
action because it is still useful to take
action on your current target if you have, say, a beneficial spell ready to cast
(your cursor shows the blue glow). But now, when you left-click your target’s
portrait with a modifier down, you’ll bandage your target. Right-clicking
your target still brings up his unit menu, with raid marker options and so
on. That’s because
TargetFrame
inherits from
SecureUnitButtonTemplate
,a
special subspecies of
SecureActionButtonTemplate
designed for unit frames
that sets the
*type2
attribute to a menu function.
NOTE
There is a slightly simpler, butless intuitive way to define bandaging as
the behavior on any modified click, and that is to set the 'type’ or '*type1’
attributes to 'item’ and the 'type*’ or 'type1' attributes to ‘target’. That
way, the target action is selected only when the click is actually unmodified.
If you have several changes to make to a frame, you may find it useful to
add a
SetFrameAttributes
function like this one:
function SetFrameAttributes(self, attributes)
for name, value in pairs(attributes) do
if type(name) == 'string’ then
self:SetAttribute(name, value)
end
end
end
TargetFrame.SetAttributes = SetFrameAttributes
How to move pages around in pdf - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
pdf change page order online; how to move pages within a pdf
How to move pages around in pdf - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
how to reorder pdf pages; rearrange pages in pdf
300
Part III
Advanced Addon Techniques
That enables you to set multiple attributes with an understandable list
format:
TargetFrame:SetAttributes{
unit = 'target’, -- this was also preset by the frame definition
type = 'target’, -- so was this
[’*type2’] = 'menu’, -- and this
item = 'Linen Bandage’,
[’shift-type*’] = 'item’,
[’ctrl-type*’] = 'item’,
[’alt-type*’] = 'item’
}
This approach generates a throw-away table; it’s suitable for one-time or
otherwise infrequent setup, but should be avoided for frequent changes.
AComplex Action Button
The last example for this chapter builds a single button from scratch that
can cast one of three spells—depending on what modifier keys are held—on
one of three friendly targets, depending on which mouse button was used
and whether the target was friendly. The example uses priest abilities; feel
free to adjust the attributes to your liking and experiment with different
configurations.
This mini-addon addsan action button to thelower-leftregion ofthe screen.
Click itto cast the spell Greater Heal; Shift+click forPower Word: Shield; and
Ctrl+click for Renew. Moreover, it offers some more options on who to heal
or protect: while it usually casts on your target, right-clicking casts on your
focus, and clicking while you have an enemy targeted automatically casts on
yourself, without changing your target.
Here’s what to do:
1. Create a directory called
QuickCasterButton
in your
Interface\AddOns
directory.
2. Create a file inside this new directory named
QuickCasterButton.toc
,
containing the following lines:
## Interface: 30300
## Title: QuickCasterButton
## Notes: Casts a variety of helpful spells on different targets
QuickCasterButton.xml
3. Create anotherfilein the samedirectory named
QuickCasterButton.xml
,
and open it in a text editor.
C# WPF PDF Viewer SDK to view PDF document in C#.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Extract, Copy PDF pages extract, copy, paste, C#.NET rotate PDF pages, C#.NET Pan around the PDF document
how to rearrange pages in pdf document; rearrange pdf pages in reader
VB.NET PDF - View PDF with WPF PDF Viewer for VB.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Copy, Paste PDF pages extract, copy, paste, C#.NET rotate PDF pages, C#.NET Pan around the PDF document.
reorder pages pdf file; move pdf pages online
Chapter 15
Taking Action with Secure Templates 301
4. Enter the beginning tags for the UI definition (required for any addon
XML file) and the button frame:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
This example illustrates one of the most common uses of
SecureAction
ButtonTemplate
, which is to marry it to
ActionButtonTemplate
via
multiple inheritance; this creates a button that has the ‘‘look and
feel’’ of the stock action buttons pre-built. The commonly used
ActionBarButtonTemplate
begins with these two templates, and then
adds functions to keep the buttons’ appearance up-to-date with what
they do. In this case, using the templates directly keeps things simple.
5. Enterthe anchor code to place the button in the lower left:
<Anchors>
<Anchor point=“BOTTOMLEFT“ relativeTo=“UIParent“>
<Offset x=“180“ y=“280“ />
</Anchor>
</Anchors>
6. Open the
<Attributes>
tag and define the button as a spell button:
<Attributes>
<Attribute name=“type“ value=“spell“ />
7. Define the default spell for the button, as well as spells for Shift+click
and Ctrl+click:
<Attribute name=“spell“ value=“Greater Heal“ />
<Attribute name=“shift-spell*“ value=“Power Word: Shield“ />
<Attribute name=“ctrl-spell*“ value=“Renew“ />
8. Now define the units for the button to affect.
nil
is usually the same as
“target“
,but for
harmbutton
to work in the next step, an actual target
needs to be defined:
<Attribute name=“unit“ value=“target“ />
<Attribute name=“*unit2“ value=“focus“ />
Avery powerful technique is to vary one attribute according to the mod-
ifier and another one according to the button. In this example, the mouse
button clicked specifies the unit to cast on, and the modifiers choose the
spell to cast. In this way, a whole grid of unit-spell combinations can be
created with comparatively few frame attributes.
C# HTML5 PDF Viewer SDK to view PDF document online in C#.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Extract, Copy and Users can view PDF document in single page or continue pages. Pan around the document.
reorder pdf pages in preview; how to move pages in pdf reader
VB.NET PDF- View PDF Online with VB.NET HTML5 PDF Viewer
Page: Replace PDF Pages. Page: Move Page Position. Page: Copy, Paste PDF Users can view PDF document in single page or continue pages. Pan around the document.
how to rearrange pages in pdf using reader; how to move pages in pdf acrobat
302
Part III
Advanced Addon Techniques
9. Define the name of the button you want used when the target is an
enemy, and then define the unit to use when that button is clicked:
<Attribute name=“harmbutton“ value=“self“ />
<Attribute name=“*unit-self“ value=“player“ />
10. Close the
Attributes
section and start a
Scripts
section so you can do
needed setup on the button:
</Attributes>
<Scripts>
11. Buttons,bydefault,areonlyregisteredforleft-clickswhenthey’recreated,
so you need to fix that if you want to right-click the button:
<OnLoad>
self:RegisterForClicks(“AnyUp“)
12. Because there is no action slotto which thebutton’s icon will be updated,
you need to set a static texture for its appearance:
_G[self:GetName()..“Icon“]:SetTexture(i
[[Interface\Icons\Spell_Holy_ImprovedResistanceAuras]])
13. The last step is close out the open tags and save the file:
</OnLoad>
</Scripts>
</Button>
</Ui>
Figure 15-2 shows the fully functional QuickCasterButton that you can use
to cast spells.
Figure 15-2: The functional QuickCasterButton
Understanding Taint and Working Safely Around
Secure Code
The secure code system depends on its function being very thorough. Any
attempt by insecure code to interfere with a secure action will cause the
secure action to fail or further spread the taint. Addons that approach or
manipulate secure buttons or other UI elements depend on a very close
association of secure and contagiously insecure code, and it’s easy to end up
gettingthe influenceofinsecure code whereit doesn’tbelong,causing familiar
elements of the UI to break in new and inventive ways.
Chapter 15
Taking Action with Secure Templates 303
If you’regetting errormessagesabout actions onlypermitted to the Blizzard
UI, or ‘‘Interface action failed because of an AddOn’’ messages are cropping
up in your chat log, it’s important to understand how taint works and
spreads if you’re going to try and fix these issues. If you’re not familiar
with the protection violation error message, you can reproduce it by running
CastSpellByName(“Attack“)
using WoWLua, producing the error shown in
Figure 15-3.
Figure 15-3: Protected function error
Notice that the message references WowLua. When WoW loads a Lua file,
every value created by the addon (functions and other globals) is marked as
such.In thiscase,the codein WowLuathatexecutes your commandsis known
to be tainted. When it tries to access
CastSpellByName
,the WoW game code
refuses to comply. Instead, it throws an error with the name of the addon that
caused the taint.
NOTE
The CastSpellByName function itself is notblocked for tainted code.
Rather, it is the actual casting of spells that is blocked. For example, if you try to
cast a spell thatyou do nothave, CastSpellByName will fail silently. Additionally,
you can safely use CastSpellByName to open tradeskills.
Enabling Taint Logging
Sometimes the way taint spreads can seem mysterious because of the various
and complex interactions of different parts of the UI code (addons, macros,
and built-in code). First, run the following command to turn on taint logging:
/console taintLog 1
The taint log shows you a time line of when taint occurs and how the taint
blocks an action. Level 1 only shows taint events if they lead up to a blocked
action. Level 2 records every single occurrence of taint including those that
are completely innocuous (and indeed inevitable). To turn off taint logging,
pass it a zero (0). The following is an example taint log attempting to run
CastSpellByName
:
5/28 15:01:43.302
An action was blocked because of taint from WowLua -
CastSpellByName()
5/28 15:01:43.302
WowLua:1
5/28 15:01:43.302
pcall()
5/28 15:01:43.302
Interface\AddOns\WowLua\WowLua.lua:217 RunScript()
5/28 15:01:43.302
Interface\AddOns\WowLua\WowLua.lua:600 Button_Run()
304
Part III
Advanced Addon Techniques
5/28 15:01:43.302
Interface\AddOns\WowLua\WowLua.lua:276 Button_OnClick()
5/28 15:01:43.302
WowLuaButton_Run:OnClick()
The first line shows the actual event, the call to
CastSpellByName
that
generated the error message shown in Figure 15-3. The other indented lines
showa stacktraceleadingupto theeventto helpyou track down the source of
any problems. Upcoming sections take a closer look at some other taint logs.
Taintlogsaresavedas
taint.log
inthe
Logs
folderofyourWoWinstallation.
Like chat logs, they are only written to disk when the game exits or the UI
is reloaded. To see the taint log for your current session, you must manually
reload the UI and then open the file quickly because WoW sometimes likes to
empty it during gameplay.
Execution Taint
There are two ways to spread taint. One is temporary and only exists when
aparticular chain of code is executing. The other is more persistent and the
cause of many headaches. The first is what you experienced in the preceding
example. The taint travels up the call stack from one function to another. For
example, enter the following command in the chat box (not WowLua):
/run WowLua:ProcessLine(“CastSpellByName(’Attack’)“)
WowLua works by reading each lineof textyouenter andthen running itas
Lua code.With the precedingcommand,youare manuallycallingthefunction
thatdoes this,tellingittoattempttocast the
Attack
spell.Theimportant point
to note is that the game blames WowLua for the infraction, not the macro
command. Figure 15-4 illustrates the taint path and the state of the blame.
Error
/run ...
Tainted as a
macro script
Tainted as
WowLua
Tainted as
WowLua
ProcessLine
CastSpellByName
Figure 15-4: Execution taint path
The taint begins when the macro processes the
/run
command (remember
that macros fall under the same restrictions as addons). At this point, the taint
is attributed to the macro command. If you were to call
CastSpellByName
directly, the error would mention ‘‘A macro script.’’ Instead, you call
Chapter 15
Taking Action with Secure Templates 305
WowLua:ProcessLine
,which now receives blame for the taint. The function
executes the code sent, which in turn tries to call
CastSpellByName
.You can
also follow this path through the taint log.
5/27 22:06:26.890
An action was blocked because of taint from WowLua -
CastSpellByName()
5/27 22:06:26.890
CastSpellByName(’Attack’):1
5/27 22:06:26.890
pcall()
5/27 22:06:26.890
Interface\AddOns\WowLua\WowLua.lua:177 ProcessLine()
5/27 22:06:26.890
WowLua:ProcessLine(“CastSpellByName(’Attack’)“):1
5/27 22:06:26.890
RunScript()
5/27 22:06:26.890
Interface\FrameXML\ChatFrame.lua:1826 ?()
5/27 22:06:26.890
Interface\FrameXML\ChatFrame.lua:3332 ChatEdit_ParseText()
5/27 22:06:26.890
Interface\FrameXML\ChatFrame.lua:3052 ChatEdit_SendText()
5/27 22:06:26.890
Interface\FrameXML\ChatFrame.lua:3073
i
ChatEdit_OnEnterPressed()
5/27 22:06:26.890
ChatFrameEditBox:OnEnterPressed()
Working from bottom to top, the log begins when you press Enter in the
chat box. Next, it works its way up to
RunScript()
,which applies the first
taint in the sequence, blaming it on ‘‘A macro script.’’ The macro script then
calls
WowLua:ProcessLine
,which receives blame for the taint.
Execution taint is transientbecause none ofthe functions involvedis perma-
nently affected in any way. The default UI uses
CastSpellByName
for certain
cases of spell casting. Even after erroneously calling, as shown here, WoW
still behaves correctly. The taint itself goes away as soon as the original
/run
command finishes.
Variable Taint
Less forgiving than execution taint, variable taint can permanently (for the
session) affect certain aspects of the built-in code. Variable taint is almost
an extension of execution taint; they both play off of each other, and even
overlap in some ways. Any tainted execution path has the potential to cause
variable taint.
Recall from Part I the ideas of values and references. World of Warcraft
has modified its Lua engine to store a taint flag with every value in the Lua
environment that identifies if the value is tainted, and the addon that caused
the taint. This is how the preceding example determined the blame. Variable
taint is caused when a tainted code path creates a new value orreference. Any
time your code makes a new global variable, function, table, and so on, that
new value is now tainted. Where you begin to run into trouble is when you
start modifying variables used by the default UI. Here’s an example in action.
Type the following line into WowLua:
/run NUM_ACTIONBAR_BUTTONS = NUM_ACTIONBAR_BUTTONS
306
Part III
Advanced Addon Techniques
Now try to use any ability on your action bar and you will see an
addon blocked messages similar to the one you saw before. The func-
tion
ActionButton_CalculateAction
in
FrameXML\ActionButton.lua
uses this
variable to determine which action slot to activate when youpress the button.
As soon as the code accesses the tainted value, the execution path becomes
infected with execution taint. This causes an error when the code attempts to
run the
UseAction
function. The only way to ‘‘cure’’ this condition is to reload
the UI.
NOTE
The tainterror from setting NUM_ACTIONBAR_BUTTONS will probably not
appearifyou are using a custom bar mod. The default UI’s action buttons calculate
which action slot to use based on NUM_ACTIONBAR_BUTTONS,the button’s ID (set
via the id XML attribute), and some other pieces of data. Addons’ action buttons
usually do notuse IDs, so ActionButton_CalculateAction never runs into the
tainted value.
NUM_ACTIONBAR_BUTTONS
could be set to some number directly, but it is
important to realize that the taint is caused simply by the act of assignment
itself. The fact that the value came froma secure variable does not exemptyou
from taint.
Another chart is helpful to picture the interactions. Figure 15-5 shows the
series of events that occurs when you click the action button after tainting
NUM_ACTIONBAR_BUTTONS
.Again, note that it’s the simple action of reading the
tainted variable that causes the execution path to be tainted.
Error
OnClick
Secure
Got WowLua’s taint by reading
NUM_ACTIONBAR_BUTTONS
Tainted as
WowLua
ActionButton_CalculateAction
UseAction
Figure 15-5: Code path tainted by a modified variable
Take a look at the resulting taint log:
5/28 15:27:23.454
Global variable NUM_ACTIONBAR_BUTTONS tainted by WowL
ua -
WowLua:1
5/28 15:27:23.454
pcall()
5/28 15:27:23.454
Interface\AddOns\WowLua\WowLua.lua:217 RunScript()
Chapter 15
Taking Action with Secure Templates 307
5/28 15:27:23.454
Interface\AddOns\WowLua\WowLua.lua:600 Button_Run()
5/28 15:27:23.454
Interface\AddOns\WowLua\WowLua.lua:276 Button_OnClick()
5/28 15:27:23.454
WowLuaButton_Run:OnClick()
5/28 15:27:23.454
Execution tainted by WowLua while reading
i
NUM_ACTIONBAR_BUTTONS - Interface\FrameXML\ActionButton.lua:139
i
ActionButton_CalculateAction()
5/28 15:27:23.454
Interface\FrameXML\SecureTemplates.lua:253 handler()
5/28 15:27:23.454
Interface\FrameXML\SecureTemplates.lua:460
5/28 15:27:23.454
An action was blocked because of taint from WowLua -
UseAction()
5/28 15:27:23.454
Interface\FrameXML\SecureTemplates.lua:258 handler()
5/28 15:27:23.454
Interface\FrameXML\SecureTemplates.lua:460
The first ‘‘Global variable tainted’’ event shows the taint being applied
to
NUM_ACTIONBAR_BUTTONS
. The next ‘‘Execution tainted’’ event, which
was originally triggered by the button’s
OnClick
handler, occurs during
ActionButton_CalculateAction
,as anticipated. Finally,
UseAction
is blocked
from executing because the code path was tainted.
NOTE
This particular taintlog illustrates a particulardistinction between taint
log levels 1 and 2. Notice that all three events share the same time stamp. At level
1, WoW waits until taint actually causes a blocked action before reporting it. When
the action blocked message is generated, WoW goes back through its tainthistory
and retrieves the first two events, and all three events are then outputto the log. If
you were to click the action button a second time, all three events would be
logged again, even though the first one happened some time ago.
On the other hand, level 2 records each eventexactly as it happens. Every global
variable set by an addon generates a tainted message. Every time Blizzard code
reads an insecure variable, itgenerates an execution tainted message. This makes
level 2 extremely verbose, but itcan also be more telling for a given issue.
Creeping Taint
One of the problems you may come across when dealing with taint issues
is the gradual spreading of variable taint. Say you have a tainted variable
used by the default UI (such as the earlier
NUM_ACTIONBAR_BUTTONS
example).
As explained, as soon as the built-in code accesses this variable, it becomes
tainted. Well, what happens when the tainted execution path then modifies
some other variable? That variable is now afflicted with the same taint that is
affecting the current execution path.
This process can happen repeatedly, often unnoticed,with each new tainted
variable potentially causing even more taint. In this way, your addon can taint
entire subsystems of the UI without modifying more than a single variable.
Not only can it spread far and wide, but the speed of the spreading can be
misleading. Some code in the default UI runs based on events that are not
308
Part III
Advanced Addon Techniques
exactly frequent. One piece of misplaced taint may not cause any problems
until you join a raid group or travel to another continent, for example.
These situations are where the taint logs can really shine. When you receive
an‘‘action blocked’’messageduringdevelopment,simplyturn on taintlogging
andyoucantrackdowntheproblems.Level 2is especiallyhelpfulin acase like
this because it allows youto see exactly when each variable becomes tainted.
Summary
This chapter covered a lot of ground. By now, you should be acquainted with:
The basic intent of the secure code system, which is to protect the game
from automation while still enabling customization.
The concept of protected frames and which of their characteristics are
restricted fromchanges during combat.
Howframeattributesallowsecurecodetoreceivecontrol messagessafely
from addon code.
Howtaintcan propagate from addon codetoBlizzardcode and cause the
UI to fail, and how to identify and prevent this.
The secure template system uses a wide assortment of specific features—
taint,protectedfunctions andframes,attributes,andso on—to achieve amuch
larger goal. It needs to protect the game against too much automation and, at
the same time, allow addons to alter the way you interact in combat. There is
still a lot to cover, but once you understand the basics laid out here, the rest
will flow much more freely.
Documents you may be interested
Documents you may be interested