Import APOS
No files matched your search
@@ -1,6 +1,16 @@
|
||||
# APOS property files
|
||||
*.properties
|
||||
|
||||
# APOS scripts
|
||||
Scripts/*
|
||||
|
||||
# Compiled class file
|
||||
bin/
|
||||
*.class
|
||||
|
||||
# Cached content files
|
||||
Content/*
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
@@ -19,5 +29,8 @@
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# Exception
|
||||
!lib/rsclassic.jar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
@@ -0,0 +1,338 @@
|
||||
-------------------
|
||||
Version 2.4.1
|
||||
|
||||
Usability improvements to auth system
|
||||
|
||||
-------------------
|
||||
Version 2.4
|
||||
|
||||
<lots of data access stuff, too long to list, check the docs>
|
||||
void addFriend(String name)
|
||||
void removeFriend(String name)
|
||||
void addIgnore(String name)
|
||||
void removeIgnore(String name)
|
||||
int getFriendCount()
|
||||
String getFriendName(int i)
|
||||
boolean isFriend(String name)
|
||||
int getIgnoredCount()
|
||||
String getIgnoredName(int i)
|
||||
boolean isIgnored(String name)
|
||||
void useSlotOnObject(int slot, int x, int y)
|
||||
(primarily for legacy compatibility with other bots)
|
||||
boolean isAutoLogin()
|
||||
void setSkipLines(boolean flag)
|
||||
boolean isSkipLines()
|
||||
void setRendering(boolean flag)
|
||||
boolean isRendering()
|
||||
void setPaintOverlay(boolean flag)
|
||||
boolean isPaintOverlay()
|
||||
|
||||
Many new included scripts
|
||||
The return of FOCR/Joker
|
||||
(Num3l is still default, but x86-32 FOCR may be more accurate because of
|
||||
rotation routines not present in Num3l).
|
||||
Smoother and faster CAPTCHA input (again)
|
||||
Unidentified herbs have the herb name in brackets
|
||||
Font fix for Linux (set bot.properties font= to Arial)
|
||||
javax.script support (only JavaScript atm)
|
||||
Exact fatigue/XP
|
||||
Made loading faster by storing content locally. The first time you start
|
||||
the bot it won't be any faster because it has to download the files first.
|
||||
Improved drawImage
|
||||
getPlayerName (spaces)
|
||||
getPlayerByName (spaces)
|
||||
Script reloading now grabs updated code
|
||||
New icon
|
||||
|
||||
-------------------
|
||||
Version 2.3
|
||||
|
||||
Console is now internal to the main frame
|
||||
Improved performance when writing text to the console
|
||||
Slight UI improvements
|
||||
Num3l is now the default OCR
|
||||
The OCR type is now saved
|
||||
It now randomly picks world 2 or 3 on start-up instead of deafulting to
|
||||
world 2.
|
||||
Smoother and faster CAPTCHA input
|
||||
|
||||
-------------------
|
||||
Version 2.2
|
||||
|
||||
Checkboxes
|
||||
getObjectById fixed to retain backwards compatibility
|
||||
Fixed the display of buttons on X11 systems
|
||||
|
||||
-------------------
|
||||
Version 2.1
|
||||
|
||||
New features
|
||||
void takeScreenshot(String file)
|
||||
void followPlayer(int server_index)
|
||||
void useItemWithPlayer(int local_index, int slot)
|
||||
void drawCircleFill(int x, int y, int radius, int colour, int trans)
|
||||
void setPixel(int x, int y, int colour)
|
||||
void drawImage(Image image, int start_x, int start_y)
|
||||
|
||||
Massive code clean up.
|
||||
System tray icon.
|
||||
Script selection UI.
|
||||
Improved built-in scripts.
|
||||
Improved logo (thanks blood).
|
||||
Fixed the bug on the account selection frame where the drop-down list
|
||||
would be too small.
|
||||
Icon (thanks Momentum Design Lab, it's part of their Matte set:
|
||||
http://momentumdesignlab.com/about/downloads/).
|
||||
|
||||
-------------------
|
||||
Version 2.0
|
||||
|
||||
New included scripts
|
||||
F3 - Certer
|
||||
F6 - Catherby
|
||||
F7 - Thieving
|
||||
F8 - Magic
|
||||
|
||||
New features
|
||||
boolean canCastSpell(int spell) (and many other data-related things,
|
||||
see the docs)
|
||||
void disableKeys()
|
||||
void onKeyPress(int keycode)
|
||||
void onServerMessage(String str)
|
||||
void onTradeRequest(String name)
|
||||
void onChatMessage(String msg, String name, boolean mod, boolean admin)
|
||||
void onPrivateMessage(String msg, String name, boolean mod, boolean admin)
|
||||
void sendPrivateMessage(String msg, String name)
|
||||
Note: you can send public chat messages using
|
||||
void setTypeLine(String str)
|
||||
and boolean next().
|
||||
This method has been present since 1.4.
|
||||
(just moved these)
|
||||
void declineTrade()
|
||||
int getTheirTradedItemCount()
|
||||
|
||||
Modified the auth screen slightly.
|
||||
Camera height is no longer modified when under roofs.
|
||||
Fog of war is now incremented/decremented with the camera height.
|
||||
|
||||
The camera can now be controlled with the following keys:
|
||||
Page Up moves it away from your player northwards.
|
||||
Page Down moves it away from your player southwards.
|
||||
Home moves it away from your player eastwards.
|
||||
End moves it away from your player westwards.
|
||||
Up zooms out, as always.
|
||||
Down zooms in, as always. Don't zoom in too far or the game crashes.
|
||||
Escape resets it.
|
||||
|
||||
Removed the random minimap/camera rotation, just because.
|
||||
|
||||
-------------------
|
||||
Version 1.9
|
||||
|
||||
New features
|
||||
boolean isSkilling()
|
||||
boolean isWalking()
|
||||
boolean isPlayerWalking(int local_index)
|
||||
int getPlayerDirection(int local_index)
|
||||
void paint() (new listener thing!)
|
||||
void drawHLine(int x, int y, int length, int colour)
|
||||
void drawVLine(int x, int y, int length, int colour)
|
||||
void drawString(String str, int x, int y, int size, int colour)
|
||||
void drawBoxFill(int x, int y, int width, int height, int colour)
|
||||
void drawBoxOutline(int x, int y, int width, int height, int colour)
|
||||
void drawBoxAlphaFill(int x, int y, int width, int height, int trans,
|
||||
int colour)
|
||||
void writeLine(String str)
|
||||
|
||||
Fixed
|
||||
isItemAt(int id, int x, int y)
|
||||
getPlayerByName(String name)
|
||||
You can now toggle the paint while a script is running
|
||||
|
||||
Cleaned up lots of stuff
|
||||
|
||||
-------------------
|
||||
Version 1.8
|
||||
|
||||
Removed features
|
||||
The internal cross platform OCR because nobody used it.
|
||||
|
||||
New features
|
||||
void useItemOnObject(int item_id, int object_x, int object_y)
|
||||
[why was this removed?]
|
||||
void sendTradeRequest(int pid)
|
||||
The auth screen from <1.5 [why was this removed?]
|
||||
PaintListener
|
||||
Graphics toggle
|
||||
Screenshot thing
|
||||
|
||||
Fixes
|
||||
Splash screen rewrite to fix null bug
|
||||
int bankCount(int id)
|
||||
boolean isReachable(int x, int y) [thanks CamHart]
|
||||
Modified a fresh client, fixed the UID, fixed the logout timer and
|
||||
re-added all the hooks
|
||||
to fix RLN's logout bug
|
||||
--------------------
|
||||
Version 1.7
|
||||
|
||||
New features
|
||||
void enablePrayer(int id)
|
||||
void disablePrayer(int id)
|
||||
boolean isPrayerEnabled(int id)
|
||||
int getShopItemById(int id)
|
||||
boolean isShopOpen()
|
||||
int getShopItemAmount(int slot)
|
||||
void buyShopItem(int slot, int amount)
|
||||
void sellShopItem(int slot, int amount)
|
||||
void closeShop()
|
||||
boolean isInTradeOffer()
|
||||
boolean isInTradeConfirm()
|
||||
void offerItemTrade(int slot, int amount)
|
||||
boolean hasOtherTraded(int item_id, int amount)
|
||||
int getOurTradedItemCount()
|
||||
void acceptTrade()
|
||||
void confirmTrade()
|
||||
void useItemOnWallObject(int slot, int x, int y)
|
||||
Parameter parsing
|
||||
|
||||
Fixes
|
||||
Id Debugger
|
||||
--------------------
|
||||
Version 1.6
|
||||
|
||||
Updated to the latest client
|
||||
|
||||
New Features
|
||||
Id Debugger
|
||||
--------------------
|
||||
Version 1.5
|
||||
|
||||
Updated to the latest client (?)
|
||||
--------------------
|
||||
Version 1.4
|
||||
|
||||
New Features
|
||||
void setTypeLine("text here") - text to be typed onto the client
|
||||
boolean next() - will type next character of type line and hit enter for
|
||||
you at the end - returns false until finished typing line
|
||||
F2 = Autofighter (nade's script)
|
||||
F3 = Draynor Certer/Uncert (mofo's script)
|
||||
F4 = Stouts (buy)
|
||||
F5 = Stouts (train)
|
||||
F12 = Reload scripts
|
||||
--------------------
|
||||
Version 1.25
|
||||
|
||||
mad bug fixes.
|
||||
--------------------
|
||||
Version 1.24
|
||||
|
||||
New Features
|
||||
void getPlayerByPid(int pid)
|
||||
|
||||
Fixes
|
||||
getNpcByIdNotTalk(int... id)
|
||||
void castOnItem(spellID, pos)
|
||||
boolean isWearingItem(id)
|
||||
void wearItem(int pos)
|
||||
--------------------
|
||||
Version 1.24
|
||||
|
||||
New Features
|
||||
void castOnItem(spellID, pos)
|
||||
boolean isWearingItem(id)
|
||||
void wearItem(int pos)
|
||||
void setTrickMode(boolean on)
|
||||
|
||||
Fixes
|
||||
fixed all the issues with NPCs
|
||||
fixed all the issues with PVP
|
||||
loads of other bug fixes/trap removals
|
||||
--------------------
|
||||
Version 1.2
|
||||
|
||||
New Features
|
||||
Now shows coords and pid in your options menu
|
||||
void magePlayer(int playeridx, int spellID)
|
||||
void attackPlayer(int playeridx)
|
||||
int[] getPlayerByName(String name) - finds a players index, x, y
|
||||
int countPlayers() - returns the amount of players in
|
||||
the area (including yourself)
|
||||
void castOnSelf(spellID)
|
||||
void castOnGroundItem(spellID, x, y, groundIndex)
|
||||
|
||||
Fixes
|
||||
Upgrade to the internal OCR
|
||||
Various bug fixes.
|
||||
--------------------
|
||||
Version 1.18
|
||||
|
||||
New Features
|
||||
void mageNpc(int spellID, int npcIDx)
|
||||
(more were added, just not 100% sure)
|
||||
(we will soon have fully commented java docs for you
|
||||
script developers to look at)
|
||||
|
||||
Fixes
|
||||
loads of bug fixes
|
||||
if you still have some bugs let us know, we want to get all the
|
||||
bugs out of the
|
||||
way before we add everything else and jump in to mass scripting mode!
|
||||
--------------------
|
||||
Version 1.17
|
||||
|
||||
New Features
|
||||
void useItemOnGroundItem(int itemID, int groundItemID)
|
||||
void useItemOnGroundItem(int pos, int x, int y, int groundItemIndex)
|
||||
boolean isItemAt(int x, int y, int id)
|
||||
boolean isObjectAt(int x, iny y)
|
||||
void pickupItem(int id, int x, int y)
|
||||
void pickupItem(int x, int y)
|
||||
void pickupItemById(int... id)
|
||||
int[] getItemById(int... id)
|
||||
|
||||
Client features added:
|
||||
Right click options -
|
||||
right click player -> view pid
|
||||
right click ground item -> view id
|
||||
right click object -> view id
|
||||
right click wall object -> veiw id
|
||||
right click inventory item -> view id
|
||||
shows pid in options menu
|
||||
|
||||
Fixes
|
||||
int[] getNpcInRadius(int id, int startX, int startY, int radius)
|
||||
int[] getNpcInExtendedRadius(int id, int startX, int startY, int xd, int yd)
|
||||
int[] getNpcById(int... id)
|
||||
int[] getNpcByIdNotTalk(int... id)
|
||||
--------------------
|
||||
Version 1.16
|
||||
|
||||
New Features
|
||||
void useItemOnObject(int itemId, int objectId)
|
||||
void useItemOnObject(int itemIdx, int x, int y)
|
||||
void useItemWithItem(int idx1, int idx2)
|
||||
int[] BANKERS
|
||||
int[] BONES
|
||||
String[] SPELLS
|
||||
|
||||
Fixes
|
||||
getHpPercent() fixed
|
||||
--------------------
|
||||
Version 1.15
|
||||
|
||||
New Features
|
||||
mageNpc(int npcIndex, int spellID)
|
||||
dropItem(int idx)
|
||||
Stout buyer/trainer (will be posted in script section)
|
||||
|
||||
Fixes
|
||||
Banking fixed
|
||||
atObject and atObject2 fixed
|
||||
atWallObject and atWallObject2 fixed
|
||||
talking to npcs is fixed
|
||||
applet sizing issue fixed
|
||||
current/max level bug fixed
|
||||
getHpPercent() fixed
|
||||
getItemIndex renamed to getInventoryIndex
|
||||
@@ -1,661 +1,2 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
APOS is free to use and modify/redistribute with source code, but not
|
||||
to sell, or distribute without accompanying source code.
|
||||
@@ -0,0 +1,4 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path: lib/rsclassic.jar
|
||||
Main-Class: ClientInit
|
||||
|
||||
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 169 KiB |
@@ -0,0 +1,38 @@
|
||||
APOS for RSC#234
|
||||
================
|
||||
|
||||
APOS was developed by RLN/nade/mofo (2009-2011).
|
||||
|
||||
APOS was then developed by Stormy from 2012 until 2016.
|
||||
|
||||
This source code was originally released by Stormy in 2016.
|
||||
|
||||
See also the APOS-Scripts repository, which includes some
|
||||
essential components like PathWalker.
|
||||
|
||||
Keyboard stuff
|
||||
--------------
|
||||
|
||||
PageUp - Moves the camera away from your player northwards.
|
||||
PageDown - Moves the camera away from your player southwards.
|
||||
Home - Moves the camera away from your player eastwards.
|
||||
End - Moves the camera away from your player westwards.
|
||||
Up - Zooms the camera in.
|
||||
Down - Zooms the camera out.
|
||||
Escape - Resets the camera.
|
||||
F12 - Takes a screenshot, saves it to the Screenshots directory.
|
||||
|
||||
Using custom fonts
|
||||
------------------
|
||||
|
||||
Edit bot.properties and add the following line:
|
||||
|
||||
```
|
||||
font=Comic Neue
|
||||
```
|
||||
|
||||
with "Comic Neue" replaced with the font you want to use. Unless you
|
||||
want to use Comic Neue.
|
||||
|
||||
RSC by default tries to use Helvetica/Arial, but can't if you don't have it
|
||||
installed.
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="APOS" default="run">
|
||||
<target name="compile">
|
||||
<mkdir dir="bin" />
|
||||
<javac srcdir="src" destdir="bin" debug="true"
|
||||
source="1.7" target="1.7"
|
||||
classpath="lib/rsclassic.jar" />
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<jar basedir="bin" destfile="bot.jar"
|
||||
manifest="MANIFEST.MF" />
|
||||
</target>
|
||||
<target name="run" depends="jar">
|
||||
<java classpath="bot.jar:lib/rsclassic.jar"
|
||||
fork="true" classname="ClientInit" dir="." />
|
||||
</target>
|
||||
<target name="clean">
|
||||
<delete dir="bin" />
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,4 @@
|
||||
@ECHO OFF
|
||||
javac -Xlint:deprecation -cp bot.jar;lib/rsclassic.jar Scripts/*.java
|
||||
echo Compilation completed.
|
||||
pause
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>All Classes</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="bar">All Classes</h1>
|
||||
<div class="indexContainer">
|
||||
<ul>
|
||||
<li><a href="Script.html" title="class in <Unnamed>" target="classFrame">Script</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>All Classes</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="bar">All Classes</h1>
|
||||
<div class="indexContainer">
|
||||
<ul>
|
||||
<li><a href="Script.html" title="class in <Unnamed>">Script</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>Constant Field Values</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript"><!--
|
||||
if (location.href.indexOf('is-external=true') == -1) {
|
||||
parent.document.title="Constant Field Values";
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
<noscript>
|
||||
<div>JavaScript is disabled on your browser.</div>
|
||||
</noscript>
|
||||
<div class="header">
|
||||
<h1 title="Constant Field Values" class="title">Constant Field Values</h1>
|
||||
<h2 title="Contents">Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#unnamed_package"><Unnamed></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="constantValuesContainer"><a name="unnamed_package">
|
||||
<!-- -->
|
||||
</a>
|
||||
<h2 title="<Unnamed>"><Unnamed>.*</h2>
|
||||
<ul class="blockList">
|
||||
<li class="blockList">
|
||||
<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
|
||||
<caption><span><a href="Script.html" title="class in <Unnamed>">Script</a></span><span class="tabEnd"> </span></caption>
|
||||
<tr>
|
||||
<th class="colFirst" scope="col">Modifier and Type</th>
|
||||
<th scope="col">Constant Field</th>
|
||||
<th class="colLast" scope="col">Value</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a name="Script.DIR_EAST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_EAST">DIR_EAST</a></code></td>
|
||||
<td class="colLast"><code>6</code></td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colFirst"><a name="Script.DIR_NORTH">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_NORTH">DIR_NORTH</a></code></td>
|
||||
<td class="colLast"><code>0</code></td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a name="Script.DIR_NORTHEAST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_NORTHEAST">DIR_NORTHEAST</a></code></td>
|
||||
<td class="colLast"><code>7</code></td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colFirst"><a name="Script.DIR_NORTHWEST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_NORTHWEST">DIR_NORTHWEST</a></code></td>
|
||||
<td class="colLast"><code>1</code></td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a name="Script.DIR_SOUTH">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_SOUTH">DIR_SOUTH</a></code></td>
|
||||
<td class="colLast"><code>4</code></td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colFirst"><a name="Script.DIR_SOUTHEAST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_SOUTHEAST">DIR_SOUTHEAST</a></code></td>
|
||||
<td class="colLast"><code>5</code></td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a name="Script.DIR_SOUTHWEST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_SOUTHWEST">DIR_SOUTHWEST</a></code></td>
|
||||
<td class="colLast"><code>3</code></td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colFirst"><a name="Script.DIR_WEST">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#DIR_WEST">DIR_WEST</a></code></td>
|
||||
<td class="colLast"><code>2</code></td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a name="Script.MAX_INV_SIZE">
|
||||
<!-- -->
|
||||
</a><code>public static final int</code></td>
|
||||
<td><code><a href="Script.html#MAX_INV_SIZE">MAX_INV_SIZE</a></code></td>
|
||||
<td class="colLast"><code>30</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>Deprecated List</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript"><!--
|
||||
if (location.href.indexOf('is-external=true') == -1) {
|
||||
parent.document.title="Deprecated List";
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
<noscript>
|
||||
<div>JavaScript is disabled on your browser.</div>
|
||||
</noscript>
|
||||
<div class="header">
|
||||
<h1 title="Deprecated API" class="title">Deprecated API</h1>
|
||||
<h2 title="Contents">Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#method">Deprecated Methods</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="contentContainer"><a name="method">
|
||||
<!-- -->
|
||||
</a>
|
||||
<ul class="blockList">
|
||||
<li class="blockList">
|
||||
<table border="0" cellpadding="3" cellspacing="0" summary="Deprecated Methods table, listing deprecated methods, and an explanation">
|
||||
<caption><span>Deprecated Methods</span><span class="tabEnd"> </span></caption>
|
||||
<tr>
|
||||
<th class="colOne" scope="col">Method and Description</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr class="altColor">
|
||||
<td class="colOne"><a href="Script.html#getOurTradedItemCount()">Script.getOurTradedItemCount()</a>
|
||||
<div class="block"><i>use Script#getLocalTradeItemCount()</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colOne"><a href="Script.html#getPlayerByPid(int)">Script.getPlayerByPid(int)</a>
|
||||
<div class="block"><i>Unreliable in comparison to
|
||||
<a href="Script.html#getPlayerByName(java.lang.String)"><code>getPlayerByName(String)</code></a>.</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colOne"><a href="Script.html#getSleepingFatigue()">Script.getSleepingFatigue()</a>
|
||||
<div class="block"><i>Use <a href="Script.html#getFatigue()"><code>getFatigue()</code></a>.</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colOne"><a href="Script.html#getTheirTradedItemCount()">Script.getTheirTradedItemCount()</a>
|
||||
<div class="block"><i>use Script#getRemoteTradeItemCount()</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colOne"><a href="Script.html#isTricking()">Script.isTricking()</a>
|
||||
<div class="block"><i>For internal use. Legacy.</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
<td class="colOne"><a href="Script.html#sleep(int)">Script.sleep(int)</a>
|
||||
<div class="block"><i>Will cause the entire game to freeze when called in main()'s
|
||||
thread. The RSC servers expect a ping every 5 seconds among
|
||||
other things, so use of this method is definitely not
|
||||
recommended. If you find yourself using this, consider
|
||||
updating your code to make use of System.currentTimeMillis()
|
||||
or System.nanoTime().</i></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>API Help</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript"><!--
|
||||
if (location.href.indexOf('is-external=true') == -1) {
|
||||
parent.document.title="API Help";
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
<noscript>
|
||||
<div>JavaScript is disabled on your browser.</div>
|
||||
</noscript>
|
||||
<div class="header">
|
||||
<h1 class="title">How This API Document Is Organized</h1>
|
||||
<div class="subTitle">This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.</div>
|
||||
</div>
|
||||
<div class="contentContainer">
|
||||
<ul class="blockList">
|
||||
<li class="blockList">
|
||||
<h2>Package</h2>
|
||||
<p>Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:</p>
|
||||
<ul>
|
||||
<li>Interfaces (italic)</li>
|
||||
<li>Classes</li>
|
||||
<li>Enums</li>
|
||||
<li>Exceptions</li>
|
||||
<li>Errors</li>
|
||||
<li>Annotation Types</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Class/Interface</h2>
|
||||
<p>Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:</p>
|
||||
<ul>
|
||||
<li>Class inheritance diagram</li>
|
||||
<li>Direct Subclasses</li>
|
||||
<li>All Known Subinterfaces</li>
|
||||
<li>All Known Implementing Classes</li>
|
||||
<li>Class/interface declaration</li>
|
||||
<li>Class/interface description</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Nested Class Summary</li>
|
||||
<li>Field Summary</li>
|
||||
<li>Constructor Summary</li>
|
||||
<li>Method Summary</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Field Detail</li>
|
||||
<li>Constructor Detail</li>
|
||||
<li>Method Detail</li>
|
||||
</ul>
|
||||
<p>Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Annotation Type</h2>
|
||||
<p>Each annotation type has its own separate page with the following sections:</p>
|
||||
<ul>
|
||||
<li>Annotation Type declaration</li>
|
||||
<li>Annotation Type description</li>
|
||||
<li>Required Element Summary</li>
|
||||
<li>Optional Element Summary</li>
|
||||
<li>Element Detail</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Enum</h2>
|
||||
<p>Each enum has its own separate page with the following sections:</p>
|
||||
<ul>
|
||||
<li>Enum declaration</li>
|
||||
<li>Enum description</li>
|
||||
<li>Enum Constant Summary</li>
|
||||
<li>Enum Constant Detail</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Deprecated API</h2>
|
||||
<p>The <a href="deprecated-list.html">Deprecated API</a> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Prev/Next</h2>
|
||||
<p>These links take you to the next or previous class, interface, package, or related page.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Frames/No Frames</h2>
|
||||
<p>These links show and hide the HTML frames. All pages are available with or without frames.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>All Classes</h2>
|
||||
<p>The <a href="allclasses-noframe.html">All Classes</a> link shows all classes and interfaces except non-static nested types.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Serialized Form</h2>
|
||||
<p>Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.</p>
|
||||
</li>
|
||||
<li class="blockList">
|
||||
<h2>Constant Field Values</h2>
|
||||
<p>The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<em>This help file applies to API documentation generated using the standard doclet.</em></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,71 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>Generated Documentation (Untitled)</title>
|
||||
<script type="text/javascript">
|
||||
targetPage = "" + window.location.search;
|
||||
if (targetPage != "" && targetPage != "undefined")
|
||||
targetPage = targetPage.substring(1);
|
||||
if (targetPage.indexOf(":") != -1 || (targetPage != "" && !validURL(targetPage)))
|
||||
targetPage = "undefined";
|
||||
function validURL(url) {
|
||||
try {
|
||||
url = decodeURIComponent(url);
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
var pos = url.indexOf(".html");
|
||||
if (pos == -1 || pos != url.length - 5)
|
||||
return false;
|
||||
var allowNumber = false;
|
||||
var allowSep = false;
|
||||
var seenDot = false;
|
||||
for (var i = 0; i < url.length - 5; i++) {
|
||||
var ch = url.charAt(i);
|
||||
if ('a' <= ch && ch <= 'z' ||
|
||||
'A' <= ch && ch <= 'Z' ||
|
||||
ch == '$' ||
|
||||
ch == '_' ||
|
||||
ch.charCodeAt(0) > 127) {
|
||||
allowNumber = true;
|
||||
allowSep = true;
|
||||
} else if ('0' <= ch && ch <= '9'
|
||||
|| ch == '-') {
|
||||
if (!allowNumber)
|
||||
return false;
|
||||
} else if (ch == '/' || ch == '.') {
|
||||
if (!allowSep)
|
||||
return false;
|
||||
allowNumber = false;
|
||||
allowSep = false;
|
||||
if (ch == '.')
|
||||
seenDot = true;
|
||||
if (ch == '/' && seenDot)
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function loadFrames() {
|
||||
if (targetPage != "" && targetPage != "undefined")
|
||||
top.classFrame.location = top.targetPage;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<frameset cols="20%,80%" title="Documentation frame" onload="top.loadFrames()">
|
||||
<frame src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
|
||||
<frame src="Script.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
|
||||
<noframes>
|
||||
<noscript>
|
||||
<div>JavaScript is disabled on your browser.</div>
|
||||
</noscript>
|
||||
<h2>Frame Alert</h2>
|
||||
<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="Script.html">Non-frame version</a>.</p>
|
||||
</noframes>
|
||||
</frameset>
|
||||
</html>
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<title>&lt;Unnamed&gt;</title>
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="bar"><a href="package-summary.html" target="classFrame"><Unnamed></a></h1>
|
||||
<div class="indexContainer">
|
||||
<h2 title="Classes">Classes</h2>
|
||||
<ul title="Classes">
|
||||
<li><a href="Script.html" title="class in <Unnamed>" target="classFrame">Script</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Generated by javadoc (version 1.7.0_75) on Sat Feb 21 23:12:20 GMT 2015 -->
|
||||
<meta name="date" content="2015-02-21">
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<div>JavaScript is disabled on your browser.</div>
|
||||
</noscript>
|
||||
<div class="header">
|
||||
<h1 title="Package" class="title">Package <Unnamed></h1>
|
||||
</div>
|
||||
<div class="contentContainer">
|
||||
<ul class="blockList">
|
||||
<li class="blockList">
|
||||
<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
|
||||
<caption><span>Class Summary</span><span class="tabEnd"> </span></caption>
|
||||
<tr>
|
||||
<th class="colFirst" scope="col">Class</th>
|
||||
<th class="colLast" scope="col">Description</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><a href="Script.html" title="class in <Unnamed>">Script</a></td>
|
||||
<td class="colLast"> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 291 B |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 849 B |
@@ -0,0 +1,474 @@
|
||||
/* Javadoc style sheet */
|
||||
/*
|
||||
Overall document style
|
||||
*/
|
||||
body {
|
||||
background-color:#ffffff;
|
||||
color:#353833;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
font-size:76%;
|
||||
margin:0;
|
||||
}
|
||||
a:link, a:visited {
|
||||
text-decoration:none;
|
||||
color:#4c6b87;
|
||||
}
|
||||
a:hover, a:focus {
|
||||
text-decoration:none;
|
||||
color:#bb7a2a;
|
||||
}
|
||||
a:active {
|
||||
text-decoration:none;
|
||||
color:#4c6b87;
|
||||
}
|
||||
a[name] {
|
||||
color:#353833;
|
||||
}
|
||||
a[name]:hover {
|
||||
text-decoration:none;
|
||||
color:#353833;
|
||||
}
|
||||
pre {
|
||||
font-size:1.3em;
|
||||
}
|
||||
h1 {
|
||||
font-size:1.8em;
|
||||
}
|
||||
h2 {
|
||||
font-size:1.5em;
|
||||
}
|
||||
h3 {
|
||||
font-size:1.4em;
|
||||
}
|
||||
h4 {
|
||||
font-size:1.3em;
|
||||
}
|
||||
h5 {
|
||||
font-size:1.2em;
|
||||
}
|
||||
h6 {
|
||||
font-size:1.1em;
|
||||
}
|
||||
ul {
|
||||
list-style-type:disc;
|
||||
}
|
||||
code, tt {
|
||||
font-size:1.2em;
|
||||
}
|
||||
dt code {
|
||||
font-size:1.2em;
|
||||
}
|
||||
table tr td dt code {
|
||||
font-size:1.2em;
|
||||
vertical-align:top;
|
||||
}
|
||||
sup {
|
||||
font-size:.6em;
|
||||
}
|
||||
/*
|
||||
Document title and Copyright styles
|
||||
*/
|
||||
.clear {
|
||||
clear:both;
|
||||
height:0px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.aboutLanguage {
|
||||
float:right;
|
||||
padding:0px 21px;
|
||||
font-size:.8em;
|
||||
z-index:200;
|
||||
margin-top:-7px;
|
||||
}
|
||||
.legalCopy {
|
||||
margin-left:.5em;
|
||||
}
|
||||
.bar a, .bar a:link, .bar a:visited, .bar a:active {
|
||||
color:#FFFFFF;
|
||||
text-decoration:none;
|
||||
}
|
||||
.bar a:hover, .bar a:focus {
|
||||
color:#bb7a2a;
|
||||
}
|
||||
.tab {
|
||||
background-color:#0066FF;
|
||||
background-image:url(resources/titlebar.gif);
|
||||
background-position:left top;
|
||||
background-repeat:no-repeat;
|
||||
color:#ffffff;
|
||||
padding:8px;
|
||||
width:5em;
|
||||
font-weight:bold;
|
||||
}
|
||||
/*
|
||||
Navigation bar styles
|
||||
*/
|
||||
.bar {
|
||||
background-image:url(resources/background.gif);
|
||||
background-repeat:repeat-x;
|
||||
color:#FFFFFF;
|
||||
padding:.8em .5em .4em .8em;
|
||||
height:auto;/*height:1.8em;*/
|
||||
font-size:1em;
|
||||
margin:0;
|
||||
}
|
||||
.topNav {
|
||||
background-image:url(resources/background.gif);
|
||||
background-repeat:repeat-x;
|
||||
color:#FFFFFF;
|
||||
float:left;
|
||||
padding:0;
|
||||
width:100%;
|
||||
clear:right;
|
||||
height:2.8em;
|
||||
padding-top:10px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.bottomNav {
|
||||
margin-top:10px;
|
||||
background-image:url(resources/background.gif);
|
||||
background-repeat:repeat-x;
|
||||
color:#FFFFFF;
|
||||
float:left;
|
||||
padding:0;
|
||||
width:100%;
|
||||
clear:right;
|
||||
height:2.8em;
|
||||
padding-top:10px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.subNav {
|
||||
background-color:#dee3e9;
|
||||
border-bottom:1px solid #9eadc0;
|
||||
float:left;
|
||||
width:100%;
|
||||
overflow:hidden;
|
||||
}
|
||||
.subNav div {
|
||||
clear:left;
|
||||
float:left;
|
||||
padding:0 0 5px 6px;
|
||||
}
|
||||
ul.navList, ul.subNavList {
|
||||
float:left;
|
||||
margin:0 25px 0 0;
|
||||
padding:0;
|
||||
}
|
||||
ul.navList li{
|
||||
list-style:none;
|
||||
float:left;
|
||||
padding:3px 6px;
|
||||
}
|
||||
ul.subNavList li{
|
||||
list-style:none;
|
||||
float:left;
|
||||
font-size:90%;
|
||||
}
|
||||
.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
|
||||
color:#FFFFFF;
|
||||
text-decoration:none;
|
||||
}
|
||||
.topNav a:hover, .bottomNav a:hover {
|
||||
text-decoration:none;
|
||||
color:#bb7a2a;
|
||||
}
|
||||
.navBarCell1Rev {
|
||||
background-image:url(resources/tab.gif);
|
||||
background-color:#a88834;
|
||||
color:#FFFFFF;
|
||||
margin: auto 5px;
|
||||
border:1px solid #c9aa44;
|
||||
}
|
||||
/*
|
||||
Page header and footer styles
|
||||
*/
|
||||
.header, .footer {
|
||||
clear:both;
|
||||
margin:0 20px;
|
||||
padding:5px 0 0 0;
|
||||
}
|
||||
.indexHeader {
|
||||
margin:10px;
|
||||
position:relative;
|
||||
}
|
||||
.indexHeader h1 {
|
||||
font-size:1.3em;
|
||||
}
|
||||
.title {
|
||||
color:#2c4557;
|
||||
margin:10px 0;
|
||||
}
|
||||
.subTitle {
|
||||
margin:5px 0 0 0;
|
||||
}
|
||||
.header ul {
|
||||
margin:0 0 25px 0;
|
||||
padding:0;
|
||||
}
|
||||
.footer ul {
|
||||
margin:20px 0 5px 0;
|
||||
}
|
||||
.header ul li, .footer ul li {
|
||||
list-style:none;
|
||||
font-size:1.2em;
|
||||
}
|
||||
/*
|
||||
Heading styles
|
||||
*/
|
||||
div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
|
||||
background-color:#dee3e9;
|
||||
border-top:1px solid #9eadc0;
|
||||
border-bottom:1px solid #9eadc0;
|
||||
margin:0 0 6px -8px;
|
||||
padding:2px 5px;
|
||||
}
|
||||
ul.blockList ul.blockList ul.blockList li.blockList h3 {
|
||||
background-color:#dee3e9;
|
||||
border-top:1px solid #9eadc0;
|
||||
border-bottom:1px solid #9eadc0;
|
||||
margin:0 0 6px -8px;
|
||||
padding:2px 5px;
|
||||
}
|
||||
ul.blockList ul.blockList li.blockList h3 {
|
||||
padding:0;
|
||||
margin:15px 0;
|
||||
}
|
||||
ul.blockList li.blockList h2 {
|
||||
padding:0px 0 20px 0;
|
||||
}
|
||||
/*
|
||||
Page layout container styles
|
||||
*/
|
||||
.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
|
||||
clear:both;
|
||||
padding:10px 20px;
|
||||
position:relative;
|
||||
}
|
||||
.indexContainer {
|
||||
margin:10px;
|
||||
position:relative;
|
||||
font-size:1.0em;
|
||||
}
|
||||
.indexContainer h2 {
|
||||
font-size:1.1em;
|
||||
padding:0 0 3px 0;
|
||||
}
|
||||
.indexContainer ul {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
.indexContainer ul li {
|
||||
list-style:none;
|
||||
}
|
||||
.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
|
||||
font-size:1.1em;
|
||||
font-weight:bold;
|
||||
margin:10px 0 0 0;
|
||||
color:#4E4E4E;
|
||||
}
|
||||
.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
|
||||
margin:10px 0 10px 20px;
|
||||
}
|
||||
.serializedFormContainer dl.nameValue dt {
|
||||
margin-left:1px;
|
||||
font-size:1.1em;
|
||||
display:inline;
|
||||
font-weight:bold;
|
||||
}
|
||||
.serializedFormContainer dl.nameValue dd {
|
||||
margin:0 0 0 1px;
|
||||
font-size:1.1em;
|
||||
display:inline;
|
||||
}
|
||||
/*
|
||||
List styles
|
||||
*/
|
||||
ul.horizontal li {
|
||||
display:inline;
|
||||
font-size:0.9em;
|
||||
}
|
||||
ul.inheritance {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
ul.inheritance li {
|
||||
display:inline;
|
||||
list-style:none;
|
||||
}
|
||||
ul.inheritance li ul.inheritance {
|
||||
margin-left:15px;
|
||||
padding-left:15px;
|
||||
padding-top:1px;
|
||||
}
|
||||
ul.blockList, ul.blockListLast {
|
||||
margin:10px 0 10px 0;
|
||||
padding:0;
|
||||
}
|
||||
ul.blockList li.blockList, ul.blockListLast li.blockList {
|
||||
list-style:none;
|
||||
margin-bottom:25px;
|
||||
}
|
||||
ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
|
||||
padding:0px 20px 5px 10px;
|
||||
border:1px solid #9eadc0;
|
||||
background-color:#f9f9f9;
|
||||
}
|
||||
ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
|
||||
padding:0 0 5px 8px;
|
||||
background-color:#ffffff;
|
||||
border:1px solid #9eadc0;
|
||||
border-top:none;
|
||||
}
|
||||
ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
|
||||
margin-left:0;
|
||||
padding-left:0;
|
||||
padding-bottom:15px;
|
||||
border:none;
|
||||
border-bottom:1px solid #9eadc0;
|
||||
}
|
||||
ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
|
||||
list-style:none;
|
||||
border-bottom:none;
|
||||
padding-bottom:0;
|
||||
}
|
||||
table tr td dl, table tr td dl dt, table tr td dl dd {
|
||||
margin-top:0;
|
||||
margin-bottom:1px;
|
||||
}
|
||||
/*
|
||||
Table styles
|
||||
*/
|
||||
.contentContainer table, .classUseContainer table, .constantValuesContainer table {
|
||||
border-bottom:1px solid #9eadc0;
|
||||
width:100%;
|
||||
}
|
||||
.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
|
||||
width:100%;
|
||||
}
|
||||
.contentContainer .description table, .contentContainer .details table {
|
||||
border-bottom:none;
|
||||
}
|
||||
.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
|
||||
vertical-align:top;
|
||||
padding-right:20px;
|
||||
}
|
||||
.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
|
||||
.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
|
||||
.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
|
||||
.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
|
||||
padding-right:3px;
|
||||
}
|
||||
.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
|
||||
position:relative;
|
||||
text-align:left;
|
||||
background-repeat:no-repeat;
|
||||
color:#FFFFFF;
|
||||
font-weight:bold;
|
||||
clear:none;
|
||||
overflow:hidden;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
caption a:link, caption a:hover, caption a:active, caption a:visited {
|
||||
color:#FFFFFF;
|
||||
}
|
||||
.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
|
||||
white-space:nowrap;
|
||||
padding-top:8px;
|
||||
padding-left:8px;
|
||||
display:block;
|
||||
float:left;
|
||||
background-image:url(resources/titlebar.gif);
|
||||
height:18px;
|
||||
}
|
||||
.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
|
||||
width:10px;
|
||||
background-image:url(resources/titlebar_end.gif);
|
||||
background-repeat:no-repeat;
|
||||
background-position:top right;
|
||||
position:relative;
|
||||
float:left;
|
||||
}
|
||||
ul.blockList ul.blockList li.blockList table {
|
||||
margin:0 0 12px 0px;
|
||||
width:100%;
|
||||
}
|
||||
.tableSubHeadingColor {
|
||||
background-color: #EEEEFF;
|
||||
}
|
||||
.altColor {
|
||||
background-color:#eeeeef;
|
||||
}
|
||||
.rowColor {
|
||||
background-color:#ffffff;
|
||||
}
|
||||
.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
|
||||
text-align:left;
|
||||
padding:3px 3px 3px 7px;
|
||||
}
|
||||
th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
|
||||
background:#dee3e9;
|
||||
border-top:1px solid #9eadc0;
|
||||
border-bottom:1px solid #9eadc0;
|
||||
text-align:left;
|
||||
padding:3px 3px 3px 7px;
|
||||
}
|
||||
td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
|
||||
font-weight:bold;
|
||||
}
|
||||
td.colFirst, th.colFirst {
|
||||
border-left:1px solid #9eadc0;
|
||||
white-space:nowrap;
|
||||
}
|
||||
td.colLast, th.colLast {
|
||||
border-right:1px solid #9eadc0;
|
||||
}
|
||||
td.colOne, th.colOne {
|
||||
border-right:1px solid #9eadc0;
|
||||
border-left:1px solid #9eadc0;
|
||||
}
|
||||
table.overviewSummary {
|
||||
padding:0px;
|
||||
margin-left:0px;
|
||||
}
|
||||
table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
|
||||
table.overviewSummary td.colOne, table.overviewSummary th.colOne {
|
||||
width:25%;
|
||||
vertical-align:middle;
|
||||
}
|
||||
table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
|
||||
width:25%;
|
||||
vertical-align:middle;
|
||||
}
|
||||
/*
|
||||
Content styles
|
||||
*/
|
||||
.description pre {
|
||||
margin-top:0;
|
||||
}
|
||||
.deprecatedContent {
|
||||
margin:0;
|
||||
padding:10px 0;
|
||||
}
|
||||
.docSummary {
|
||||
padding:0;
|
||||
}
|
||||
/*
|
||||
Formatting effect styles
|
||||
*/
|
||||
.sourceLineNo {
|
||||
color:green;
|
||||
padding:0 30px 0 0;
|
||||
}
|
||||
h1.hidden {
|
||||
visibility:hidden;
|
||||
overflow:hidden;
|
||||
font-size:.9em;
|
||||
}
|
||||
.block {
|
||||
display:block;
|
||||
margin:3px 0 0 0;
|
||||
}
|
||||
.strong {
|
||||
font-weight:bold;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
[0] name='Controlled'
|
||||
[1] name='Aggressive'
|
||||
[2] name='Accurate'
|
||||
[3] name='Defensive'
|
||||
@@ -0,0 +1,794 @@
|
||||
[0] name='Unicorn' desc='It's a unicorn' combat=21
|
||||
[1] name='Bob' desc='An axe seller' combat=2
|
||||
[2] name='Sheep' desc='A very wooly sheep' combat=0
|
||||
[3] name='Chicken' desc='Yep definitely a chicken' combat=3
|
||||
[4] name='Goblin' desc='An ugly green creature' combat=13
|
||||
[5] name='Hans' desc='A castle servant' combat=3
|
||||
[6] name='cow' desc='It's a multi purpose cow' combat=8
|
||||
[7] name='cook' desc='The head cook of Lumbridge castle' combat=15
|
||||
[8] name='Bear' desc='Eek! A bear!' combat=24
|
||||
[9] name='Priest' desc='A priest of Saradomin' combat=0
|
||||
[10] name='Urhney' desc='He looks a little grumpy' combat=8
|
||||
[11] name='Man' desc='One of runescapes many citizens' combat=9
|
||||
[12] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[13] name='Camel' desc='Oh its a camel' combat=0
|
||||
[14] name='Gypsy' desc='An old gypsy lady' combat=0
|
||||
[15] name='Ghost' desc='Ooh spooky' combat=12
|
||||
[16] name='Sir Prysin' desc='One of the king's knights' combat=40
|
||||
[17] name='Traiborn the wizard' desc='An old wizard' combat=12
|
||||
[18] name='Captain Rovin' desc='The head of the palace guard' combat=51
|
||||
[19] name='Rat' desc='Overgrown vermin' combat=8
|
||||
[20] name='Reldo' desc='I think he's the librarian' combat=12
|
||||
[21] name='mugger' desc='He jumps out and attacks people' combat=10
|
||||
[22] name='Lesser Demon' desc='Lesser but still pretty big' combat=79
|
||||
[23] name='Giant Spider' desc='I think this spider has been genetically modified' combat=8
|
||||
[24] name='Man' desc='A shifty looking man' combat=30
|
||||
[25] name='Jonny the beard' desc='I can see why he's called the beard' combat=10
|
||||
[26] name='Baraek' desc='A fur trader' combat=30
|
||||
[27] name='Katrine' desc='She doesn't look to friendly' combat=25
|
||||
[28] name='Tramp' desc='A scruffy looking chap' combat=7
|
||||
[29] name='Rat' desc='A small muddy rat' combat=2
|
||||
[30] name='Romeo' desc='He looks mildly confused' combat=45
|
||||
[31] name='Juliet' desc='She looks a little stressed' combat=2
|
||||
[32] name='Father Lawrence' desc='A kindly looking priest' combat=0
|
||||
[33] name='Apothecary' desc='I wonder if he has any good potions' combat=6
|
||||
[34] name='spider' desc='Incey wincey' combat=2
|
||||
[35] name='Delrith' desc='A freshly summoned demon' combat=30
|
||||
[36] name='Veronica' desc='She doesn't look too happy' combat=2
|
||||
[37] name='Weaponsmaster' desc='The phoenix gang quartermaster' combat=25
|
||||
[38] name='Professor Oddenstein' desc='A mad scientist if I ever saw one' combat=4
|
||||
[39] name='Curator' desc='He looks like he's daydreaming' combat=2
|
||||
[40] name='skeleton' desc='It rattles as it walks' combat=21
|
||||
[41] name='zombie' desc='The living dead' combat=24
|
||||
[42] name='king' desc='King Roald the VIII' combat=30
|
||||
[43] name='Giant bat' desc='An angry flying rodent' combat=32
|
||||
[44] name='Bartender' desc='A friendly barman' combat=0
|
||||
[45] name='skeleton' desc='It rattles as it walks' combat=31
|
||||
[46] name='skeleton' desc='It rattles as it walks' combat=25
|
||||
[47] name='Rat' desc='overgrown vermin' combat=13
|
||||
[48] name='Horvik the Armourer' desc='He looks strong' combat=16
|
||||
[49] name='Bear' desc='A bear' combat=0
|
||||
[50] name='skeleton' desc='It rattles when it walks' combat=19
|
||||
[51] name='Shopkeeper' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[52] name='zombie' desc='The living dead' combat=19
|
||||
[53] name='Ghost' desc='Ooh spooky' combat=25
|
||||
[54] name='Aubury' desc='I think he might be a shop keeper' combat=0
|
||||
[55] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[56] name='shopkeeper' desc='I can buy swords off him' combat=0
|
||||
[57] name='Darkwizard' desc='He works evil magic' combat=13
|
||||
[58] name='lowe' desc='The owner of the archery store' combat=0
|
||||
[59] name='Thessalia' desc='A young shop assistant' combat=0
|
||||
[60] name='Darkwizard' desc='He works evil magic' combat=25
|
||||
[61] name='Giant' desc='A very large foe' combat=37
|
||||
[62] name='Goblin' desc='An ugly green creature' combat=7
|
||||
[63] name='farmer' desc='He grows the crops in this area' combat=15
|
||||
[64] name='Thief' desc='He'll take anything that isn't nailed down' combat=21
|
||||
[65] name='Guard' desc='He tries to keep order around here' combat=28
|
||||
[66] name='Black Knight' desc='A sinister looking knight' combat=46
|
||||
[67] name='Hobgoblin' desc='A large ugly green creature' combat=32
|
||||
[68] name='zombie' desc='The living dead' combat=32
|
||||
[69] name='Zaff' desc='He trades in staffs' combat=0
|
||||
[70] name='Scorpion' desc='An extremely vicious scorpion' combat=21
|
||||
[71] name='silk trader' desc='He sells silk' combat=0
|
||||
[72] name='Man' desc='One of Runescapes many citizens' combat=9
|
||||
[73] name='Guide' desc='He gives hints to new adventurers' combat=1
|
||||
[74] name='Giant Spider' desc='I think this spider has been genetically modified' combat=31
|
||||
[75] name='Peksa' desc='A helmet salesman' combat=9
|
||||
[76] name='Barbarian' desc='Not civilised looking' combat=16
|
||||
[77] name='Fred the farmer' desc='An old farmer' combat=9
|
||||
[78] name='Gunthor the Brave' desc='The barbarians fearless leader' combat=37
|
||||
[79] name='Witch' desc='She's got warts' combat=25
|
||||
[80] name='Ghost' desc='Ooh spooky' combat=25
|
||||
[81] name='Wizard' desc='An old wizard' combat=16
|
||||
[82] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[83] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[84] name='Zeke' desc='He sells Scimitars' combat=0
|
||||
[85] name='Louie Legs' desc='He might want to sell something' combat=0
|
||||
[86] name='Warrior' desc='A member of Al Kharid's military' combat=18
|
||||
[87] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[88] name='Shop Assistant' desc='Maybe she'd like to buy some of my junk' combat=0
|
||||
[89] name='Highwayman' desc='He holds up passers by' combat=13
|
||||
[90] name='Kebab Seller' desc='A seller of strange food' combat=0
|
||||
[91] name='Chicken' desc='Yep definitely a chicken' combat=3
|
||||
[92] name='Ernest' desc='A former chicken' combat=3
|
||||
[93] name='Monk' desc='A Peaceful monk' combat=13
|
||||
[94] name='Dwarf' desc='A short angry guy' combat=18
|
||||
[95] name='Banker' desc='He can look after my money' combat=9
|
||||
[96] name='Count Draynor' desc='A vicious vampire' combat=43
|
||||
[97] name='Morgan' desc='A frigtened villager' combat=9
|
||||
[98] name='Dr Harlow' desc='His nose is very red' combat=9
|
||||
[99] name='Deadly Red spider' desc='I think this spider has been genetically modified' combat=36
|
||||
[100] name='Guard' desc='He's here to guard this fortress' combat=28
|
||||
[101] name='Cassie' desc='She sells shields' combat=25
|
||||
[102] name='White Knight' desc='A chivalrous knight' combat=56
|
||||
[103] name='Ranael' desc='A shopkeeper of some sort' combat=25
|
||||
[104] name='Moss Giant' desc='his beard seems to have a life of its own' combat=62
|
||||
[105] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[106] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[107] name='Witch' desc='She's got warts' combat=25
|
||||
[108] name='Black Knight' desc='A sinister looking knight' combat=46
|
||||
[109] name='Greldo' desc='A small green warty creature' combat=7
|
||||
[110] name='Sir Amik Varze' desc='The leader of the white knights' combat=56
|
||||
[111] name='Guildmaster' desc='He's in charge of this place' combat=40
|
||||
[112] name='Valaine' desc='She runs the champion's store' combat=25
|
||||
[113] name='Drogo' desc='He runs a mining store' combat=18
|
||||
[114] name='Imp' desc='A cheeky little imp' combat=5
|
||||
[115] name='Flynn' desc='The mace salesman' combat=16
|
||||
[116] name='Wyson the gardener' desc='An old gardener' combat=8
|
||||
[117] name='Wizard Mizgog' desc='An old wizard' combat=12
|
||||
[118] name='Prince Ali' desc='A young prince' combat=20
|
||||
[119] name='Hassan' desc='the Chancellor to the emir' combat=20
|
||||
[120] name='Osman' desc='He looks a little shifty' combat=20
|
||||
[121] name='Joe' desc='Lady Keli's head guard' combat=40
|
||||
[122] name='Leela' desc='She comes from Al Kharid' combat=20
|
||||
[123] name='Lady Keli' desc='An Infamous bandit' combat=20
|
||||
[124] name='Ned' desc='An old sailor' combat=20
|
||||
[125] name='Aggie' desc='A witch' combat=25
|
||||
[126] name='Prince Ali' desc='That is an effective disguise' combat=10
|
||||
[127] name='Jailguard' desc='I wonder what he's guarding' combat=34
|
||||
[128] name='Redbeard Frank' desc='A pirate' combat=25
|
||||
[129] name='Wydin' desc='A grocer' combat=0
|
||||
[130] name='shop assistant' desc='I can buy swords off him' combat=0
|
||||
[131] name='Brian' desc='An axe seller' combat=0
|
||||
[132] name='squire' desc='A young squire' combat=0
|
||||
[133] name='Head chef' desc='He looks after the chef's guild' combat=15
|
||||
[134] name='Thurgo' desc='A short angry guy' combat=18
|
||||
[135] name='Ice Giant' desc='He's got icicles in his beard' combat=68
|
||||
[136] name='King Scorpion' desc='Wow scorpions shouldn't grow that big' combat=36
|
||||
[137] name='Pirate' desc='A vicious pirate' combat=27
|
||||
[138] name='Sir Vyvin' desc='One of the white knights of Falador' combat=56
|
||||
[139] name='Monk of Zamorak' desc='An evil cleric' combat=29
|
||||
[140] name='Monk of Zamorak' desc='An evil cleric' combat=19
|
||||
[141] name='Wayne' desc='An armourer' combat=16
|
||||
[142] name='Barmaid' desc='a pretty barmaid' combat=25
|
||||
[143] name='Dwarven shopkeeper' desc='I wonder if he wants to buy any of my junk' combat=18
|
||||
[144] name='Doric' desc='A dwarven smith' combat=18
|
||||
[145] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[146] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[147] name='Guide' desc='She gives hints to new adventurers' combat=1
|
||||
[148] name='Hetty' desc='A witch' combat=25
|
||||
[149] name='Betty' desc='A witch' combat=25
|
||||
[150] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[151] name='General wartface' desc='An ugly green creature' combat=13
|
||||
[152] name='General Bentnoze' desc='An ugly green creature' combat=13
|
||||
[153] name='Goblin' desc='An ugly green creature' combat=13
|
||||
[154] name='Goblin' desc='An ugly green creature' combat=13
|
||||
[155] name='Herquin' desc='A gem merchant' combat=0
|
||||
[156] name='Rommik' desc='The owner of the crafting shop' combat=0
|
||||
[157] name='Grum' desc='Grum the goldsmith' combat=0
|
||||
[158] name='Ice warrior' desc='A strange inhuman warrior' combat=57
|
||||
[159] name='Warrior' desc='A skilled fighter' combat=27
|
||||
[160] name='Thrander' desc='A smith of some sort' combat=16
|
||||
[161] name='Border Guard' desc='a guard from Al Kharid' combat=18
|
||||
[162] name='Border Guard' desc='a guard from Al Kharid' combat=18
|
||||
[163] name='Customs Officer' desc='She is here to stop smugglers' combat=16
|
||||
[164] name='Luthas' desc='The owner of the banana plantation' combat=16
|
||||
[165] name='Zambo' desc='He will sell me exotic rum' combat=16
|
||||
[166] name='Captain Tobias' desc='An old sailor' combat=20
|
||||
[167] name='Gerrant' desc='I wonder what he's got for sale' combat=0
|
||||
[168] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[169] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[170] name='Seaman Lorris' desc='A young sailor' combat=20
|
||||
[171] name='Seaman Thresnor' desc='A young sailor' combat=20
|
||||
[172] name='Tanner' desc='He makes leather' combat=45
|
||||
[173] name='Dommik' desc='The owner of the crafting shop' combat=0
|
||||
[174] name='Abbot Langley' desc='A Peaceful monk' combat=13
|
||||
[175] name='Thordur' desc='He runs a a tourist attraction' combat=18
|
||||
[176] name='Brother Jered' desc='human' combat=13
|
||||
[177] name='Rat' desc='Overgrown vermin' combat=13
|
||||
[178] name='Ghost' desc='Ooh spooky' combat=25
|
||||
[179] name='skeleton' desc='it rattles when it walks' combat=31
|
||||
[180] name='zombie' desc='the living dead' combat=32
|
||||
[181] name='Lesser Demon' desc='Lesser but still very big' combat=79
|
||||
[182] name='Melzar the mad' desc='He looks totally insane' combat=45
|
||||
[183] name='Scavvo' desc='He has lopsided eyes' combat=10
|
||||
[184] name='Greater Demon' desc='big red and incredibly evil' combat=87
|
||||
[185] name='Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[186] name='Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[187] name='Oziach' desc='A strange little man' combat=0
|
||||
[188] name='Bear' desc='Eek! A bear!' combat=26
|
||||
[189] name='Black Knight' desc='An armoured follower of Zamorak' combat=46
|
||||
[190] name='chaos Dwarf' desc='a dwarf gone bad' combat=59
|
||||
[191] name='dwarf' desc='A dwarf who looks after the mining guild' combat=18
|
||||
[192] name='Wormbrain' desc='Dumb even by goblin standards' combat=7
|
||||
[193] name='Klarense' desc='A young sailor' combat=20
|
||||
[194] name='Ned' desc='An old sailor' combat=20
|
||||
[195] name='skeleton' desc='A Taller than normal skeleton' combat=54
|
||||
[196] name='Dragon' desc='A powerful and ancient dragon' combat=110
|
||||
[197] name='Oracle' desc='A mystic of unknown race' combat=57
|
||||
[198] name='Duke of Lumbridge' desc='Duke Horacio of Lumbridge' combat=30
|
||||
[199] name='Dark Warrior' desc='A warrior touched by chaos' combat=21
|
||||
[200] name='Druid' desc='A worshipper of Guthix' combat=29
|
||||
[201] name='Red Dragon' desc='A big powerful dragon' combat=140
|
||||
[202] name='Blue Dragon' desc='A mother dragon' combat=105
|
||||
[203] name='Baby Blue Dragon' desc='Young but still dangerous' combat=50
|
||||
[204] name='Kaqemeex' desc='A wise druid' combat=29
|
||||
[205] name='Sanfew' desc='An old druid' combat=29
|
||||
[206] name='Suit of armour' desc='A dusty old suit of armour' combat=29
|
||||
[207] name='Adventurer' desc='A cleric' combat=13
|
||||
[208] name='Adventurer' desc='A wizard' combat=12
|
||||
[209] name='Adventurer' desc='A Warrior' combat=56
|
||||
[210] name='Adventurer' desc='An archer' combat=25
|
||||
[211] name='Leprechaun' desc='A funny little man who lives in a tree' combat=18
|
||||
[212] name='Monk of entrana' desc='A Peaceful monk' combat=13
|
||||
[213] name='Monk of entrana' desc='A Peaceful monk' combat=13
|
||||
[214] name='zombie' desc='The living dead' combat=32
|
||||
[215] name='Monk of entrana' desc='A Peaceful monk' combat=13
|
||||
[216] name='tree spirit' desc='Ooh spooky' combat=95
|
||||
[217] name='cow' desc='It's a dairy cow' combat=8
|
||||
[218] name='Irksol' desc='Is he invisible or just a set of floating clothes?' combat=2
|
||||
[219] name='Fairy Lunderwin' desc='A fairy merchant' combat=2
|
||||
[220] name='Jakut' desc='An unusual looking merchant' combat=2
|
||||
[221] name='Doorman' desc='He guards the entrance to the faerie market' combat=56
|
||||
[222] name='Fairy Shopkeeper' desc='I wonder what he's got for sale' combat=0
|
||||
[223] name='Fairy Shop Assistant' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[224] name='Fairy banker' desc='He can look after my money' combat=9
|
||||
[225] name='Giles' desc='He runs an ore exchange store' combat=30
|
||||
[226] name='Miles' desc='He runs a bar exchange store' combat=30
|
||||
[227] name='Niles' desc='He runs a fish exchange store' combat=30
|
||||
[228] name='Gaius' desc='he sells very big swords' combat=16
|
||||
[229] name='Fairy Ladder attendant' desc='A worker in the faerie market' combat=0
|
||||
[230] name='Jatix' desc='A hard working druid' combat=29
|
||||
[231] name='Master Crafter' desc='The man in charge of the crafter's guild' combat=0
|
||||
[232] name='Bandit' desc='He's ready for a fight' combat=29
|
||||
[233] name='Noterazzo' desc='A bandit shopkeeper' combat=29
|
||||
[234] name='Bandit' desc='A wilderness outlaw' combat=29
|
||||
[235] name='Fat Tony' desc='A Gourmet Pizza chef' combat=15
|
||||
[236] name='Donny the lad' desc='A bandit leader' combat=39
|
||||
[237] name='Black Heather' desc='A bandit leader' combat=39
|
||||
[238] name='Speedy Keith' desc='A bandit leader' combat=39
|
||||
[239] name='White wolf sentry' desc='A vicious mountain wolf' combat=31
|
||||
[240] name='Boy' desc='He doesn't seem very happy' combat=39
|
||||
[241] name='Rat' desc='He seems to live here' combat=2
|
||||
[242] name='Nora T Hag' desc='She's got warts' combat=25
|
||||
[243] name='Grey wolf' desc='A sinister looking wolf' combat=64
|
||||
[244] name='shapeshifter' desc='I've not seen anyone like this before' combat=24
|
||||
[245] name='shapeshifter' desc='I think this spider has been genetically modified' combat=34
|
||||
[246] name='shapeshifter' desc='Eek! A bear!' combat=44
|
||||
[247] name='shapeshifter' desc='A sinister looking wolf' combat=54
|
||||
[248] name='White wolf' desc='A vicious mountain wolf' combat=41
|
||||
[249] name='Pack leader' desc='A vicious mountain wolf' combat=71
|
||||
[250] name='Harry' desc='I wonder what he's got for sale' combat=0
|
||||
[251] name='Thug' desc='He likes hitting things' combat=18
|
||||
[252] name='Firebird' desc='Probably not a chicken' combat=6
|
||||
[253] name='Achetties' desc='One of Asgarnia's greatest heros' combat=46
|
||||
[254] name='Ice queen' desc='The leader of the ice warriors' combat=103
|
||||
[255] name='Grubor' desc='A rough looking thief' combat=15
|
||||
[256] name='Trobert' desc='A well dressed thief' combat=13
|
||||
[257] name='Garv' desc='A diligent guard' combat=28
|
||||
[258] name='guard' desc='A vicious pirate' combat=27
|
||||
[259] name='Grip' desc='Scar face petes head guard' combat=46
|
||||
[260] name='Alfonse the waiter' desc='He should get a clean apron' combat=9
|
||||
[261] name='Charlie the cook' desc='Head cook of the Shrimp and parrot' combat=15
|
||||
[262] name='Guard Dog' desc='He doesn't seem pleased to see me' combat=46
|
||||
[263] name='Ice spider' desc='I think this spider has been genetically modified' combat=64
|
||||
[264] name='Pirate' desc='A vicious pirate' combat=30
|
||||
[265] name='Jailer' desc='Guards prisoners for the black knights' combat=51
|
||||
[266] name='Lord Darquarius' desc='A black knight commander' combat=76
|
||||
[267] name='Seth' desc='He runs a fish exchange store' combat=30
|
||||
[268] name='Banker' desc='He can look after my money' combat=9
|
||||
[269] name='Helemos' desc='A retired hero' combat=46
|
||||
[270] name='Chaos Druid' desc='A crazy evil druid' combat=19
|
||||
[271] name='Poison Scorpion' desc='It has a very vicious looking tail' combat=26
|
||||
[272] name='Velrak the explorer' desc='he looks cold and hungry' combat=3
|
||||
[273] name='Sir Lancelot' desc='A knight of the round table' combat=56
|
||||
[274] name='Sir Gawain' desc='A knight of the round table' combat=56
|
||||
[275] name='King Arthur' desc='A wise old king' combat=56
|
||||
[276] name='Sir Mordred' desc='An evil knight' combat=58
|
||||
[277] name='Renegade knight' desc='He isn't very friendly' combat=51
|
||||
[278] name='Davon' desc='An amulet trader' combat=27
|
||||
[279] name='Bartender' desc='I could get some grog off him' combat=0
|
||||
[280] name='Arhein' desc='A merchant' combat=0
|
||||
[281] name='Morgan le faye' desc='An evil sorceress' combat=25
|
||||
[282] name='Candlemaker' desc='He makes and sells candles' combat=16
|
||||
[283] name='lady' desc='She has a hint of magic about her' combat=0
|
||||
[284] name='lady' desc='She has a hint of magic about her' combat=0
|
||||
[285] name='lady' desc='She has a hint of magic about her' combat=0
|
||||
[286] name='Beggar' desc='A scruffy looking chap' combat=7
|
||||
[287] name='Merlin' desc='An old wizard' combat=12
|
||||
[288] name='Thrantax' desc='A freshly summoned demon' combat=90
|
||||
[289] name='Hickton' desc='The owner of the archery store' combat=0
|
||||
[290] name='Black Demon' desc='A big scary jet black demon' combat=156
|
||||
[291] name='Black Dragon' desc='A fierce dragon with black scales!' combat=200
|
||||
[292] name='Poison Spider' desc='I think this spider has been genetically modified' combat=63
|
||||
[293] name='Monk of Zamorak' desc='An evil cleric' combat=47
|
||||
[294] name='Hellhound' desc='Hello nice doggy' combat=114
|
||||
[295] name='Animated axe' desc='a magic axe with a mind of it's own' combat=46
|
||||
[296] name='Black Unicorn' desc='It's a sort of unicorn' combat=31
|
||||
[297] name='Frincos' desc='A Peaceful monk' combat=13
|
||||
[298] name='Otherworldly being' desc='Is he invisible or just a set of floating clothes?' combat=66
|
||||
[299] name='Owen' desc='He runs a fish exchange store' combat=30
|
||||
[300] name='Thormac the sorceror' desc='A powerful sorcerrer' combat=25
|
||||
[301] name='Seer' desc='An old wizard' combat=16
|
||||
[302] name='Kharid Scorpion' desc='a smaller less dangerous scorpion' combat=21
|
||||
[303] name='Kharid Scorpion' desc='a smaller less dangerous scorpion' combat=21
|
||||
[304] name='Kharid Scorpion' desc='a smaller less dangerous scorpion' combat=21
|
||||
[305] name='Barbarian guard' desc='Not very civilised' combat=16
|
||||
[306] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[307] name='man' desc='A well dressed nobleman' combat=9
|
||||
[308] name='gem trader' desc='He sells gems' combat=0
|
||||
[309] name='Dimintheis' desc='A well dressed nobleman' combat=9
|
||||
[310] name='chef' desc='A busy looking chef' combat=15
|
||||
[311] name='Hobgoblin' desc='An ugly green creature' combat=48
|
||||
[312] name='Ogre' desc='A large dim looking humanoid' combat=58
|
||||
[313] name='Boot the Dwarf' desc='A short angry guy' combat=18
|
||||
[314] name='Wizard' desc='A young wizard' combat=16
|
||||
[315] name='Chronozon' desc='Chronozon the blood demon' combat=121
|
||||
[316] name='Captain Barnaby' desc='An old sailor' combat=20
|
||||
[317] name='Customs Official' desc='She's here to stop smugglers' combat=16
|
||||
[318] name='Man' desc='One of Runescape's citizens' combat=9
|
||||
[319] name='farmer' desc='An humble peasant' combat=15
|
||||
[320] name='Warrior' desc='A skilled fighter' combat=27
|
||||
[321] name='Guard' desc='He tries to keep the law and order around here' combat=28
|
||||
[322] name='Knight' desc='A knight of Ardougne' combat=56
|
||||
[323] name='Paladin' desc='A paladin of Ardougne' combat=71
|
||||
[324] name='Hero' desc='A Hero of Ardougne' combat=83
|
||||
[325] name='Baker' desc='He sells hot baked bread' combat=15
|
||||
[326] name='silk merchant' desc='He buys silk' combat=0
|
||||
[327] name='Fur trader' desc='A buyer and seller of animal furs' combat=0
|
||||
[328] name='silver merchant' desc='He deals in silver' combat=0
|
||||
[329] name='spice merchant' desc='He sells exotic spices' combat=15
|
||||
[330] name='gem merchant' desc='He sells gems' combat=0
|
||||
[331] name='Zenesha' desc='A shopkeeper of some sort' combat=25
|
||||
[332] name='Kangai Mau' desc='A tribesman' combat=0
|
||||
[333] name='Wizard Cromperty' desc='An old wizard' combat=12
|
||||
[334] name='RPDT employee' desc='A delivery man' combat=12
|
||||
[335] name='Horacio' desc='An old gardener' combat=8
|
||||
[336] name='Aemad' desc='He helps run the adventurers store' combat=16
|
||||
[337] name='Kortan' desc='He helps run the adventurers store' combat=16
|
||||
[338] name='zoo keeper' desc='He looks after Ardougne city zoo' combat=20
|
||||
[339] name='Make over mage' desc='He can change how I look' combat=0
|
||||
[340] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[341] name='chuck' desc='A wood merchant' combat=0
|
||||
[342] name='Rogue' desc='He needs a shave' combat=21
|
||||
[343] name='Shadow spider' desc='Is it a spider or is it a shadow' combat=53
|
||||
[344] name='Fire Giant' desc='A big guy with red glowing skin' combat=109
|
||||
[345] name='Grandpa Jack' desc='A wistful old man' combat=20
|
||||
[346] name='Sinister stranger' desc='not your average fisherman' combat=43
|
||||
[347] name='Bonzo' desc='Fishing competition organiser' combat=30
|
||||
[348] name='Forester' desc='He looks after McGrubor's wood' combat=21
|
||||
[349] name='Morris' desc='Fishing competition organiser' combat=30
|
||||
[350] name='Brother Omad' desc='A Peaceful monk' combat=13
|
||||
[351] name='Thief' desc='A dastardly blanket thief' combat=21
|
||||
[352] name='Head Thief' desc='A dastardly blanket thief' combat=34
|
||||
[353] name='Big Dave' desc='A well built fisherman' combat=15
|
||||
[354] name='Joshua' desc='A grumpy fisherman' combat=15
|
||||
[355] name='Mountain Dwarf' desc='A short angry guy' combat=18
|
||||
[356] name='Mountain Dwarf' desc='A short angry guy' combat=28
|
||||
[357] name='Brother Cedric' desc='A Peaceful monk' combat=13
|
||||
[358] name='Necromancer' desc='A crazy evil necromancer' combat=34
|
||||
[359] name='zombie' desc='The living dead' combat=24
|
||||
[360] name='Lucien' desc='He walks with a slight limp' combat=21
|
||||
[361] name='The Fire warrior of lesarkus' desc='A strange red humanoid' combat=63
|
||||
[362] name='guardian of Armadyl' desc='A worshipper of Armadyl' combat=54
|
||||
[363] name='guardian of Armadyl' desc='A worshipper of Armadyl' combat=54
|
||||
[364] name='Lucien' desc='He walks with a limp' combat=21
|
||||
[365] name='winelda' desc='A witch' combat=25
|
||||
[366] name='Brother Kojo' desc='A Peaceful monk' combat=13
|
||||
[367] name='Dungeon Rat' desc='Overgrown vermin' combat=16
|
||||
[368] name='Master fisher' desc='The man in charge of the fishing guild' combat=15
|
||||
[369] name='Orven' desc='He runs a fish exchange store' combat=30
|
||||
[370] name='Padik' desc='He runs a fish exchange store' combat=30
|
||||
[371] name='Shopkeeper' desc='He smells of fish' combat=0
|
||||
[372] name='Lady servil' desc='She look's wealthy' combat=2
|
||||
[373] name='Guard' desc='It's one of General Khazard's guard's' combat=28
|
||||
[374] name='Guard' desc='It's one of General Khazard's guard's' combat=28
|
||||
[375] name='Guard' desc='It's one of General Khazard's guard's' combat=28
|
||||
[376] name='Guard' desc='It's one of General Khazard's guard's' combat=28
|
||||
[377] name='Jeremy Servil' desc='A young squire' combat=0
|
||||
[378] name='Justin Servil' desc='Jeremy servil's father' combat=0
|
||||
[379] name='fightslave joe' desc='He look's mistreated and weak' combat=0
|
||||
[380] name='fightslave kelvin' desc='He look's mistreated and weak' combat=0
|
||||
[381] name='local' desc='A scruffy looking chap' combat=7
|
||||
[382] name='Khazard Bartender' desc='A tough looking barman' combat=0
|
||||
[383] name='General Khazard' desc='He look's real nasty' combat=100
|
||||
[384] name='Khazard Ogre' desc='Khazard's strongest ogre warrior' combat=58
|
||||
[385] name='Guard' desc='It's one of General Khazard's guard's' combat=28
|
||||
[386] name='Khazard Scorpion' desc='A large angry scorpion' combat=46
|
||||
[387] name='hengrad' desc='He look's mistreated and weak' combat=0
|
||||
[388] name='Bouncer' desc='Hello nice doggy' combat=122
|
||||
[389] name='Stankers' desc='A cheerful looking fellow' combat=0
|
||||
[390] name='Docky' desc='An old sailor' combat=20
|
||||
[391] name='Shopkeeper' desc='Maybe he'd like to buy some of my junk' combat=0
|
||||
[392] name='Fairy queen' desc='A very little queen' combat=2
|
||||
[393] name='Merlin' desc='An old wizard' combat=12
|
||||
[394] name='Crone' desc='A strange old lady' combat=25
|
||||
[395] name='High priest of entrana' desc='A Peaceful monk' combat=13
|
||||
[396] name='elkoy' desc='It's a tree gnome' combat=3
|
||||
[397] name='remsai' desc='It's a tree gnome' combat=3
|
||||
[398] name='bolkoy' desc='It's a tree gnome' combat=3
|
||||
[399] name='local gnome' desc='It's a young tree gnome' combat=3
|
||||
[400] name='bolren' desc='It's a gnome he look's important' combat=3
|
||||
[401] name='Black Knight titan' desc='He is blocking the way' combat=146
|
||||
[402] name='kalron' desc='he look's lost' combat=3
|
||||
[403] name='brother Galahad' desc='A Peaceful monk' combat=13
|
||||
[404] name='tracker 1' desc='It's a tree gnome' combat=3
|
||||
[405] name='tracker 2' desc='It's a tree gnome' combat=3
|
||||
[406] name='tracker 3' desc='It's a tree gnome' combat=3
|
||||
[407] name='Khazard troop' desc='It's one of General Khazard's warrior's' combat=28
|
||||
[408] name='commander montai' desc='It's a tree gnome' combat=3
|
||||
[409] name='gnome troop' desc='It's a tree gnome trooper' combat=3
|
||||
[410] name='khazard warlord' desc='He look's real nasty' combat=100
|
||||
[411] name='Sir Percival' desc='He's covered in pieces of straw' combat=56
|
||||
[412] name='Fisher king' desc='an old king' combat=30
|
||||
[413] name='maiden' desc='She has a far away look in her eyes' combat=2
|
||||
[414] name='Fisherman' desc='an old fisherman' combat=30
|
||||
[415] name='King Percival' desc='The new fisher king' combat=56
|
||||
[416] name='unhappy peasant' desc='He looks tired and hungry' combat=25
|
||||
[417] name='happy peasant' desc='He looks well fed and full of energy' combat=25
|
||||
[418] name='ceril' desc='It's Sir ceril carnillean a local noblemen' combat=9
|
||||
[419] name='butler' desc='It's the carnillean family butler' combat=9
|
||||
[420] name='carnillean guard' desc='It's a carnillean family guard' combat=28
|
||||
[421] name='Tribesman' desc='A primative warrior' combat=39
|
||||
[422] name='henryeta' desc='It's a wealthy looking woman' combat=2
|
||||
[423] name='philipe' desc='It's a young well dressed boy' combat=0
|
||||
[424] name='clivet' desc='A strange looking man in black ' combat=20
|
||||
[425] name='cult member' desc='An suspicous looking man in black ' combat=20
|
||||
[426] name='Lord hazeel' desc='He could do with some sun' combat=100
|
||||
[427] name='alomone' desc='A musculer looking man in black ' combat=42
|
||||
[428] name='Khazard commander' desc='It's one of General Khazard's commander's' combat=41
|
||||
[429] name='claus' desc='the carnillean family cook' combat=15
|
||||
[430] name='1st plague sheep' desc='The sheep has the plague' combat=0
|
||||
[431] name='2nd plague sheep' desc='The sheep has the plague' combat=0
|
||||
[432] name='3rd plague sheep' desc='The sheep has the plague' combat=0
|
||||
[433] name='4th plague sheep' desc='The sheep has the plague' combat=0
|
||||
[434] name='Farmer brumty' desc='He looks after livestock in this area' combat=15
|
||||
[435] name='Doctor orbon' desc='A local doctor' combat=15
|
||||
[436] name='Councillor Halgrive' desc='A town counceller' combat=20
|
||||
[437] name='Edmond' desc='A local civilian' combat=20
|
||||
[438] name='Citizen' desc='He look's tired' combat=11
|
||||
[439] name='Citizen' desc='He look's frightened' combat=10
|
||||
[440] name='Citizen' desc='She look's frustrated' combat=12
|
||||
[441] name='Citizen' desc='He look's angry' combat=20
|
||||
[442] name='Citizen' desc='He look's disillusioned' combat=15
|
||||
[443] name='Jethick' desc='A cynical old man' combat=15
|
||||
[444] name='Mourner' desc='A mourner or plague healer' combat=2
|
||||
[445] name='Mourner' desc='A mourner or plague healer' combat=2
|
||||
[446] name='Ted Rehnison' desc='The head of the Rehnison family' combat=9
|
||||
[447] name='Martha Rehnison' desc='A fairly poor looking woman' combat=12
|
||||
[448] name='Billy Rehnison' desc='The Rehnisons eldest son' combat=45
|
||||
[449] name='Milli Rehnison' desc='She doesn't seem very happy' combat=39
|
||||
[450] name='Alrena' desc='She look's concerned' combat=2
|
||||
[451] name='Mourner' desc='A mourner or plague healer' combat=2
|
||||
[452] name='Clerk' desc='A bueracratic administrator' combat=2
|
||||
[453] name='Carla' desc='She look's upset' combat=2
|
||||
[454] name='Bravek' desc='The city warder of West Ardougne' combat=30
|
||||
[455] name='Caroline' desc='A well dressed middle aged lady' combat=2
|
||||
[456] name='Holgart' desc='An old sailor' combat=20
|
||||
[457] name='Holgart' desc='An old sailor' combat=20
|
||||
[458] name='Holgart' desc='An old sailor' combat=20
|
||||
[459] name='kent' desc='caroline's husband' combat=45
|
||||
[460] name='bailey' desc='the fishing platform cook' combat=15
|
||||
[461] name='kennith' desc='A young scared looking boy' combat=0
|
||||
[462] name='Platform Fisherman' desc='an emotionless fisherman' combat=30
|
||||
[463] name='Platform Fisherman' desc='an emotionless fisherman' combat=30
|
||||
[464] name='Platform Fisherman' desc='an emotionless fisherman' combat=30
|
||||
[465] name='Elena' desc='She doesn't look too happy' combat=2
|
||||
[466] name='jinno' desc='He doesn't seem to mind his lack of legs' combat=30
|
||||
[467] name='Watto' desc='He doesn't seem to mind his lack of legs' combat=30
|
||||
[468] name='Recruiter' desc='A member of the Ardougne royal army' combat=51
|
||||
[469] name='Head mourner' desc='In charge of people with silly outfits' combat=2
|
||||
[470] name='Almera' desc='A woman of the wilderness' combat=2
|
||||
[471] name='hudon' desc='A young boisterous looking lad' combat=0
|
||||
[472] name='hadley' desc='A happy looking fellow' combat=30
|
||||
[473] name='Rat' desc='Overgrown vermin' combat=7
|
||||
[474] name='Combat instructor' desc='He will tell me how to fight' combat=51
|
||||
[475] name='golrie' desc='It's a tree gnome' combat=3
|
||||
[476] name='Guide' desc='She gives hints to new adventurers' combat=1
|
||||
[477] name='King Black Dragon' desc='The biggest meanest dragon around' combat=245
|
||||
[478] name='cooking instructor' desc='Talk to him to learn about runescape food' combat=15
|
||||
[479] name='fishing instructor' desc='He smells of fish' combat=15
|
||||
[480] name='financial advisor' desc='He knows about money' combat=0
|
||||
[481] name='gerald' desc='An old fisherman' combat=15
|
||||
[482] name='mining instructor' desc='A short angry guy' combat=18
|
||||
[483] name='Elena' desc='She looks concerned' combat=2
|
||||
[484] name='Omart' desc='A nervous looking fellow' combat=30
|
||||
[485] name='Bank assistant' desc='She can look after my stuff' combat=9
|
||||
[486] name='Jerico' desc='He looks friendly enough' combat=15
|
||||
[487] name='Kilron' desc='He looks shifty' combat=15
|
||||
[488] name='Guidor's wife' desc='She looks rather concerned' combat=2
|
||||
[489] name='Quest advisor' desc='I wonder what advise he has to impart' combat=51
|
||||
[490] name='chemist' desc='human' combat=4
|
||||
[491] name='Mourner' desc='A mourner or plague healer' combat=2
|
||||
[492] name='Mourner' desc='A mourner or plague healer' combat=2
|
||||
[493] name='Wilderness guide' desc='He's ready for a fight' combat=29
|
||||
[494] name='Magic Instructor' desc='An old wizard' combat=12
|
||||
[495] name='Mourner' desc='A mourner or plague healer' combat=22
|
||||
[496] name='Community instructor' desc='This is the last advisor - honest' combat=2
|
||||
[497] name='boatman' desc='An old sailor' combat=20
|
||||
[498] name='skeleton mage' desc='It rattles as it walks' combat=21
|
||||
[499] name='controls guide' desc='He's ready for a fight' combat=29
|
||||
[500] name='nurse sarah' desc='She's quite a looker' combat=2
|
||||
[501] name='Tailor' desc='He's ready for a party' combat=29
|
||||
[502] name='Mourner' desc='A mourner or plague healer' combat=25
|
||||
[503] name='Guard' desc='He tries to keep order around here' combat=28
|
||||
[504] name='Chemist' desc='He looks clever enough' combat=29
|
||||
[505] name='Chancy' desc='He's ready for a bet' combat=29
|
||||
[506] name='Hops' desc='He's drunk' combat=29
|
||||
[507] name='DeVinci' desc='He has a colourful personality' combat=29
|
||||
[508] name='Guidor' desc='He's not that ill' combat=29
|
||||
[509] name='Chancy' desc='He's ready for a bet' combat=29
|
||||
[510] name='Hops' desc='He's drunk' combat=29
|
||||
[511] name='DeVinci' desc='He has a colourful personality' combat=29
|
||||
[512] name='king Lathas' desc='King Lanthas of east ardounge' combat=30
|
||||
[513] name='Head wizard' desc='He runs the wizards guild' combat=12
|
||||
[514] name='Magic store owner' desc='An old wizard' combat=12
|
||||
[515] name='Wizard Frumscone' desc='A confused looking wizard' combat=12
|
||||
[516] name='target practice zombie' desc='The living dead' combat=24
|
||||
[517] name='Trufitus' desc='A wise old witch doctor' combat=6
|
||||
[518] name='Colonel Radick' desc='A soldier of the town of Yanille' combat=51
|
||||
[519] name='Soldier' desc='A soldier of the town of Yanille' combat=28
|
||||
[520] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[521] name='Jungle Spider' desc='A venomous deadly spider' combat=47
|
||||
[522] name='Jiminua' desc='She looks very interested in selling some of her wares.' combat=0
|
||||
[523] name='Jogre' desc='An aggressive humanoid' combat=58
|
||||
[524] name='Guard' desc='He tries to keep order around here' combat=28
|
||||
[525] name='Ogre' desc='Useful for ranged training' combat=58
|
||||
[526] name='Guard' desc='He tries to keep order around here' combat=28
|
||||
[527] name='Guard' desc='He tries to keep order around here' combat=28
|
||||
[528] name='shop keeper' desc='he sells weapons' combat=0
|
||||
[529] name='Bartender' desc='I could get a beer off him' combat=0
|
||||
[530] name='Frenita' desc='runs a cookery shop' combat=0
|
||||
[531] name='Ogre chieftan' desc='A slightly bigger uglier ogre' combat=78
|
||||
[532] name='rometti' desc='It's a well dressed tree gnome' combat=3
|
||||
[533] name='Rashiliyia' desc='A willowy ethereal being who floats above the ground' combat=80
|
||||
[534] name='Blurberry' desc='It's a red faced tree gnome' combat=3
|
||||
[535] name='Heckel funch' desc='It's another jolly tree gnome' combat=3
|
||||
[536] name='Aluft Gianne' desc='It's a tree gnome chef' combat=3
|
||||
[537] name='Hudo glenfad' desc='It's another jolly tree gnome' combat=3
|
||||
[538] name='Irena' desc='human' combat=0
|
||||
[539] name='Mosol' desc='A jungle warrior' combat=0
|
||||
[540] name='Gnome banker' desc='It's tree gnome banker' combat=3
|
||||
[541] name='King Narnode Shareen' desc='It's a gnome he look's important' combat=3
|
||||
[542] name='UndeadOne' desc='One of Rashaliyas Minions' combat=62
|
||||
[543] name='Drucas' desc='engraver' combat=20
|
||||
[544] name='tourist' desc='human' combat=29
|
||||
[545] name='King Narnode Shareen' desc='It's a gnome he look's important' combat=3
|
||||
[546] name='Hazelmere' desc='An ancient looking gnome' combat=3
|
||||
[547] name='Glough' desc='An rough looking gnome' combat=3
|
||||
[548] name='Shar' desc='Concerned about the economy' combat=0
|
||||
[549] name='Shantay' desc='human' combat=0
|
||||
[550] name='charlie' desc='Poor guy?' combat=0
|
||||
[551] name='Gnome guard' desc='A tree gnome guard' combat=31
|
||||
[552] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[553] name='Mehman' desc='local' combat=29
|
||||
[554] name='Ana' desc='This lady doesn't look as if she belongs here.' combat=16
|
||||
[555] name='Chaos Druid warrior' desc='A crazy evil druid' combat=44
|
||||
[556] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[557] name='Shipyard worker' desc='He look's busy' combat=44
|
||||
[558] name='Shipyard worker' desc='He look's busy' combat=44
|
||||
[559] name='Shipyard worker' desc='He look's busy' combat=44
|
||||
[560] name='Shipyard foreman' desc='He look's busy' combat=62
|
||||
[561] name='Shipyard foreman' desc='He look's busy' combat=62
|
||||
[562] name='Gnome guard' desc='A tree gnome guard' combat=23
|
||||
[563] name='Femi' desc='It's a little tree gnome' combat=3
|
||||
[564] name='Femi' desc='It's a little tree gnome' combat=3
|
||||
[565] name='Anita' desc='It's a little tree gnome' combat=3
|
||||
[566] name='Glough' desc='An rough looking gnome' combat=3
|
||||
[567] name='Salarin the twisted' desc='A crazy evil druid' combat=69
|
||||
[568] name='Black Demon' desc='A big scary jet black demon' combat=175
|
||||
[569] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[570] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[571] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[572] name='Gnome pilot' desc='He can fly the glider' combat=3
|
||||
[573] name='Sigbert the Adventurer' desc='A Warrior' combat=56
|
||||
[574] name='Yanille Watchman' desc='He watches out for invading ogres' combat=33
|
||||
[575] name='Tower guard' desc='He stops people going up the tower' combat=33
|
||||
[576] name='Gnome Trainer' desc='He can advise on training' combat=11
|
||||
[577] name='Gnome Trainer' desc='He can advise on training' combat=11
|
||||
[578] name='Gnome Trainer' desc='He can advise on training' combat=11
|
||||
[579] name='Gnome Trainer' desc='He can advise on training' combat=11
|
||||
[580] name='Blurberry barman' desc='He serves cocktails' combat=3
|
||||
[581] name='Gnome waiter' desc='He can serve you gnome food' combat=3
|
||||
[582] name='Gnome guard' desc='A tree gnome guard' combat=27
|
||||
[583] name='Gnome child' desc='that's a little gnome' combat=3
|
||||
[584] name='Earth warrior' desc='A strange inhuman warrior' combat=52
|
||||
[585] name='Gnome child' desc='He's a little fellow' combat=3
|
||||
[586] name='Gnome child' desc='hello little gnome' combat=3
|
||||
[587] name='Gulluck' desc='He sells weapons' combat=10
|
||||
[588] name='Gunnjorn' desc='Not civilised looking' combat=16
|
||||
[589] name='Zadimus' desc='Ghostly Visage of the dead Zadimus' combat=0
|
||||
[590] name='Brimstail' desc='An ancient looking gnome' combat=3
|
||||
[591] name='Gnome child' desc='He's a little fellow' combat=3
|
||||
[592] name='Gnome local' desc='A tree gnome villager' combat=9
|
||||
[593] name='Gnome local' desc='A tree gnome villager' combat=3
|
||||
[594] name='Moss Giant' desc='his beard seems to have a life of its own' combat=62
|
||||
[595] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[596] name='Goalie' desc='A gnome ball goal catcher' combat=70
|
||||
[597] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[598] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[599] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[600] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[601] name='Referee' desc='He controls the game' combat=3
|
||||
[602] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[603] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[604] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[605] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[606] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[607] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[608] name='Gnome Baller' desc='A tree gnome ball player' combat=70
|
||||
[609] name='Gnome Baller' desc='He's on your team' combat=70
|
||||
[610] name='Gnome Baller' desc='He's on your team' combat=70
|
||||
[611] name='Cheerleader' desc='It's a little tree gnome' combat=3
|
||||
[612] name='Cheerleader' desc='It's a little tree gnome' combat=3
|
||||
[613] name='Nazastarool Zombie' desc='One of Rashaliyas Minions' combat=83
|
||||
[614] name='Nazastarool Skeleton' desc='One of Rashaliyas Minions' combat=83
|
||||
[615] name='Nazastarool Ghost' desc='One of Rashaliyas Minions' combat=83
|
||||
[616] name='Fernahei' desc='An enthusiastic fishing shop owner' combat=6
|
||||
[617] name='Jungle Banker' desc='He can look after my money' combat=9
|
||||
[618] name='Cart Driver' desc='He drives the cart' combat=15
|
||||
[619] name='Cart Driver' desc='He drives the cart' combat=15
|
||||
[620] name='Obli' desc='An intelligent looking shop owner' combat=0
|
||||
[621] name='Kaleb' desc='This is Kaleb Paramaya - a warm and friendly inn owner' combat=0
|
||||
[622] name='Yohnus' desc='This is Yohnus - he runs the local blacksmiths' combat=0
|
||||
[623] name='Serevel' desc='This is Serevel - he sells tickets for the 'Lady of the Waves'' combat=0
|
||||
[624] name='Yanni' desc='Yanni Salika - He buys and sells antiques.' combat=0
|
||||
[625] name='Official' desc='He helps the referee' combat=3
|
||||
[626] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[627] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[628] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[629] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[630] name='Blessed Vermen' desc='A undead servent of iban' combat=14
|
||||
[631] name='Blessed Spider' desc='One of iban's eight legged friends' combat=35
|
||||
[632] name='Paladin' desc='A paladin of Ardougne' combat=71
|
||||
[633] name='Paladin' desc='A paladin of Ardougne' combat=71
|
||||
[634] name='slave' desc='He seems possessed' combat=16
|
||||
[635] name='slave' desc='He seems possessed' combat=16
|
||||
[636] name='slave' desc='He seems to have been here a while' combat=16
|
||||
[637] name='slave' desc='He seems possessed' combat=16
|
||||
[638] name='slave' desc='He seems to have been here a while' combat=16
|
||||
[639] name='slave' desc='He seems possessed' combat=16
|
||||
[640] name='slave' desc='He seems to have been here a while' combat=16
|
||||
[641] name='Kalrag' desc='I think this is one of Ibans pets' combat=78
|
||||
[642] name='Niloof' desc='A short angry guy' combat=18
|
||||
[643] name='Kardia the Witch' desc='She's got warts' combat=25
|
||||
[644] name='Souless' desc='He seems an empty shell' combat=16
|
||||
[645] name='Othainian' desc='big red and incredibly evil' combat=78
|
||||
[646] name='Doomion' desc='A big scary jet black demon' combat=98
|
||||
[647] name='Holthion' desc='big red and incredibly evil' combat=78
|
||||
[648] name='Klank' desc='A short angry guy' combat=18
|
||||
[649] name='Iban' desc='You feel terror just looking at him' combat=21
|
||||
[650] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[651] name='Goblin guard' desc='An imposing green creature' combat=48
|
||||
[652] name='Observatory Professor' desc='He works in the observatory' combat=4
|
||||
[653] name='Ugthanki' desc='A dangerous type of spitting camel that can temporarily blind an opponent.' combat=45
|
||||
[654] name='Observatory assistant' desc='The Professor's assistant' combat=4
|
||||
[655] name='Souless' desc='A servent to zamorak' combat=24
|
||||
[656] name='Dungeon spider' desc='A nasty poisonous arachnid' combat=22
|
||||
[657] name='Kamen' desc='A short angry guy' combat=18
|
||||
[658] name='Iban disciple' desc='An evil follower of Iban' combat=19
|
||||
[659] name='Koftik' desc='The kings top tracker' combat=16
|
||||
[660] name='Goblin' desc='These goblins have grown strong' combat=19
|
||||
[661] name='Chadwell' desc='A sturdy looking gent' combat=16
|
||||
[662] name='Professor' desc='The owner of the observatory' combat=4
|
||||
[663] name='San Tojalon' desc='The animated spirit of San Tojalon' combat=120
|
||||
[664] name='Ghost' desc='A doomed victim of zamorak' combat=29
|
||||
[665] name='Spirit of Scorpius' desc='The undead spirit of the follower of Zamorak' combat=100
|
||||
[666] name='Scorpion' desc='There are nasty scorpions around this grave' combat=21
|
||||
[667] name='Dark Mage' desc='He works in the ways of dark magic' combat=0
|
||||
[668] name='Mercenary' desc='He seems to be guarding an area' combat=50
|
||||
[669] name='Mercenary Captain' desc='He's in control of the local guards.' combat=64
|
||||
[670] name='Mercenary' desc='He seems to be guarding an area' combat=39
|
||||
[671] name='Mining Slave' desc='A chained slave forced to mine rocks.' combat=16
|
||||
[672] name='Watchtower wizard' desc='A learned man' combat=12
|
||||
[673] name='Ogre Shaman' desc='An intelligent form of ogre' combat=100
|
||||
[674] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[675] name='Ogre guard' desc='These ogres protect the city' combat=78
|
||||
[676] name='Ogre guard' desc='These ogres protect the city' combat=78
|
||||
[677] name='Ogre guard' desc='These ogres protect the city' combat=78
|
||||
[678] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[679] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[680] name='Og' desc='The chieftan of this ogre tribe' combat=78
|
||||
[681] name='Grew' desc='The chieftan of this ogre tribe' combat=78
|
||||
[682] name='Toban' desc='The chieftan of this ogre tribe' combat=78
|
||||
[683] name='Gorad' desc='A high ranking ogre official' combat=78
|
||||
[684] name='Ogre guard' desc='this creature looks very tough' combat=96
|
||||
[685] name='Yanille Watchman' desc='A captured guard of Yanille' combat=33
|
||||
[686] name='Ogre merchant' desc='He sells ogre-inspired items' combat=58
|
||||
[687] name='Ogre trader' desc='He trades in metals' combat=58
|
||||
[688] name='Ogre trader' desc='He trades in food' combat=58
|
||||
[689] name='Ogre trader' desc='He trades in food' combat=58
|
||||
[690] name='Mercenary' desc='He seems to be guarding an area' combat=39
|
||||
[691] name='City Guard' desc='high ranking ogre guards' combat=78
|
||||
[692] name='Mercenary' desc='He seems to be guarding this area' combat=39
|
||||
[693] name='Lawgof' desc='He guards the mines' combat=18
|
||||
[694] name='Dwarf' desc='A short angry guy' combat=18
|
||||
[695] name='lollk' desc='He looks scared' combat=18
|
||||
[696] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[697] name='Ogre guard' desc='These ogres protect the city' combat=78
|
||||
[698] name='Nulodion' desc='He's the head of black guard weapon development' combat=18
|
||||
[699] name='Dwarf' desc='A short angry guy' combat=18
|
||||
[700] name='Al Shabim' desc='The leader of a nomadic Bedabin desert people - sometimes referred to as the 'Tenti's'' combat=0
|
||||
[701] name='Bedabin Nomad' desc='A Bedabin nomad - they live in the harshest extremes in the desert' combat=0
|
||||
[702] name='Captain Siad' desc='He's in control of the whole mining camp.' combat=48
|
||||
[703] name='Bedabin Nomad Guard' desc='A Bedabin nomad guard - he's protecting something important' combat=70
|
||||
[704] name='Ogre citizen' desc='A denizen of Gu'Tanoth' combat=58
|
||||
[705] name='Rock of ages' desc='A huge boulder' combat=150
|
||||
[706] name='Ogre' desc='A large dim looking humanoid' combat=58
|
||||
[707] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[708] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[709] name='Skavid' desc='Servant race to the ogres' combat=3
|
||||
[710] name='Draft Mercenary Guard' desc='He's quickly drafted in to deal with trouble makers' combat=50
|
||||
[711] name='Mining Cart Driver' desc='He drives the mining cart' combat=15
|
||||
[712] name='kolodion' desc='He runs the mage arena' combat=12
|
||||
[713] name='kolodion' desc='He runs the mage arena' combat=12
|
||||
[714] name='Gertrude' desc='A busy housewife' combat=20
|
||||
[715] name='Shilop' desc='A young boisterous looking lad' combat=0
|
||||
[716] name='Rowdy Guard' desc='He looks as if he's spoiling for trouble' combat=50
|
||||
[717] name='Shantay Pass Guard' desc='He seems to be guarding the Shantay Pass' combat=32
|
||||
[718] name='Rowdy Slave' desc='A slave who's looking for trouble.' combat=16
|
||||
[719] name='Shantay Pass Guard' desc='He seems to be guarding the Shantay Pass' combat=32
|
||||
[720] name='Assistant' desc='He is an assistant to Shantay and helps him to run the pass.' combat=0
|
||||
[721] name='Desert Wolf' desc='A vicious Desert wolf' combat=31
|
||||
[722] name='Workman' desc='This person is working on the site' combat=9
|
||||
[723] name='Examiner' desc='As you examine the examiner you examine that she is indeed an examiner!!' combat=2
|
||||
[724] name='Student' desc='A student busily digging!' combat=0
|
||||
[725] name='Student' desc='A student busily digging!' combat=20
|
||||
[726] name='Guide' desc='This person specialises in panning for gold' combat=12
|
||||
[727] name='Student' desc='A student busily digging!' combat=18
|
||||
[728] name='Archaeological expert' desc='An expert on archaeology!' combat=15
|
||||
[729] name='civillian' desc='He looks aggitated!' combat=18
|
||||
[730] name='civillian' desc='She looks aggitated!' combat=0
|
||||
[731] name='civillian' desc='She looks aggitated!' combat=0
|
||||
[732] name='civillian' desc='He looks aggitated!' combat=15
|
||||
[733] name='Murphy' desc='The man in charge of the fishing trawler' combat=15
|
||||
[734] name='Murphy' desc='The man in charge of the fishing trawler' combat=15
|
||||
[735] name='Sir Radimus Erkle' desc='A huge muscular man in charge of the Legends Guild' combat=10
|
||||
[736] name='Legends Guild Guard' desc='This guard is protecting the entrance to the Legends Guild.' combat=50
|
||||
[737] name='Escaping Mining Slave' desc='An emancipated slave with cool Desert Clothes.' combat=16
|
||||
[738] name='Workman' desc='This person is working in the mine' combat=9
|
||||
[739] name='Murphy' desc='The man in charge of the fishing trawler' combat=15
|
||||
[740] name='Echned Zekin' desc='An evil spirit of the underworld.' combat=50
|
||||
[741] name='Donovan the Handyman' desc='It's the family odd jobs man' combat=9
|
||||
[742] name='Pierre the Dog Handler' desc='It's the guy who looks after the family guard dog' combat=9
|
||||
[743] name='Hobbes the Butler' desc='It's the family butler' combat=9
|
||||
[744] name='Louisa The Cook' desc='It's the family cook' combat=0
|
||||
[745] name='Mary The Maid' desc='The family maid' combat=25
|
||||
[746] name='Stanford The Gardener' desc='It's the family Gardener' combat=8
|
||||
[747] name='Guard' desc='He looks like he's in over his head here' combat=28
|
||||
[748] name='Guard Dog' desc='He doesn't seem pleased to see me' combat=46
|
||||
[749] name='Guard' desc='***EMPTY PLEASE USE OR REPLACE***' combat=8
|
||||
[750] name='Man' desc='A thirsty looking man' combat=9
|
||||
[751] name='Anna Sinclair' desc='The first child of the late Lord Sinclair' combat=9
|
||||
[752] name='Bob Sinclair' desc='The second child of the late Lord Sinclair' combat=9
|
||||
[753] name='Carol Sinclair' desc='The third child of the late Lord Sinclair' combat=9
|
||||
[754] name='David Sinclair' desc='The fourth child of the late Lord Sinclair' combat=9
|
||||
[755] name='Elizabeth Sinclair' desc='The fifth child of the late Lord Sinclair' combat=9
|
||||
[756] name='Frank Sinclair' desc='The sixth child of the late Lord Sinclair' combat=9
|
||||
[757] name='kolodion' desc='He's a shape shifter' combat=65
|
||||
[758] name='kolodion' desc='He's a shape shifter' combat=68
|
||||
[759] name='kolodion' desc='He's a shape shifter' combat=46
|
||||
[760] name='kolodion' desc='He's a shape shifter' combat=98
|
||||
[761] name='Irvig Senay' desc='The animated spirit of Irvig Senay' combat=125
|
||||
[762] name='Ranalph Devere' desc='The animated spirit of Ranalph Devere' combat=130
|
||||
[763] name='Poison Salesman' desc='Peter Potter - Poison Purveyor' combat=7
|
||||
[764] name='Gujuo' desc='A tall charismatic looking jungle native - he approaches with confidence' combat=60
|
||||
[765] name='Jungle Forester' desc='A woodsman who specialises in large and exotic timber' combat=15
|
||||
[766] name='Ungadulu' desc='An ancient looking Shaman' combat=75
|
||||
[767] name='Ungadulu' desc='An ancient looking Shaman - he looks very strange with glowing red eyes...' combat=75
|
||||
[768] name='Death Wing' desc='A supernatural creature of the underworld' combat=80
|
||||
[769] name='Nezikchened' desc='An ancient powerful Demon of the Underworld...' combat=172
|
||||
[770] name='Dwarf Cannon engineer' desc='He's the head of black guard weapon development' combat=18
|
||||
[771] name='Dwarf commander' desc='He guards the mines' combat=18
|
||||
[772] name='Viyeldi' desc='The spirit of a dead sorcerer' combat=80
|
||||
[773] name='Nurmof' desc='He sells pickaxes' combat=18
|
||||
[774] name='Fatigue expert' desc='He looks wide awake' combat=10
|
||||
[775] name='Karamja Wolf' desc='A hungry' combat=61
|
||||
[776] name='Jungle Savage' desc='A savage and fearless Jungle warrior' combat=87
|
||||
[777] name='Oomlie Bird' desc='A variety of flightless jungle fowl - it has a sharp beak and a bad temper.' combat=32
|
||||
[778] name='Sidney Smith' desc='Sidney Smith - Certification clerk' combat=30
|
||||
[779] name='Siegfried Erkle' desc='An eccentric shop keeper - related to the Grand Vizier of the Legends Guild' combat=25
|
||||
[780] name='Tea seller' desc='He has delicious tea to buy' combat=9
|
||||
[781] name='Wilough' desc='A young son of gertrudes' combat=0
|
||||
[782] name='Philop' desc='Gertrudes youngest' combat=0
|
||||
[783] name='Kanel' desc='Gertrudes youngest's twin brother' combat=0
|
||||
[784] name='chamber guardian' desc='He hasn't seen much sun latley' combat=15
|
||||
[785] name='Sir Radimus Erkle' desc='A huge muscular man in charge of the Legends Guild' combat=10
|
||||
[786] name='Pit Scorpion' desc='Very vicious little scorpions' combat=35
|
||||
[787] name='Shadow Warrior' desc='A sinsistar shadowy figure' combat=64
|
||||
[788] name='Fionella' desc='She runs the legend's general store' combat=25
|
||||
[789] name='Battle mage' desc='He kills in the name of guthix' combat=52
|
||||
[790] name='Battle mage' desc='He kills in the name of zamarok' combat=52
|
||||
[791] name='Battle mage' desc='He kills in the name of Saradomin' combat=52
|
||||
[792] name='Gundai' desc='He must get lonely out here' combat=15
|
||||
[793] name='Lundail' desc='He sells rune stones' combat=15
|
||||
@@ -0,0 +1,14 @@
|
||||
[0] name='Thick skin' desc='Increases your defense by 5%' req='1' drain=15
|
||||
[1] name='Burst of strength' desc='Increases your strength by 5%' req='4' drain=15
|
||||
[2] name='Clarity of thought' desc='Increases your attack by 5%' req='7' drain=15
|
||||
[3] name='Rock skin' desc='Increases your defense by 10%' req='10' drain=30
|
||||
[4] name='Superhuman strength' desc='Increases your strength by 10%' req='13' drain=30
|
||||
[5] name='Improved reflexes' desc='Increases your attack by 10%' req='16' drain=30
|
||||
[6] name='Rapid restore' desc='2x restore rate for all stats except hits' req='19' drain=5
|
||||
[7] name='Rapid heal' desc='2x restore rate for hitpoints stat' req='22' drain=10
|
||||
[8] name='Protect items' desc='Keep 1 extra item if you die' req='25' drain=10
|
||||
[9] name='Steel skin' desc='Increases your defense by 15%' req='28' drain=60
|
||||
[10] name='Ultimate strength' desc='Increases your strength by 15%' req='31' drain=60
|
||||
[11] name='Incredible reflexes' desc='Increases your attack by 15%' req='34' drain=60
|
||||
[12] name='Paralyze monster' desc='Stops monsters from fighting back' req='37' drain=60
|
||||
[13] name='Protect from missiles' desc='100% protection from ranged attack' req='40' drain=60
|
||||
@@ -0,0 +1,18 @@
|
||||
[0] name='Attack'
|
||||
[1] name='Defence'
|
||||
[2] name='Strength'
|
||||
[3] name='Hits'
|
||||
[4] name='Ranged'
|
||||
[5] name='Prayer'
|
||||
[6] name='Magic'
|
||||
[7] name='Cooking'
|
||||
[8] name='Woodcut'
|
||||
[9] name='Fletching'
|
||||
[10] name='Fishing'
|
||||
[11] name='Firemaking'
|
||||
[12] name='Crafting'
|
||||
[13] name='Smithing'
|
||||
[14] name='Mining'
|
||||
[15] name='Herblaw'
|
||||
[16] name='Agility'
|
||||
[17] name='Thieving'
|
||||
@@ -0,0 +1,48 @@
|
||||
[0] name='Wind strike' desc='A strength 1 missile attack' req='1'
|
||||
[1] name='Confuse' desc='Reduces your opponents attack by 5%' req='3'
|
||||
[2] name='Water strike' desc='A strength 2 missile attack' req='5'
|
||||
[3] name='Enchant lvl-1 amulet' desc='For use on sapphire amulets' req='7'
|
||||
[4] name='Earth strike' desc='A strength 3 missile attack' req='9'
|
||||
[5] name='Weaken' desc='Reduces your opponents strength by 5%' req='11'
|
||||
[6] name='Fire strike' desc='A strength 4 missile attack' req='13'
|
||||
[7] name='Bones to bananas' desc='Changes all held bones into bananas!' req='15'
|
||||
[8] name='Wind bolt' desc='A strength 5 missile attack' req='17'
|
||||
[9] name='Curse' desc='Reduces your opponents defense by 5%' req='19'
|
||||
[10] name='Low level alchemy' desc='Converts an item into gold' req='21'
|
||||
[11] name='Water bolt' desc='A strength 6 missile attack' req='23'
|
||||
[12] name='Varrock teleport' desc='Teleports you to Varrock' req='25'
|
||||
[13] name='Enchant lvl-2 amulet' desc='For use on emerald amulets' req='27'
|
||||
[14] name='Earth bolt' desc='A strength 7 missile attack' req='29'
|
||||
[15] name='Lumbridge teleport' desc='Teleports you to Lumbridge' req='31'
|
||||
[16] name='Telekinetic grab' desc='Take an item you can see but can't reach' req='33'
|
||||
[17] name='Fire bolt' desc='A strength 8 missile attack' req='35'
|
||||
[18] name='Falador teleport' desc='Teleports you to Falador' req='37'
|
||||
[19] name='Crumble undead' desc='Hits skeleton, ghosts & zombies hard!' req='39'
|
||||
[20] name='Wind blast' desc='A strength 9 missile attack' req='41'
|
||||
[21] name='Superheat item' desc='Smelt 1 ore without a furnace' req='43'
|
||||
[22] name='Camelot teleport' desc='Teleports you to Camelot' req='45'
|
||||
[23] name='Water blast' desc='A strength 10 missile attack' req='47'
|
||||
[24] name='Enchant lvl-3 amulet' desc='For use on ruby amulets' req='49'
|
||||
[25] name='Iban blast' desc='A strength 25 missile attack!' req='50'
|
||||
[26] name='Ardougne teleport' desc='Teleports you to Ardougne' req='51'
|
||||
[27] name='Earth blast' desc='A strength 11 missile attack' req='53'
|
||||
[28] name='High level alchemy' desc='Convert an item into more gold' req='55'
|
||||
[29] name='Charge Water Orb' desc='Needs to be cast on a water obelisk' req='56'
|
||||
[30] name='Enchant lvl-4 amulet' desc='For use on diamond amulets' req='57'
|
||||
[31] name='Watchtower teleport' desc='Teleports you to the watchtower' req='58'
|
||||
[32] name='Fire blast' desc='A strength 12 missile attack' req='59'
|
||||
[33] name='Claws of Guthix' desc='Summons the power of Guthix' req='60'
|
||||
[34] name='Saradomin strike' desc='Summons the power of Saradomin' req='60'
|
||||
[35] name='Flames of Zamorak' desc='Summons the power of Zamorak' req='60'
|
||||
[36] name='Charge earth Orb' desc='Needs to be cast on an earth obelisk' req='60'
|
||||
[37] name='Wind wave' desc='A strength 13 missile attack' req='62'
|
||||
[38] name='Charge Fire Orb' desc='Needs to be cast on a fire obelisk' req='63'
|
||||
[39] name='Water wave' desc='A strength 14 missile attack' req='65'
|
||||
[40] name='Charge air Orb' desc='Needs to be cast on an air obelisk' req='66'
|
||||
[41] name='Vulnerability' desc='Reduces your opponents defense by 10%' req='66'
|
||||
[42] name='Enchant lvl-5 amulet' desc='For use on dragonstone amulets' req='68'
|
||||
[43] name='Earth wave' desc='A strength 15 missile attack' req='70'
|
||||
[44] name='Enfeeble' desc='Reduces your opponents strength by 10%' req='73'
|
||||
[45] name='Fire wave' desc='A strength 16 missile attack' req='75'
|
||||
[46] name='Stun' desc='Reduces your opponents attack by 10%' req='80'
|
||||
[47] name='Charge' desc='Increase your mage arena spells damage' req='80'
|
||||
@@ -0,0 +1,214 @@
|
||||
[0] name='Wall' desc='' cmd='WalkTo'
|
||||
[1] name='Doorframe' desc='' cmd='WalkTo'
|
||||
[2] name='Door' desc='The door is shut' cmd='Open'
|
||||
[3] name='Window' desc='' cmd='WalkTo'
|
||||
[4] name='Fence' desc='' cmd='WalkTo'
|
||||
[5] name='railings' desc='' cmd='WalkTo'
|
||||
[6] name='Stained glass window' desc='' cmd='WalkTo'
|
||||
[7] name='Highwall' desc='' cmd='WalkTo'
|
||||
[8] name='Door' desc='The door is shut' cmd='Open'
|
||||
[9] name='Doorframe' desc='' cmd='WalkTo'
|
||||
[10] name='battlement' desc='' cmd='WalkTo'
|
||||
[11] name='Doorframe' desc='' cmd='WalkTo'
|
||||
[12] name='snowwall' desc='' cmd='WalkTo'
|
||||
[13] name='arrowslit' desc='' cmd='WalkTo'
|
||||
[14] name='timberwall' desc='' cmd='WalkTo'
|
||||
[15] name='timberwindow' desc='' cmd='WalkTo'
|
||||
[16] name='blank' desc='' cmd='WalkTo'
|
||||
[17] name='highblank' desc='' cmd='WalkTo'
|
||||
[18] name='mossybricks' desc='' cmd='WalkTo'
|
||||
[19] name='Door' desc='The door is shut' cmd='Open'
|
||||
[20] name='Door' desc='The door is shut' cmd='Open'
|
||||
[21] name='Door' desc='The door is shut' cmd='Open'
|
||||
[22] name='Odd looking wall' desc='This wall doesn't look quite right' cmd='Push'
|
||||
[23] name='Door' desc='The door is shut' cmd='Open'
|
||||
[24] name='web' desc='A spider's web' cmd='WalkTo'
|
||||
[25] name='Door' desc='The door is shut' cmd='Open'
|
||||
[26] name='Door' desc='The door is shut' cmd='Open'
|
||||
[27] name='Door' desc='The door is shut' cmd='Open'
|
||||
[28] name='Door' desc='The door is shut' cmd='Open'
|
||||
[29] name='Door' desc='The door is shut' cmd='Open'
|
||||
[30] name='Door' desc='The door is shut' cmd='Open'
|
||||
[31] name='Door' desc='The door is shut' cmd='Open'
|
||||
[32] name='Door' desc='The door is shut' cmd='Open'
|
||||
[33] name='Door' desc='The door is shut' cmd='Open'
|
||||
[34] name='Window' desc='' cmd='WalkTo'
|
||||
[35] name='Door' desc='The door is shut' cmd='Open'
|
||||
[36] name='Door' desc='The door is shut' cmd='Open'
|
||||
[37] name='Door' desc='The door is shut' cmd='Open'
|
||||
[38] name='Door' desc='The door is shut' cmd='Open'
|
||||
[39] name='Door' desc='The door is shut' cmd='Open'
|
||||
[40] name='Door' desc='The door is shut' cmd='Open'
|
||||
[41] name='Crumbled' desc='' cmd='WalkTo'
|
||||
[42] name='Cavern' desc='' cmd='WalkTo'
|
||||
[43] name='Door' desc='The door is shut' cmd='Open'
|
||||
[44] name='Door' desc='The door is shut' cmd='Open'
|
||||
[45] name='Door' desc='The door is shut' cmd='Open'
|
||||
[46] name='cavern2' desc='' cmd='WalkTo'
|
||||
[47] name='Door' desc='The door is shut' cmd='Open'
|
||||
[48] name='Door' desc='The door is shut' cmd='Open'
|
||||
[49] name='Door' desc='The door is shut' cmd='Open'
|
||||
[50] name='Door' desc='The door is shut' cmd='Open'
|
||||
[51] name='Door' desc='The door is shut' cmd='Open'
|
||||
[52] name='Door' desc='The door is shut' cmd='Open'
|
||||
[53] name='Door' desc='The door is shut' cmd='Open'
|
||||
[54] name='Door' desc='The door is shut' cmd='Open'
|
||||
[55] name='Door' desc='The door is shut' cmd='Open'
|
||||
[56] name='Wall' desc='' cmd='WalkTo'
|
||||
[57] name='Door' desc='The door is shut' cmd='Open'
|
||||
[58] name='Strange looking wall' desc='This wall doesn't look quite right' cmd='Push'
|
||||
[59] name='Door' desc='The door is shut' cmd='Open'
|
||||
[60] name='Door' desc='The door is shut' cmd='Open'
|
||||
[61] name='Door' desc='The door is shut' cmd='Open'
|
||||
[62] name='memberrailings' desc='' cmd='WalkTo'
|
||||
[63] name='Door' desc='The door is shut' cmd='Open'
|
||||
[64] name='Door' desc='The door is shut' cmd='Open'
|
||||
[65] name='Magic Door' desc='The door is shut' cmd='Open'
|
||||
[66] name='Door' desc='The door is shut' cmd='Open'
|
||||
[67] name='Door' desc='The door is shut' cmd='Open'
|
||||
[68] name='Door' desc='The door is shut' cmd='Open'
|
||||
[69] name='Door' desc='The door is shut' cmd='Open'
|
||||
[70] name='Door' desc='The door is shut' cmd='Open'
|
||||
[71] name='Door' desc='The door is shut' cmd='Open'
|
||||
[72] name='Door' desc='The door is shut' cmd='Open'
|
||||
[73] name='Door' desc='The door is shut' cmd='Open'
|
||||
[74] name='Door' desc='The door is shut' cmd='Open'
|
||||
[75] name='Door' desc='The door is shut' cmd='Open'
|
||||
[76] name='Door' desc='The door is shut' cmd='Open'
|
||||
[77] name='Door' desc='The door is shut' cmd='Open'
|
||||
[78] name='Door' desc='The door is shut' cmd='Open'
|
||||
[79] name='Strange Panel' desc='This wall doesn't look quite right' cmd='Push'
|
||||
[80] name='Door' desc='The door is shut' cmd='Open'
|
||||
[81] name='Door' desc='The door is shut' cmd='Open'
|
||||
[82] name='Door' desc='The door is shut' cmd='Open'
|
||||
[83] name='Door' desc='The door is shut' cmd='Open'
|
||||
[84] name='Door' desc='The door is shut' cmd='Open'
|
||||
[85] name='Door' desc='The door is shut' cmd='Open'
|
||||
[86] name='blockblank' desc='' cmd='WalkTo'
|
||||
[87] name='unusual looking wall' desc='This wall doesn't look quite right' cmd='Push'
|
||||
[88] name='Door' desc='The door is shut' cmd='Open'
|
||||
[89] name='Door' desc='The door is shut' cmd='Open'
|
||||
[90] name='Door' desc='The door is shut' cmd='Open'
|
||||
[91] name='Door' desc='The door is shut' cmd='Open'
|
||||
[92] name='Door' desc='The door is shut' cmd='Open'
|
||||
[93] name='Door' desc='The door is shut' cmd='Open'
|
||||
[94] name='Door' desc='The door is shut' cmd='Open'
|
||||
[95] name='Door' desc='The door is shut' cmd='Open'
|
||||
[96] name='Door' desc='The door is shut' cmd='Open'
|
||||
[97] name='Door' desc='The door is shut' cmd='Open'
|
||||
[98] name='Door' desc='The door is shut' cmd='Open'
|
||||
[99] name='Door' desc='The door is shut' cmd='Open'
|
||||
[100] name='Door' desc='The door is shut' cmd='Open'
|
||||
[101] name='Fence with loose pannels' desc='I wonder if I could get through this' cmd='push'
|
||||
[102] name='Door' desc='The door is shut' cmd='Open'
|
||||
[103] name='Door' desc='The door is shut' cmd='Open'
|
||||
[104] name='Door' desc='The door is shut' cmd='Open'
|
||||
[105] name='Door' desc='The door is shut' cmd='Open'
|
||||
[106] name='Door' desc='The door is shut' cmd='Open'
|
||||
[107] name='Door' desc='The door is shut' cmd='Open'
|
||||
[108] name='Door' desc='The door is shut' cmd='Open'
|
||||
[109] name='Door' desc='The door is shut' cmd='Open'
|
||||
[110] name='Door' desc='The door is shut' cmd='Open'
|
||||
[111] name='rat cage' desc='The rat's have damaged the bars' cmd='search'
|
||||
[112] name='Door' desc='The door is shut' cmd='Open'
|
||||
[113] name='Door' desc='The door is shut' cmd='Open'
|
||||
[114] name='Door' desc='The door is shut' cmd='Open'
|
||||
[115] name='Door' desc='The door is shut' cmd='Open'
|
||||
[116] name='Door' desc='The door is shut' cmd='Open'
|
||||
[117] name='Door' desc='The door is shut' cmd='Open'
|
||||
[118] name='arrowslit' desc='' cmd='WalkTo'
|
||||
[119] name='solidblank' desc='' cmd='WalkTo'
|
||||
[120] name='Door' desc='The door is shut' cmd='Open'
|
||||
[121] name='Door' desc='The door is shut' cmd='Open'
|
||||
[122] name='Door' desc='The door is shut' cmd='Open'
|
||||
[123] name='Door' desc='The door is shut' cmd='Open'
|
||||
[124] name='loose panel' desc='The panel has worn with age' cmd='break'
|
||||
[125] name='Door' desc='The door is shut' cmd='Open'
|
||||
[126] name='plankswindow' desc='' cmd='WalkTo'
|
||||
[127] name='Low Fence' desc='' cmd='WalkTo'
|
||||
[128] name='Door' desc='The door is shut' cmd='Open'
|
||||
[129] name='Door' desc='The door is shut' cmd='Open'
|
||||
[130] name='Door' desc='The door is shut' cmd='Open'
|
||||
[131] name='Door' desc='The door is shut' cmd='Open'
|
||||
[132] name='Door' desc='The door is shut' cmd='Open'
|
||||
[133] name='Door' desc='The door is shut' cmd='Open'
|
||||
[134] name='Door' desc='The door is shut' cmd='Open'
|
||||
[135] name='Door' desc='The door is shut' cmd='Open'
|
||||
[136] name='Door' desc='The door is shut' cmd='Open'
|
||||
[137] name='Cooking pot' desc='Smells good!' cmd='WalkTo'
|
||||
[138] name='Door' desc='The door is shut' cmd='Open'
|
||||
[139] name='Door' desc='The door is shut' cmd='Open'
|
||||
[140] name='Door' desc='The door is shut' cmd='Open'
|
||||
[141] name='Door' desc='The door is shut' cmd='Open'
|
||||
[142] name='Door' desc='The door is shut' cmd='Open'
|
||||
[143] name='Door' desc='The door is shut' cmd='Open'
|
||||
[144] name='plankstimber' desc='' cmd='WalkTo'
|
||||
[145] name='Door' desc='The door is shut' cmd='Open'
|
||||
[146] name='Door' desc='The door is shut' cmd='Open'
|
||||
[147] name='magic portal' desc='' cmd='enter'
|
||||
[148] name='magic portal' desc='' cmd='enter'
|
||||
[149] name='magic portal' desc='' cmd='enter'
|
||||
[150] name='Door' desc='The door is shut' cmd='Open'
|
||||
[151] name='Cavern wall' desc='It looks as if it is covered in some fungus.' cmd='WalkTo'
|
||||
[152] name='Door' desc='The door is shut' cmd='Open'
|
||||
[153] name='Door' desc='the door is shut' cmd='walk through'
|
||||
[154] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[155] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[156] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[157] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[158] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[159] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[160] name='Door' desc='The door is shut' cmd='walk through'
|
||||
[161] name='Door' desc='The door is shut' cmd='Open'
|
||||
[162] name='Door' desc='The door is shut' cmd='Open'
|
||||
[163] name='Low wall' desc='' cmd='jump'
|
||||
[164] name='Low wall' desc='' cmd='jump'
|
||||
[165] name='Blacksmiths Door' desc='The door is shut' cmd='Open'
|
||||
[166] name='railings' desc='' cmd='pick lock'
|
||||
[167] name='railings' desc='' cmd='pick lock'
|
||||
[168] name='railings' desc='' cmd='pick lock'
|
||||
[169] name='railings' desc='' cmd='pick lock'
|
||||
[170] name='railings' desc='' cmd='pick lock'
|
||||
[171] name='railings' desc='' cmd='WalkTo'
|
||||
[172] name='railings' desc='' cmd='WalkTo'
|
||||
[173] name='Door' desc='The door is shut' cmd='Open'
|
||||
[174] name='Doorframe' desc='' cmd='WalkTo'
|
||||
[175] name='Tent' desc='' cmd='WalkTo'
|
||||
[176] name='Jail Door' desc='The door is shut' cmd='Open'
|
||||
[177] name='Jail Door' desc='The door is shut' cmd='Open'
|
||||
[178] name='Window' desc='A barred window' cmd='WalkTo'
|
||||
[179] name='magic portal' desc='A magical barrier shimmers with power' cmd='WalkTo'
|
||||
[180] name='Jail Door' desc='A solid iron gate' cmd='Open'
|
||||
[181] name='railings' desc='' cmd='WalkTo'
|
||||
[182] name='railings' desc='' cmd='WalkTo'
|
||||
[183] name='railings' desc='' cmd='WalkTo'
|
||||
[184] name='railings' desc='' cmd='WalkTo'
|
||||
[185] name='railings' desc='' cmd='WalkTo'
|
||||
[186] name='railings' desc='' cmd='WalkTo'
|
||||
[187] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[188] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[189] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[190] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[191] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[192] name='Cave exit' desc='The way out' cmd='Leave'
|
||||
[193] name='railings' desc='' cmd='WalkTo'
|
||||
[194] name='Door' desc='The door is shut' cmd='Open'
|
||||
[195] name='battlement' desc='This is blocking your path' cmd='Climb-over'
|
||||
[196] name='Tent Door' desc='An entrance into the tent' cmd='Go through'
|
||||
[197] name='Door' desc='The door is shut' cmd='Open'
|
||||
[198] name='Tent Door' desc='An entrance into the tent' cmd='Go through'
|
||||
[199] name='Low Fence' desc='A damaged wooden fence' cmd='search'
|
||||
[200] name='Sturdy Iron Gate' desc='A solid iron gate' cmd='Open'
|
||||
[201] name='battlement' desc='this low wall blocks your path' cmd='climb over'
|
||||
[202] name='Water' desc='My waterfall boundary!' cmd='WalkTo'
|
||||
[203] name='Wheat' desc='Test Boundary!' cmd='WalkTo'
|
||||
[204] name='Jungle' desc='Thick inpenetrable jungle' cmd='Chop'
|
||||
[205] name='Window' desc='you can see a vicious looking guard dog right outside' cmd='Investigate'
|
||||
[206] name='Rut' desc='Looks like a small rut carved into the ground.' cmd='WalkTo'
|
||||
[207] name='Crumbled Cavern 1' desc='' cmd='WalkTo'
|
||||
[208] name='Crumbled Cavern 2' desc='' cmd='WalkTo'
|
||||
[209] name='cavernhole' desc='' cmd='WalkTo'
|
||||
[210] name='flamewall' desc='A supernatural fire of incredible intensity' cmd='Touch'
|
||||
[211] name='Ruined wall' desc='Some ancient wall structure - it doesn't look too high.' cmd='WalkTo'
|
||||
[212] name='Ancient Wall' desc='An ancient - slightly higher wall with some strange markings on it' cmd='Use'
|
||||
[213] name='Door' desc='The door is shut' cmd='Open'
|
||||
|
After Width: | Height: | Size: 904 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,137 @@
|
||||
import com.aposbot._default.IAutoLogin;
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot.Constants;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class AutoLogin
|
||||
implements IAutoLogin {
|
||||
|
||||
private static final AutoLogin instance = new AutoLogin();
|
||||
private IClient c;
|
||||
private boolean enabled;
|
||||
private String username;
|
||||
private String password;
|
||||
private boolean loaded;
|
||||
private volatile boolean banned;
|
||||
private long next_attempt;
|
||||
|
||||
private AutoLogin() {
|
||||
}
|
||||
|
||||
static void init(IClient client) {
|
||||
instance.c = client;
|
||||
}
|
||||
|
||||
public static boolean isAutoLogin() {
|
||||
return instance.isEnabled();
|
||||
}
|
||||
|
||||
public static void setAutoLogin(boolean b) {
|
||||
instance.setEnabled(b);
|
||||
}
|
||||
|
||||
public static void setCredentials(String username, String password) {
|
||||
instance.setAccount(username, password);
|
||||
}
|
||||
|
||||
public static void onLoginResponse(String arg0, String arg1) {
|
||||
String message = arg0 + " " + arg1;
|
||||
System.out.println(message);
|
||||
message = message.toLowerCase(Locale.ENGLISH);
|
||||
if (message.contains("updated")) {
|
||||
System.out.println("Looks like APOS is out of date. Wait patiently for an update to be released on the forums.");
|
||||
instance.next_attempt = Long.MAX_VALUE;
|
||||
} else if (message.contains("member") ||
|
||||
message.contains("stolen") ||
|
||||
message.contains("locked") ||
|
||||
message.contains("banned") ||
|
||||
message.contains("customer support") ||
|
||||
message.contains("new players") ||
|
||||
message.contains("cannot access") ||
|
||||
message.contains("disabled")) {
|
||||
System.out.println("Autologin has been infinitely delayed due to an apparent fatal problem. If you've managed to solve that problem, re-enable it.");
|
||||
instance.next_attempt = Long.MAX_VALUE;
|
||||
} else {
|
||||
instance.next_attempt = System.currentTimeMillis() + 4000L + Constants.RANDOM.nextInt(8000);
|
||||
}
|
||||
}
|
||||
|
||||
public static void loginTick() {
|
||||
instance.onLoginTick();
|
||||
}
|
||||
|
||||
public static void checkForLog() {
|
||||
loginTick();
|
||||
}
|
||||
|
||||
public static void welcomeBoxTick() {
|
||||
instance.onWelcomeBoxTick();
|
||||
}
|
||||
|
||||
static final AutoLogin get() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginTick() {
|
||||
if (banned) return;
|
||||
|
||||
if (System.currentTimeMillis() < next_attempt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
String font = ClientInit.getBotLoader().getFont();
|
||||
if (font != null) {
|
||||
System.out.println("Setting font to " + font);
|
||||
c.setFont(font);
|
||||
}
|
||||
StaticAccess.setStrings();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
if (enabled && username != null) {
|
||||
final int len = password.length();
|
||||
final StringBuilder b = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
b.append('*');
|
||||
}
|
||||
System.out.println("Logging in: " + username + " " + b.toString());
|
||||
c.login(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWelcomeBoxTick() {
|
||||
c.onLoggedIn();
|
||||
if (enabled) {
|
||||
System.out.println("Closing welcome box.");
|
||||
c.closeWelcomeBox();
|
||||
}
|
||||
PaintListener.resetXp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean b) {
|
||||
enabled = b;
|
||||
if (b) {
|
||||
next_attempt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBanned(boolean b) {
|
||||
banned = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccount(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import com.aposbot.BotFrame;
|
||||
import com.aposbot.BotLoader;
|
||||
import com.aposbot._default.IAutoLogin;
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IClientInit;
|
||||
import com.aposbot._default.IPaintListener;
|
||||
import com.aposbot._default.IScriptListener;
|
||||
import com.aposbot._default.ISleepListener;
|
||||
|
||||
public final class ClientInit
|
||||
implements IClientInit {
|
||||
|
||||
private static BotLoader loader;
|
||||
|
||||
public static void main(String[] argv) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (final Throwable t) {
|
||||
} finally {
|
||||
loader = new BotLoader(argv, new ClientInit());
|
||||
}
|
||||
}
|
||||
|
||||
private ClientInit() {
|
||||
}
|
||||
|
||||
static BotLoader getBotLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClient createClient(BotFrame frame) {
|
||||
client.il[237] = "Welcome to @cya@APOS";
|
||||
final Extension ex = new Extension(frame);
|
||||
ScriptListener.init(ex);
|
||||
AutoLogin.init(ex);
|
||||
PaintListener.init(ex);
|
||||
return ex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAutoLogin getAutoLogin() {
|
||||
return AutoLogin.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISleepListener getSleepListener() {
|
||||
return SleepListener.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScriptListener getScriptListener() {
|
||||
return ScriptListener.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPaintListener getPaintListener() {
|
||||
return PaintListener.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,922 @@
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.script.Invocable;
|
||||
|
||||
import com.aposbot.BotFrame;
|
||||
import com.aposbot._default.IAutoLogin;
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IJokerFOCR;
|
||||
import com.aposbot._default.IPaintListener;
|
||||
import com.aposbot._default.IScript;
|
||||
import com.aposbot._default.IScriptListener;
|
||||
import com.aposbot._default.IStaticAccess;
|
||||
|
||||
public class Extension extends client
|
||||
implements IClient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final BotFrame frame;
|
||||
private boolean disableKeys;
|
||||
|
||||
Extension(BotFrame frame) {
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoggedIn() {
|
||||
frame.enableRenderingToggle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(Wd, Oi + 12);
|
||||
}
|
||||
|
||||
private void paste() {
|
||||
try {
|
||||
Clipboard c = Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard();
|
||||
Transferable t = c.getContents(null);
|
||||
DataFlavor f = DataFlavor.stringFlavor;
|
||||
if (!t.isDataFlavorSupported(f)) {
|
||||
return;
|
||||
}
|
||||
char[] str = ((String)t.getTransferData(f))
|
||||
.toCharArray();
|
||||
for (int i = 0; i < str.length; ++i) {
|
||||
if (str[i] >= ' ' && str[i] <= '~') {
|
||||
typeChar(str[i], str[i]);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Couldn't paste: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
final int keyCode = e.getKeyCode();
|
||||
if (disableKeys) {
|
||||
ScriptListener.get().onKeyPress(keyCode);
|
||||
return;
|
||||
}
|
||||
if ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_V) {
|
||||
paste();
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
setCameraNSOffset(0);
|
||||
setCameraEWOffset(0);
|
||||
setCameraHeight(750);
|
||||
fogginess = 0;
|
||||
break;
|
||||
case KeyEvent.VK_PAGE_UP:
|
||||
setCameraNSOffset(getCameraNSOffset() - 10);
|
||||
break;
|
||||
case KeyEvent.VK_PAGE_DOWN:
|
||||
setCameraNSOffset(getCameraNSOffset() + 10);
|
||||
break;
|
||||
case KeyEvent.VK_HOME:
|
||||
setCameraEWOffset(getCameraEWOffset() + 10);
|
||||
break;
|
||||
case KeyEvent.VK_END:
|
||||
setCameraEWOffset(getCameraEWOffset() - 10);
|
||||
break;
|
||||
case KeyEvent.VK_UP:
|
||||
final int h = getCameraHeight();
|
||||
if (h > 300) {
|
||||
setCameraHeight(h - 10);
|
||||
fogginess -= 30;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_DOWN:
|
||||
setCameraHeight(getCameraHeight() + 10);
|
||||
fogginess += 30;
|
||||
break;
|
||||
case KeyEvent.VK_F12:
|
||||
case KeyEvent.VK_PRINTSCREEN:
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
takeScreenshot(String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
}, "ScreenshotThread").start();
|
||||
break;
|
||||
default:
|
||||
ScriptListener.get().onKeyPress(keyCode);
|
||||
super.keyPressed(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRendering(boolean b) {
|
||||
disable_gfx = !b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRendering() {
|
||||
return !disable_gfx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoLogin(boolean b) {
|
||||
frame.setAutoLogin(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeysDisabled(boolean b) {
|
||||
disableKeys = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScript() {
|
||||
frame.stopScript();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeScreenshot(String fileName) {
|
||||
frame.takeScreenshot(fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServer(int id) {
|
||||
frame.updateWorld(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServer() {
|
||||
return Integer.parseInt(frame.getCodeBase().substring(14, 15));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCameraNSOffset() {
|
||||
return oc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCameraNSOffset(int i) {
|
||||
oc = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCameraEWOffset() {
|
||||
return Be;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCameraEWOffset(int i) {
|
||||
Be = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCameraHeight() {
|
||||
return ac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCameraHeight(int i) {
|
||||
ac = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionInd(int i) {
|
||||
xh = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeWelcomeBox() {
|
||||
Oh = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalX() {
|
||||
return Lf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalY() {
|
||||
return sh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombatTimer() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogoutTimer(int i) {
|
||||
bj = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAreaX() {
|
||||
return Qg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAreaY() {
|
||||
return zg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseLevel(int skill) {
|
||||
return cg[skill];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentLevel(int skill) {
|
||||
return oh[skill];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getExperience(int skill) {
|
||||
return Ak[skill] / 4.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombatStyle() {
|
||||
return Fg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCombatStyle(int i) {
|
||||
Fg = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDialogOptions() {
|
||||
return ah;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogOptionCount() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDialogVisible() {
|
||||
return Ph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDialogVisible(boolean b) {
|
||||
Ph = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSleeping() {
|
||||
return Qk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventorySize() {
|
||||
return lc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryId(int i) {
|
||||
return vf[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStack(int i) {
|
||||
return xe[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBankVisible() {
|
||||
return Fe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBankVisible(boolean b) {
|
||||
Fe = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBankSize() {
|
||||
return vj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBankId(int i) {
|
||||
return ae[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBankStack(int i) {
|
||||
return di[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroundItemCount() {
|
||||
return Ah;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroundItemLocalX(int i) {
|
||||
return Zf[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroundItemLocalY(int i) {
|
||||
return Ni[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroundItemId(int i) {
|
||||
return Gj[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectCount() {
|
||||
return eh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectLocalX(int i) {
|
||||
return Se[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectLocalY(int i) {
|
||||
return ye[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectId(int i) {
|
||||
return vc[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectDir(int i) {
|
||||
return bg[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBoundCount() {
|
||||
return hf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBoundLocalX(int i) {
|
||||
return Jd[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBoundLocalY(int i) {
|
||||
return yk[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBoundDir(int i) {
|
||||
return Hj[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBoundId(int i) {
|
||||
return Ng[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeChar(char key_char, int key_code) {
|
||||
// TODO: keep shift down
|
||||
boolean upper = Character.isUpperCase(key_char);
|
||||
int m = 0;
|
||||
if (upper) {
|
||||
super.keyPressed(new KeyEvent(this,
|
||||
KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
|
||||
0, KeyEvent.VK_SHIFT, KeyEvent.CHAR_UNDEFINED));
|
||||
m |= KeyEvent.VK_SHIFT;
|
||||
}
|
||||
super.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED,
|
||||
System.currentTimeMillis(), m, key_code, key_char));
|
||||
super.keyTyped(new KeyEvent(this, KeyEvent.KEY_TYPED,
|
||||
System.currentTimeMillis(), m,
|
||||
KeyEvent.VK_UNDEFINED, key_char));
|
||||
super.keyReleased(new KeyEvent(this, KeyEvent.KEY_RELEASED,
|
||||
System.currentTimeMillis(), m, key_code, key_char));
|
||||
if (upper) {
|
||||
super.keyReleased(new KeyEvent(this,
|
||||
KeyEvent.KEY_RELEASED, System.currentTimeMillis(),
|
||||
0, KeyEvent.VK_SHIFT, KeyEvent.CHAR_UNDEFINED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShopVisible() {
|
||||
return uk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShopVisible(boolean b) {
|
||||
uk = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getShopSize() {
|
||||
return Rj.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getShopId(int i) {
|
||||
return Rj[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getShopStack(int i) {
|
||||
return Jf[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquipped(int slot) {
|
||||
return Aj[slot] == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrayerEnabled(int id) {
|
||||
return bk[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrayerEnabled(int i, boolean flag) {
|
||||
bk[i] = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInTradeOffer() {
|
||||
return Hk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInTradeOffer(boolean b) {
|
||||
Hk = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInTradeConfirm() {
|
||||
return Xj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInTradeConfirm(boolean b) {
|
||||
Xj = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocalAcceptedTrade() {
|
||||
return Mi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocalConfirmedTrade() {
|
||||
return Vi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRemoteAcceptedTrade() {
|
||||
return md;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalTradeItemCount() {
|
||||
return mf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalTradeItemId(int i) {
|
||||
return Qf[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalTradeItemStack(int i) {
|
||||
return jj[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemoteTradeItemCount() {
|
||||
return Lk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemoteTradeItemId(int i) {
|
||||
return zj[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemoteTradeItemStack(int i) {
|
||||
return Dd[i];
|
||||
}
|
||||
|
||||
private ba getScreen() {
|
||||
return li;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getPixels() {
|
||||
return getScreen().rb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return getScreen().Gb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggedIn() {
|
||||
return getScreen() != null && qg == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[][] getAdjacency() {
|
||||
return Hh.bb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, int x, int y, int font, int colour) {
|
||||
/* use xb so our text has shadows */
|
||||
boolean orig = getScreen().xb;
|
||||
getScreen().xb = true;
|
||||
getScreen().a(str, x, y, colour, false, font);
|
||||
getScreen().xb = orig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayMessage(String str) {
|
||||
a(false, ((String) (null)), 0, str, 7, 0, ((String) (null)), ((String) (null)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offerItemTrade(int slot, int amount) {
|
||||
a(amount, (byte)9, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) {
|
||||
Vh = 2;
|
||||
a(-12, password, username, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walkDirectly(int destLX, int destLY, boolean action) {
|
||||
a(destLY, destLX, sh, Lf, action, 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walkAround(int destLX, int destLY) {
|
||||
a((byte)10, sh, destLY, destLX, true, Lf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walkToBound(int destLX, int destLY, int dir) {
|
||||
a(false, destLX, destLY, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walkToObject(int destLX, int destLY, int dir, int id) {
|
||||
b(5126, id, destLX, destLY, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPacket(int opcode) {
|
||||
Jh.b(opcode, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put1(int val) {
|
||||
Jh.f.c(val, 115);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put2(int val) {
|
||||
Jh.f.e(393, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put4(int val) {
|
||||
Jh.f.b(-422797528, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishPacket() {
|
||||
Jh.b(21294);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCAPTCHA(String str) {
|
||||
Jh.b(45, 0);
|
||||
if (Yk) {
|
||||
Jh.f.c(1, -75);
|
||||
} else {
|
||||
Jh.f.c(0, -100);
|
||||
Yk = true;
|
||||
}
|
||||
Jh.f.a(str, 116);
|
||||
Jh.b(21294);
|
||||
e = "";
|
||||
Zj = il[436];
|
||||
Cb = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSkipLines() {
|
||||
return U;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkipLines(boolean flag) {
|
||||
U = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPrivateMessage(String msg, String name) {
|
||||
name = name.replace(' ', (char)160);
|
||||
x = "";
|
||||
Bj = 0;
|
||||
Ob = "";
|
||||
Qd = name;
|
||||
a((byte)-76, name, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFriend(String str) {
|
||||
str = str.replace(' ', (char)160);
|
||||
Bj = 0;
|
||||
e = "";
|
||||
Cb = "";
|
||||
b(114, str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIgnore(String str) {
|
||||
str = str.replace(' ', (char)160);
|
||||
e = "";
|
||||
Bj = 0;
|
||||
Cb = "";
|
||||
a(str, (byte)5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIgnore(String str) {
|
||||
str = str.replace(' ', (char)160);
|
||||
//a((byte)-15, ia.a[j3]);
|
||||
a((byte)-15, str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriend(String str) {
|
||||
str = str.replace(' ', (char)160);
|
||||
//b(ua.h[i3], (byte)69);
|
||||
b(str, (byte)69);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuestCount() {
|
||||
return Te.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuestName(int i) {
|
||||
return Te[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQuestComplete(int i) {
|
||||
return fi[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFatigue() {
|
||||
return (vg * 100.0) / 750.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getSleepingFatigue() {
|
||||
return (100.0 * pg) / 750.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return Yc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlayer() {
|
||||
return wi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlayer(int index) {
|
||||
return rg[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerName(Object mob) {
|
||||
return ((ta) mob).c.replace((char) 160, ' ');
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCombatLevel(Object mob) {
|
||||
return ((ta) mob).s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNpcCount() {
|
||||
return de;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNpc(int index) {
|
||||
return Tb[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNpcId(Object mob) {
|
||||
return ((ta) mob).t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMobWalking(Object mob) {
|
||||
return ((ta) mob).e != (((ta) mob).o + 1) % 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMobTalking(Object mob) {
|
||||
return ((ta) mob).I > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeadIconVisible(Object mob) {
|
||||
return ((ta) mob).E > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHpBarVisible(Object mob) {
|
||||
return ((ta) mob).d > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobBaseHitpoints(Object mob) {
|
||||
return ((ta) mob).G;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobServerIndex(Object mob) {
|
||||
return ((ta) mob).b;
|
||||
}
|
||||
|
||||
private int getMobLocDivide() {
|
||||
return Ug;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobLocalX(Object mob) {
|
||||
return (((ta) mob).i - 64) / getMobLocDivide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobLocalY(Object mob) {
|
||||
return (((ta) mob).K - 64) / getMobLocDivide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobDirection(Object mob) {
|
||||
return ((ta) mob).y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMobInCombat(Object mob) {
|
||||
final int dir = getMobDirection(mob);
|
||||
return dir == 8 || dir == 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStaticAccess getStatic() {
|
||||
return StaticAccess.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScriptListener getScriptListener() {
|
||||
return ScriptListener.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAutoLogin getAutoLogin() {
|
||||
return AutoLogin.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPaintListener getPaintListener() {
|
||||
return PaintListener.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJokerFOCR getJoker() {
|
||||
return Joker.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScript createInvocableScript(Invocable inv, String name) {
|
||||
return new JavaxScriptInvocable(this, inv, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(String name) {
|
||||
StaticAccess.loadFont(this, "h11p", name, 0);
|
||||
StaticAccess.loadFont(this, "h12b", name, 1);
|
||||
StaticAccess.loadFont(this, "h12p", name, 2);
|
||||
StaticAccess.loadFont(this, "h13b", name, 3);
|
||||
StaticAccess.loadFont(this, "h14b", name, 4);
|
||||
StaticAccess.loadFont(this, "h16b", name, 5);
|
||||
StaticAccess.loadFont(this, "h20b", name, 6);
|
||||
StaticAccess.loadFont(this, "h24b", name, 7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final byte[] a(String s1, int i1, int j1, int k1) {
|
||||
// found in applet class
|
||||
try {
|
||||
J++;
|
||||
return StaticAccess.load(s1, i1, j1);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resizeGame(int width, int height) {
|
||||
Wd = width;
|
||||
Oi = height - 12;
|
||||
|
||||
Rh = width;
|
||||
Hf = height;
|
||||
Eb = (-this.Wd + this.Rh) / 2;
|
||||
K = 0;
|
||||
|
||||
// set raster
|
||||
li.rb = new int[width * height];
|
||||
li.lb = li.u = width;
|
||||
li.Rb = li.k = height;
|
||||
li.fb.setDimensions(width, height);
|
||||
|
||||
/*
|
||||
li.Gb = this.createImage(li);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
li.b(true);
|
||||
this.prepareImage(li.Gb, this);
|
||||
}
|
||||
|
||||
System.out.println(li.Gb.getWidth(null) + " " + li.Gb.getHeight(null));
|
||||
*/
|
||||
|
||||
// set scene
|
||||
Ek.pb = li.rb;
|
||||
Ek.A = width;
|
||||
Ek.wb = height;
|
||||
Ek.a(this.Oi / 2, true, this.Wd, this.Wd / 2, this.Oi / 2, this.qd, this.Wd / 2);
|
||||
|
||||
// make interfaces
|
||||
O(56);
|
||||
|
||||
Mc = new qa(this.li, 5);
|
||||
Ud = Mc.a(this.li.u - 199, 196, 90,
|
||||
true, 106, 500, 24 + 36, 1);
|
||||
|
||||
zk = new qa(this.li, 5);
|
||||
Hi = zk.a(this.li.u - 199, 196, 126,
|
||||
true, 106, 500, 36 + 40, 1);
|
||||
|
||||
fe = new qa(this.li, 5);
|
||||
lk = fe.a(this.li.u - 199, 196, 251,
|
||||
true, 106, 500, 24 + 36, 1);
|
||||
|
||||
if ((width - 73) < 1000) {
|
||||
client.il[262] = String.format(
|
||||
"~%d~@whi@Remove WWWWWWWWWW", width - 73);
|
||||
} else {
|
||||
client.il[262] = "";
|
||||
}
|
||||
|
||||
Xb = getGraphics();
|
||||
//repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGameWidth() {
|
||||
return Wd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGameHeight() {
|
||||
return Oi + 12;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public final class JavaxScriptInvocable extends Script {
|
||||
|
||||
private final Invocable inv;
|
||||
private final String name;
|
||||
|
||||
public JavaxScriptInvocable(Extension ex, Invocable inv, String name) {
|
||||
super(ex);
|
||||
this.inv = inv;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(String params) {
|
||||
try {
|
||||
inv.invokeFunction("init", params);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int main() {
|
||||
try {
|
||||
return looseToInt(inv.invokeFunction("main", this));
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint() {
|
||||
try {
|
||||
inv.invokeFunction("paint", this);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerMessage(String str) {
|
||||
try {
|
||||
inv.invokeFunction("onServerMessage", str);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTradeRequest(String name) {
|
||||
try {
|
||||
inv.invokeFunction("onTradeRequest", name);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChatMessage(String msg, String name, boolean mod,
|
||||
boolean admin) {
|
||||
|
||||
try {
|
||||
inv.invokeFunction("onChatMessage", msg, name, mod, admin);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrivateMessage(String msg, String name, boolean mod,
|
||||
boolean admin) {
|
||||
|
||||
try {
|
||||
inv.invokeFunction("onPrivateMessage", msg, name, mod, admin);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyPress(int keycode) {
|
||||
try {
|
||||
inv.invokeFunction("onKeyPress", keycode);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
} catch (ScriptException ex) {
|
||||
System.out.println(ScriptListener.ERROR_MESSAGE);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final int looseToInt(Object object) {
|
||||
// needlessly excessive?
|
||||
Class<?> c = object.getClass();
|
||||
if (Integer.class.equals(c)) {
|
||||
return ((Integer) object).intValue();
|
||||
} else if (Long.class.equals(c)) {
|
||||
return ((Long) object).intValue();
|
||||
} else if (Short.class.equals(c)) {
|
||||
return ((Short) object).intValue();
|
||||
} else if (Byte.class.equals(c)) {
|
||||
return ((Byte) object).intValue();
|
||||
} else if (Float.class.equals(c)) {
|
||||
return ((Float) object).intValue();
|
||||
} else if (Double.class.equals(c)) {
|
||||
return ((Double) object).intValue();
|
||||
} else if (String.class.equals(c)) {
|
||||
return Integer.parseInt((String) object);
|
||||
} else if (BigInteger.class.equals(c)) {
|
||||
return ((BigInteger) object).intValue();
|
||||
} else if (BigDecimal.class.equals(c)) {
|
||||
return ((BigDecimal) object).intValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import java.io.File;
|
||||
|
||||
import com.aposbot._default.IJokerFOCR;
|
||||
|
||||
public final class Joker
|
||||
implements IJokerFOCR {
|
||||
|
||||
private static final Joker instance = new Joker();
|
||||
private boolean loaded;
|
||||
|
||||
private Joker() {
|
||||
}
|
||||
|
||||
private static native String getSleepWord();
|
||||
|
||||
private static native void initOCR(String file_model, String file_dict);
|
||||
|
||||
private static native void closeOCR();
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closeOCR();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilePaths(String file_model, String file_dict) {
|
||||
initOCR(file_model, file_dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuess() {
|
||||
return getSleepWord();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadNativeLibrary() {
|
||||
try {
|
||||
System.load(new File("." + File.separator + "lib" + File.separator + "Joker.dll").getAbsolutePath());
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error loading Joker/FOCR:");
|
||||
t.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLibraryLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
static final Joker get() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
import java.text.DecimalFormat;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import com.aposbot.RasterOps;
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IPaintListener;
|
||||
|
||||
public final class PaintListener
|
||||
implements IPaintListener {
|
||||
|
||||
public static volatile boolean render_solid = true;
|
||||
public static volatile boolean render_textures = true;
|
||||
|
||||
private static final int BAR_WIDTH = 100;
|
||||
private static final int BAR_HEIGHT = 20;
|
||||
|
||||
private static final int HP_FRONT = 0x3CDC3C;
|
||||
private static final int HP_BACK = 0x3CDC3C;
|
||||
|
||||
private static final int PRAY_FRONT = 0x3CBEDC;
|
||||
private static final int PRAY_BACK = 0x3CBEDC;
|
||||
|
||||
private static final int BOTTOM_GRAY = 0x0A0A03;
|
||||
private static final int BOTTOM_DARK = 0x002831;
|
||||
private static final int BOTTOM_MID = 0x00394A;
|
||||
private static final int BOTTOM_LIGHT = 0x005D7B;
|
||||
|
||||
private static final PaintListener instance = new PaintListener();
|
||||
private final DecimalFormat dformat = new DecimalFormat("#,##0.0#");
|
||||
private IClient client;
|
||||
private boolean enabled = true;
|
||||
private double startingXP;
|
||||
private volatile boolean banned;
|
||||
private Dimension d = new Dimension();
|
||||
private boolean resized = true;
|
||||
|
||||
private PaintListener() {
|
||||
}
|
||||
|
||||
static void init(IClient client) {
|
||||
instance.client = client;
|
||||
}
|
||||
|
||||
public static void paint() {
|
||||
instance.onPaint();
|
||||
}
|
||||
|
||||
public static void resetXp() {
|
||||
instance.resetDisplayedXp();
|
||||
}
|
||||
|
||||
public static void toggle() {
|
||||
instance.setPaintingEnabled(!instance.isPaintingEnabled());
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return instance.isPaintingEnabled();
|
||||
}
|
||||
|
||||
public static void setEnabled(boolean enabled) {
|
||||
instance.setPaintingEnabled(enabled);
|
||||
}
|
||||
|
||||
private void drawStatBar(int x, int y,
|
||||
double current, double base, int front, int back)
|
||||
{
|
||||
int rw = client.getGameWidth();
|
||||
int rh = client.getGameHeight();
|
||||
int[] pixels = client.getPixels();
|
||||
int width = (int)(current / base * BAR_WIDTH);
|
||||
|
||||
y -= (BAR_HEIGHT / 2) + 4;
|
||||
RasterOps.fillRectAlpha(pixels, rw, rh,
|
||||
x, y, width, BAR_HEIGHT,
|
||||
160, front);
|
||||
RasterOps.fillRectAlpha(pixels, rw, rh,
|
||||
x + width, y, BAR_WIDTH - width, BAR_HEIGHT,
|
||||
65, back);
|
||||
}
|
||||
|
||||
private void drawGradient()
|
||||
{
|
||||
int rw = client.getGameWidth();
|
||||
int rh = client.getGameHeight();
|
||||
int[] pixels = client.getPixels();
|
||||
int x = 512;
|
||||
int y = client.getGameHeight() - 13;
|
||||
|
||||
RasterOps.fillRect(pixels, rw, rh, x, y, rw, 1, 0x0);
|
||||
y += 1;
|
||||
RasterOps.fillRect(pixels, rw, rh, x, y, rw, 11, BOTTOM_GRAY);
|
||||
y += 2;
|
||||
RasterOps.fillRect(pixels, rw, rh, x, y, rw, 7, BOTTOM_DARK);
|
||||
y += 1;
|
||||
RasterOps.fillRect(pixels, rw, rh, x, y, rw, 5, BOTTOM_MID);
|
||||
y += 1;
|
||||
RasterOps.fillRect(pixels, rw, rh, x, y, rw, 3, BOTTOM_LIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPaint() {
|
||||
if (banned) return;
|
||||
|
||||
drawGradient();
|
||||
|
||||
synchronized (d) {
|
||||
if (!resized) {
|
||||
client.resizeGame(d.width, d.height);
|
||||
resized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!enabled) return;
|
||||
|
||||
final int hits = client.getCurrentLevel(3);
|
||||
final int base_hits = client.getBaseLevel(3);
|
||||
|
||||
final int pray = client.getCurrentLevel(5);
|
||||
final int base_pray = client.getBaseLevel(5);
|
||||
|
||||
int x, y;
|
||||
|
||||
if (client.getGameWidth() >= (512 + 7 + BAR_WIDTH) &&
|
||||
client.getGameHeight() >= (346 + 84 + 25)) {
|
||||
x = client.getGameWidth() - BAR_WIDTH - 7;
|
||||
y = client.getGameHeight() - 84 - 25;
|
||||
} else {
|
||||
x = 7;
|
||||
y = 135;
|
||||
}
|
||||
|
||||
drawStatBar(x, y, hits, base_hits, HP_FRONT, HP_BACK);
|
||||
client.drawString(String.format("Hits: %d/%d",
|
||||
hits, base_hits), x + 2, y, 2, 0xFFFFFF);
|
||||
|
||||
y += (BAR_HEIGHT + 7);
|
||||
|
||||
drawStatBar(x, y, pray, base_pray, PRAY_FRONT, PRAY_BACK);
|
||||
client.drawString(String.format("Pray: %d/%d",
|
||||
pray, base_pray), x + 2, y, 2, 0xFFFFFF);
|
||||
|
||||
y += (BAR_HEIGHT + 5);
|
||||
|
||||
client.drawString(String.format("Tile: (%d,%d)",
|
||||
client.getLocalX() + client.getAreaX(),
|
||||
client.getLocalY() + client.getAreaY()),
|
||||
x, y, 2, 0xFFFFFF);
|
||||
|
||||
y += 17;
|
||||
|
||||
client.drawString(String.format("Fatigue: %.2f%%",
|
||||
client.getFatigue()),
|
||||
x, y, 2, 0xFFFFFF);
|
||||
|
||||
y += 17;
|
||||
|
||||
client.drawString("XP: " +
|
||||
dformat.format(getTotalXp() - startingXP),
|
||||
x, y, 2, 0xFFFFFF);
|
||||
|
||||
ScriptListener.get().onPaintTick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetDisplayedXp() {
|
||||
startingXP = getTotalXp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaintingEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaintingEnabled(boolean b) {
|
||||
enabled = b;
|
||||
}
|
||||
|
||||
private double getTotalXp() {
|
||||
double total = 0.0;
|
||||
final int len = StaticAccess.SKILL_NAMES.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
total += client.getExperience(i);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static final IPaintListener get() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBanned(boolean b) {
|
||||
banned = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doResize(int w, int h) {
|
||||
synchronized (d) {
|
||||
resized = false;
|
||||
d.width = w;
|
||||
d.height = h;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderSolid(boolean b) {
|
||||
render_solid = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderTextures(boolean b) {
|
||||
render_textures = b;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import com.aposbot._default.IScript;
|
||||
import com.aposbot._default.IScriptListener;
|
||||
|
||||
public final class ScriptListener
|
||||
implements IScriptListener {
|
||||
|
||||
static final String ERROR_MESSAGE = "Error processing script. Send this output to the script's author:";
|
||||
private Extension ex;
|
||||
private long next;
|
||||
private boolean running;
|
||||
private IScript script;
|
||||
private String lastWord;
|
||||
private boolean newWord;
|
||||
private volatile boolean banned;
|
||||
|
||||
private static final ScriptListener instance = new ScriptListener();
|
||||
|
||||
private ScriptListener() {
|
||||
}
|
||||
|
||||
static void init(Extension ex) {
|
||||
instance.ex = ex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameTick() {
|
||||
if (banned) {
|
||||
return;
|
||||
}
|
||||
if (running) {
|
||||
if (script.isSleeping()) {
|
||||
if (newWord && (script.getFatigue() == 0 || script.isTricking())) {
|
||||
final String word = SleepListener.get().getGuess();
|
||||
if (word != null && !word.equals(lastWord)) {
|
||||
System.out.println("Sending guessed word: " + word);
|
||||
ex.sendCAPTCHA(word);
|
||||
lastWord = word;
|
||||
newWord = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() >= next) {
|
||||
try {
|
||||
next = (script.main() + System.currentTimeMillis());
|
||||
} catch (final Throwable t) {
|
||||
System.out.println(ERROR_MESSAGE);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPaintTick() {
|
||||
if (running) {
|
||||
try {
|
||||
script.paint();
|
||||
} catch (final Throwable t) {
|
||||
System.out.println(ERROR_MESSAGE);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGameMessage(boolean flag, String s1, int i1, String s2, int j1, int k1, String s3,
|
||||
String s4) {
|
||||
if (running) {
|
||||
if (s1 != null) {
|
||||
s1 = s1.replace((char) 160, ' ');
|
||||
}
|
||||
try {
|
||||
if (j1 == 1) {
|
||||
script.onPrivateMessage(s2, s1, k1 == 1, k1 >= 2);
|
||||
} else if (j1 == 0 || j1 == 3) {
|
||||
script.onServerMessage(s2);
|
||||
} else if (j1 == 4) {
|
||||
script.onChatMessage(s2, s1, k1 == 1, k1 >= 2);
|
||||
} else if (j1 == 6) {
|
||||
script.onTradeRequest(s1);
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
System.out.println(ERROR_MESSAGE);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyPress(int i) {
|
||||
if (running) {
|
||||
script.onKeyPress(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewSleepWord() {
|
||||
newWord = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptRunning(boolean b) {
|
||||
running = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScriptRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIScript(IScript script) {
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
if (script == null) {
|
||||
return "null";
|
||||
}
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasScript() {
|
||||
return script != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBanned(boolean b) {
|
||||
banned = b;
|
||||
}
|
||||
|
||||
public static boolean isRunning() {
|
||||
return instance.isScriptRunning();
|
||||
}
|
||||
|
||||
public static void setRunning(boolean b) {
|
||||
instance.setScriptRunning(b);
|
||||
}
|
||||
|
||||
public static void runScript() {
|
||||
instance.onGameTick();
|
||||
}
|
||||
|
||||
public static void message(boolean flag, String s1, int i1, String s2, int j1, int k1, String s3,
|
||||
String s4) {
|
||||
|
||||
instance.onGameMessage(flag, s1, i1, s2, j1, k1, s3, s4);
|
||||
}
|
||||
|
||||
static final IScriptListener get() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.aposbot.BotLoader;
|
||||
import com.aposbot.EntryFrame;
|
||||
import com.aposbot._default.ISleepListener;
|
||||
import com.stormy.ocrlib.DictSearch;
|
||||
import com.stormy.ocrlib.OCR;
|
||||
import com.stormy.ocrlib.SimpleImageIO;
|
||||
|
||||
public final class SleepListener
|
||||
implements ISleepListener {
|
||||
|
||||
private static final SleepListener instance = new SleepListener();
|
||||
private static final int OCR_NUM3 = 0;
|
||||
private static final int OCR_JOKER = 1;
|
||||
private static final int OCR_EXTERNAL = 2;
|
||||
private static final int OCR_MANUAL = 3;
|
||||
private OCR stormy;
|
||||
private File hc;
|
||||
private File slword;
|
||||
private long mod;
|
||||
private String sleepWord;
|
||||
private int ocrType;
|
||||
|
||||
private static final String hc_bmp = "." + File.separator + "HC.BMP";
|
||||
|
||||
private static final String slword_txt = "." + File.separator + "slword.txt";
|
||||
|
||||
private static final String dict_txt = "." + File.separator + "lib" + File.separator + "Dictionary.txt";
|
||||
|
||||
private static final String model_txt = "." + File.separator + "lib" + File.separator + "Model.txt";
|
||||
|
||||
private SleepListener() {
|
||||
}
|
||||
|
||||
public static void newWord(byte[] data) {
|
||||
instance.onNewWord(data);
|
||||
}
|
||||
|
||||
private static String readLine(File file) {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(file));
|
||||
return reader.readLine().trim();
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error reading slword.txt: " + t.toString());
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static byte[] convertImage(byte[] data) {
|
||||
int var1 = 1;
|
||||
byte var2 = 0;
|
||||
final byte[] var4 = new byte[10200];
|
||||
int var3;
|
||||
int var5;
|
||||
int var6;
|
||||
for (var3 = 0; var3 < 255; var2 = (byte) (255 - var2)) {
|
||||
var5 = data[var1++] & 255;
|
||||
for (var6 = 0; var6 < var5; ++var6) {
|
||||
var4[var3++] = var2;
|
||||
}
|
||||
}
|
||||
for (var5 = 1; var5 < 40; ++var5) {
|
||||
var6 = 0;
|
||||
while (var6 < 255) {
|
||||
final int var7 = data[var1++] & 255;
|
||||
for (int var8 = 0; var8 < var7; ++var8) {
|
||||
var4[var3] = var4[var3 - 255];
|
||||
++var3;
|
||||
++var6;
|
||||
}
|
||||
if (var6 < 255) {
|
||||
var4[var3] = (byte) (255 - var4[var3 - 255]);
|
||||
++var3;
|
||||
++var6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return var4;
|
||||
}
|
||||
|
||||
private static void saveBitmap(OutputStream out, byte[] data) throws IOException {
|
||||
out.write(66);
|
||||
out.write(77);
|
||||
short var3 = 1342;
|
||||
out.write(var3 & 255);
|
||||
out.write(var3 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
byte var10 = 62;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 40;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var3 = 256;
|
||||
out.write(var3 & 255);
|
||||
out.write(var3 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 40;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 1;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
var10 = 1;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
var10 = 0;
|
||||
out.write(var10 & 255);
|
||||
out.write(var10 >> 8 & 255);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(0);
|
||||
out.write(255);
|
||||
out.write(255);
|
||||
out.write(255);
|
||||
out.write(0);
|
||||
int var4 = 9945;
|
||||
for (int var5 = 0; var5 < 40; ++var5) {
|
||||
for (int var6 = 0; var6 < 32; ++var6) {
|
||||
byte var7 = 0;
|
||||
for (int var8 = 0; var8 < 8; ++var8) {
|
||||
var7 = (byte) (2 * var7);
|
||||
if (var6 != 31 || var8 != 7) {
|
||||
if (data[var4] != 0) {
|
||||
++var7;
|
||||
}
|
||||
++var4;
|
||||
}
|
||||
}
|
||||
out.write(var7);
|
||||
}
|
||||
var4 -= 510;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSolver(BotLoader bl, String type) {
|
||||
if (type.equals(EntryFrame.LABEL_NUM3)) {
|
||||
BufferedReader mr = null;
|
||||
BufferedReader dr = null;
|
||||
try {
|
||||
mr = new BufferedReader(new FileReader(model_txt));
|
||||
dr = new BufferedReader(new FileReader(dict_txt));
|
||||
stormy = new OCR(new DictSearch(dr), mr);
|
||||
ocrType = OCR_NUM3;
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
ocrType = OCR_MANUAL;
|
||||
} finally {
|
||||
try {
|
||||
if (mr != null) {
|
||||
mr.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
}
|
||||
try {
|
||||
if (dr != null) {
|
||||
dr.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
}
|
||||
}
|
||||
} else if (type.equals(EntryFrame.LABEL_EXTERNAL)) {
|
||||
hc = new File(hc_bmp);
|
||||
slword = new File(slword_txt);
|
||||
ocrType = OCR_EXTERNAL;
|
||||
} else if (type.equals(EntryFrame.LABEL_JOKER)) {
|
||||
hc = new File(hc_bmp);
|
||||
final Joker joker = Joker.get();
|
||||
if (joker.loadNativeLibrary()) {
|
||||
joker.setFilePaths(model_txt, dict_txt);
|
||||
ocrType = OCR_JOKER;
|
||||
} else {
|
||||
ocrType = OCR_MANUAL;
|
||||
}
|
||||
} else {
|
||||
ocrType = OCR_MANUAL;
|
||||
}
|
||||
if (ocrType != bl.getDefaultOCR()) {
|
||||
bl.setDefaultOCR(ocrType);
|
||||
bl.storeProperties(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewWord(byte[] data) {
|
||||
if (ScriptListener.get().isScriptRunning() && ocrType != OCR_MANUAL) {
|
||||
if (ocrType == OCR_NUM3) {
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
|
||||
try {
|
||||
saveBitmap(out, convertImage(data));
|
||||
sleepWord = stormy.guess(SimpleImageIO.readBMP(out.toByteArray()), true);
|
||||
} catch (final IOException ex) {
|
||||
ex.printStackTrace();
|
||||
sleepWord = null;
|
||||
}
|
||||
} else {
|
||||
if (ocrType != OCR_JOKER) {
|
||||
mod = slword.lastModified();
|
||||
}
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(hc);
|
||||
saveBitmap(out, convertImage(data));
|
||||
if (ocrType == OCR_JOKER) {
|
||||
sleepWord = Joker.get().getGuess();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ScriptListener.get().onNewSleepWord();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuess() {
|
||||
if (ocrType == OCR_EXTERNAL) {
|
||||
if (mod < slword.lastModified()) {
|
||||
sleepWord = readLine(slword);
|
||||
mod = slword.lastModified();
|
||||
return sleepWord;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return sleepWord;
|
||||
}
|
||||
|
||||
static final SleepListener get() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.URL;
|
||||
|
||||
import com.aposbot._default.IStaticAccess;
|
||||
|
||||
public final class StaticAccess
|
||||
implements IStaticAccess {
|
||||
|
||||
static final String[] SKILL_NAMES = {
|
||||
"Attack", "Defense", "Strength", "Hits", "Ranged", "Prayer", "Magic",
|
||||
"Cooking", "Woodcut", "Fletching", "Fishing", "Firemaking", "Crafting",
|
||||
"Smithing", "Mining", "Herblaw", "Agility", "Thieving"
|
||||
};
|
||||
|
||||
static final String[] SPELL_NAMES = {
|
||||
"Wind strike", "Confuse", "Water strike", "Enchant lvl-1 amulet",
|
||||
"Earth strike", "Weaken", "Fire strike", "Bones to bananas",
|
||||
"Wind bolt", "Curse", "Low level alchemy", "Water bolt",
|
||||
"Varrock teleport", "Enchant lvl-2 amulet", "Earth bolt",
|
||||
"Lumbridge teleport", "Telekinetic grab", "Fire bolt",
|
||||
"Falador teleport", "Crumble undead", "Wind blast", "Superheat item",
|
||||
"Camelot teleport", "Water blast", "Enchant lvl-3 amulet",
|
||||
"Iban blast", "Ardougne teleport", "Earth blast", "High level alchemy",
|
||||
"Charge Water Orb", "Enchant lvl-4 amulet", "Watchtower teleport",
|
||||
"Fire blast", "Claws of Guthix", "Saradomin strike",
|
||||
"Flames of Zamorak", "Charge earth Orb", "Wind wave",
|
||||
"Charge Fire Orb", "Water wave", "Charge air Orb", "Vulnerability",
|
||||
"Enchant lvl-5 amulet", "Earth wave", "Enfeeble", "Fire wave", "Stun",
|
||||
"Charge"
|
||||
};
|
||||
|
||||
private static final StaticAccess instance = new StaticAccess();
|
||||
|
||||
@Override
|
||||
public String getNpcName(int id) {
|
||||
return e.Mb[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNpcDesc(int id) {
|
||||
return ba.ac[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNpcLevel(int id) {
|
||||
return ((eb.b[id] + (la.a[id] + jb.k[id])) - -fb.d[id]) / 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemName(int id) {
|
||||
return ac.x[id];
|
||||
}
|
||||
|
||||
static void setStrings() {
|
||||
ac.x[165] += " (Guam Leaf)";
|
||||
ac.x[435] += " (Marrentill)";
|
||||
ac.x[436] += " (Tarromin)";
|
||||
ac.x[437] += " (Harralander)";
|
||||
ac.x[438] += " (Ranarr Weed)";
|
||||
ac.x[439] += " (Irit Leaf)";
|
||||
ac.x[440] += " (Avantoe)";
|
||||
ac.x[441] += " (Kwuarm)";
|
||||
ac.x[442] += " (Cadantine)";
|
||||
ac.x[443] += " (Dwarf Weed)";
|
||||
ac.x[933] += " (Torstol)";
|
||||
ac.x[221] += " (4)";
|
||||
ac.x[222] += " (3)";
|
||||
ac.x[223] += " (2)";
|
||||
ac.x[224] += " (1)";
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
ac.x[480 + (i * 3)] += " (3)";
|
||||
ac.x[480 + (i * 3) + 1] += " (2)";
|
||||
ac.x[480 + (i * 3) + 2] += " (1)";
|
||||
}
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
ac.x[566 + (i * 3)] += " (3)";
|
||||
ac.x[566 + (i * 3) + 1] += " (2)";
|
||||
ac.x[566 + (i * 3) + 2] += " (1)";
|
||||
}
|
||||
ac.x[963] += " (3)";
|
||||
ac.x[964] += " (2)";
|
||||
ac.x[965] += " (1)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemDesc(int id) {
|
||||
return ga.b[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemCommand(int id) {
|
||||
return lb.ac[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemBasePrice(int id) {
|
||||
return kb.b[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemStackable(int id) {
|
||||
return fa.e[id] != 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemTradable(int id) {
|
||||
return kb.c[id] != 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectName(int id) {
|
||||
return l.a[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectDesc(int id) {
|
||||
return la.f[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoundName(int id) {
|
||||
return ta.r[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoundDesc(int id) {
|
||||
return ub.b[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellReqLevel(int id) {
|
||||
return pa.f[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellType(int i) {
|
||||
return qb.e[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReagentCount(int id) {
|
||||
return o.p[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReagentId(int spell, int i) {
|
||||
return oa.d[spell][i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReagentAmount(int spell, int i) {
|
||||
return da.J[spell][i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFriendCount() {
|
||||
return n.g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFriendName(int i) {
|
||||
return ua.h[i].replace((char)160, ' ');
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIgnoredCount() {
|
||||
return db.g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIgnoredName(int i) {
|
||||
return ia.a[i].replace((char)160, ' ');
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrayerCount() {
|
||||
return t.g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrayerLevel(int i) {
|
||||
return ca.B[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrayerName(int i) {
|
||||
return t.h[i];
|
||||
}
|
||||
|
||||
public static final StaticAccess get() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSpellNames() {
|
||||
return SPELL_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSkillNames() {
|
||||
return SKILL_NAMES;
|
||||
}
|
||||
|
||||
static final boolean loadFont(e game, String name, String replacement, int index) {
|
||||
// Modification of client's qa.a
|
||||
// added "replacement" argument
|
||||
boolean flag = false;
|
||||
name = name.toLowerCase();
|
||||
boolean flag1 = false;
|
||||
if (name.startsWith("helvetica")) {
|
||||
name = name.substring(9);
|
||||
}
|
||||
if (name.startsWith("h")) {
|
||||
name = name.substring(1);
|
||||
}
|
||||
if (name.startsWith("f")) {
|
||||
name = name.substring(1);
|
||||
flag = true;
|
||||
}
|
||||
if (name.startsWith("d")) {
|
||||
name = name.substring(1);
|
||||
flag1 = true;
|
||||
}
|
||||
if (name.endsWith(".jf")) {
|
||||
name = name.substring(0, -3 + name.length());
|
||||
}
|
||||
int k1 = 0;
|
||||
if (name.endsWith("b")) {
|
||||
k1 = 1;
|
||||
name = name.substring(0, name.length() - 1);
|
||||
}
|
||||
if (name.endsWith("p")) {
|
||||
name = name.substring(0, -1 + name.length());
|
||||
}
|
||||
int size = Integer.parseInt(name);
|
||||
Font font = new Font(replacement, k1, size);
|
||||
FontMetrics fontmetrics = game.getFontMetrics(font);
|
||||
final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| ";
|
||||
b.c = 855;
|
||||
for (int i2 = 0; -96 < ~i2; i2++) {
|
||||
if (!s.a(index, font, i2, -95, game, characters.charAt(i2),
|
||||
fontmetrics, flag1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m.b[index] = new byte[b.c];
|
||||
for (int j2 = 0; ~j2 > ~b.c; j2++) {
|
||||
m.b[index][j2] = qb.k[j2];
|
||||
}
|
||||
|
||||
if (1 == k1 && fb.k[index]) {
|
||||
fb.k[index] = false;
|
||||
if (!loadFont(game, (new StringBuilder()).append("f").append(size)
|
||||
.append("p").toString(), replacement, index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (flag && !fb.k[index]) {
|
||||
fb.k[index] = false;
|
||||
if (!loadFont(game, (new StringBuilder()).append("d").append(size)
|
||||
.append("p").toString(), replacement, index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// modification of ib.a
|
||||
public static byte[] load(String friendly_name, int arg0, int index) throws IOException {
|
||||
ib.b++;
|
||||
if (null != la.g[index]) {
|
||||
return la.g[index];
|
||||
}
|
||||
nb.q = arg0;
|
||||
o.l = friendly_name;
|
||||
if (m.e != null) {
|
||||
byte data[] = m.e.a(9395, index);
|
||||
if (null != data && mb.a(data, data.length, 0) == tb.l[index]) {
|
||||
la.g[index] = k.a(128, true, data);
|
||||
return la.g[index];
|
||||
}
|
||||
}
|
||||
|
||||
String filename = (new StringBuilder()).append(ib.z[5])
|
||||
.append(index).append("_")
|
||||
.append(Long.toHexString(tb.l[index])).toString();
|
||||
byte data[] = null;
|
||||
String path = "." + File.separator + "Content" + File.separator + filename;
|
||||
File file = new File(path);
|
||||
boolean file_exists = file.exists();
|
||||
URL url = null;
|
||||
if (!file_exists) {
|
||||
url = new URL(ib.c, filename);
|
||||
}
|
||||
|
||||
for (int j1 = 0; ~j1 > -4; j1++) {
|
||||
|
||||
if (!file_exists) {
|
||||
System.out.println("[" + friendly_name + "]: loading from URL: " + url);
|
||||
data = da.a(url, true, true);
|
||||
if (data != null) {
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
try {
|
||||
out.write(data);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("[" + friendly_name + "]: loading from file: " + path);
|
||||
RandomAccessFile f = new RandomAccessFile(file, "r");
|
||||
data = new byte[(int) f.length()];
|
||||
try {
|
||||
f.readFully(data);
|
||||
} finally {
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (~mb.a(data, data.length, 0) != ~tb.l[index]) {
|
||||
continue;
|
||||
}
|
||||
if (null != m.e) {
|
||||
m.e.a(index, data.length, -97, data);
|
||||
}
|
||||
la.g[index] = k.a(128, true, data);
|
||||
return la.g[index];
|
||||
}
|
||||
|
||||
if (null != data) {
|
||||
StringBuilder stringbuilder = new StringBuilder(
|
||||
(new StringBuilder()).append(ib.z[4]).append(index)
|
||||
.append(ib.z[3]).append(tb.l[index]).toString());
|
||||
stringbuilder.append((new StringBuilder()).append(ib.z[2])
|
||||
.append(data.length).toString());
|
||||
for (int k1 = 0; ~data.length < ~k1 && -6 < ~k1; k1++) {
|
||||
stringbuilder.append((new StringBuilder()).append(" ")
|
||||
.append(data[k1]).toString());
|
||||
}
|
||||
|
||||
throw new IOException(stringbuilder.toString());
|
||||
} else {
|
||||
throw new IOException((new StringBuilder()).append(ib.z[4])
|
||||
.append(index).append(ib.z[3]).append(tb.l[index])
|
||||
.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextField;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
final class AuthFrame extends Frame {
|
||||
|
||||
private static final Dimension fieldSize = new Dimension(120, 25);
|
||||
private final Window parent;
|
||||
private final TextField username;
|
||||
private final TextField password;
|
||||
private final Button okButton;
|
||||
|
||||
public AuthFrame(String title, String message, Window parent) {
|
||||
super(title);
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
Panel labelPanel = null;
|
||||
if (message != null) {
|
||||
labelPanel = new Panel();
|
||||
final String str[] = message.split("\n");
|
||||
labelPanel.setLayout(new GridLayout(str.length, 0));
|
||||
for (int i = 0; i < str.length; ++i) {
|
||||
labelPanel.add(new Label(str[i]));
|
||||
}
|
||||
}
|
||||
|
||||
final Panel userPanel = new Panel();
|
||||
userPanel.add(new Label("Username:"));
|
||||
username = new TextField();
|
||||
username.setPreferredSize(fieldSize);
|
||||
userPanel.add(username);
|
||||
|
||||
final Panel pwdPanel = new Panel();
|
||||
pwdPanel.add(new Label("Password:"));
|
||||
password = new TextField();
|
||||
password.setPreferredSize(fieldSize);
|
||||
password.setEchoChar('*');
|
||||
pwdPanel.add(password);
|
||||
|
||||
final Panel inputPanel = new Panel();
|
||||
inputPanel.setLayout(new GridLayout(2, 1));
|
||||
inputPanel.add(userPanel);
|
||||
inputPanel.add(pwdPanel);
|
||||
|
||||
final Panel buttonPanel = new Panel();
|
||||
|
||||
okButton = new Button("OK");
|
||||
buttonPanel.add(okButton);
|
||||
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
if (labelPanel != null) {
|
||||
add(labelPanel, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
add(inputPanel, BorderLayout.CENTER);
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
pack();
|
||||
setResizable(false);
|
||||
}
|
||||
|
||||
private void close() {
|
||||
username.setText("");
|
||||
password.setText("");
|
||||
dispose();
|
||||
}
|
||||
|
||||
public synchronized String getUsername() {
|
||||
return username.getText();
|
||||
}
|
||||
|
||||
public synchronized String getPassword() {
|
||||
return password.getText();
|
||||
}
|
||||
|
||||
public synchronized void addActionListener(ActionListener al) {
|
||||
okButton.addActionListener(al);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
username.setText("");
|
||||
password.setText("");
|
||||
setLocationRelativeTo(parent);
|
||||
toFront();
|
||||
requestFocus();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
final class BobRand extends Random {
|
||||
|
||||
// http://burtleburtle.net/bob/rand/smallprng.html
|
||||
// Public domain.
|
||||
|
||||
private static final long serialVersionUID = 3048370036096647657L;
|
||||
private int a = 0;
|
||||
private int b = 0;
|
||||
private int c = 0;
|
||||
private int d = 0;
|
||||
|
||||
public BobRand() {
|
||||
setSeed(new SecureRandom().nextInt());
|
||||
}
|
||||
|
||||
public BobRand(int seed) {
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
public void setSeed(int seed) {
|
||||
a = 0xf1ea5eed;
|
||||
b = c = d = seed;
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
next(32);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeed(long seed) {
|
||||
setSeed((int) seed);
|
||||
}
|
||||
|
||||
private static int rot(int x, int k) {
|
||||
return ((x << k) | (x >>> (32 - k)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int next(int bits) {
|
||||
int e = a - rot(b, 27);
|
||||
a = b ^ rot(c, 17);
|
||||
b = c + d;
|
||||
c = d + e;
|
||||
d = e + a;
|
||||
return d >>> (32 - bits);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.aposbot._default.IAutoLogin;
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IClientInit;
|
||||
import com.aposbot._default.IJokerFOCR;
|
||||
import com.aposbot._default.IPaintListener;
|
||||
import com.aposbot._default.IScriptListener;
|
||||
import com.aposbot.applet.AVStub;
|
||||
|
||||
public final class BotFrame extends Frame {
|
||||
|
||||
private static final long serialVersionUID = -2847514806687135697L;
|
||||
private Checkbox loginCheck;
|
||||
private Checkbox gfxCheck;
|
||||
private Button startButton;
|
||||
private Debugger debugger;
|
||||
private ScriptFrame scriptFrame;
|
||||
private Choice worldChoice;
|
||||
private AVStub stub;
|
||||
private IClient client;
|
||||
|
||||
BotFrame(IClientInit init, final TextArea cTextArea, String account) {
|
||||
super("APOS (" + account + ")");
|
||||
setFont(Constants.UI_FONT);
|
||||
setIconImages(Constants.ICONS);
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
quit();
|
||||
}
|
||||
});
|
||||
|
||||
if (SystemTray.isSupported()) {
|
||||
final TrayIcon icon = new TrayIcon(Constants.ICON_16, "APOS (" + account + ")");
|
||||
icon.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
final BotFrame t = BotFrame.this;
|
||||
t.setVisible(!t.isVisible());
|
||||
}
|
||||
});
|
||||
try {
|
||||
SystemTray.getSystemTray().add(icon);
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
//final int defaultWorld = Constants.RANDOM.nextBoolean() ? 2 : 3;
|
||||
final int defaultWorld = 2 + Constants.RANDOM.nextInt(4);
|
||||
|
||||
final String str = "http://classic" + defaultWorld + ".runescape.com/";
|
||||
|
||||
final String rsc_page;
|
||||
try {
|
||||
byte[] b = HTTPClient.load(str +
|
||||
"plugin.js?param=o0,a1,s0", str, true);
|
||||
rsc_page = new String(b, Constants.UTF_8);
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error fetching RSC page: " + t.toString());
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> params = HTTPClient.getParameters(rsc_page);
|
||||
|
||||
client = init.createClient(this);
|
||||
((Component)client).setBackground(Color.BLACK);
|
||||
|
||||
try {
|
||||
final URL url = new URL(str);
|
||||
stub = new AVStub((Applet) client, url, url, params);
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
client.setStub(stub);
|
||||
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
image = ImageIO.read(new File("." + File.separator + "lib" + File.separator + "logo.png"));
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error loading logo: " + t.toString());
|
||||
}
|
||||
|
||||
final Panel sidePanel = new ImagePanel(image);
|
||||
setColours(sidePanel, true);
|
||||
sidePanel.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
|
||||
|
||||
final Dimension buttonSize = new Dimension(120, 23);
|
||||
|
||||
final Choice worldChoice = new Choice();
|
||||
worldChoice.setPreferredSize(buttonSize);
|
||||
worldChoice.setForeground(SystemColor.textText);
|
||||
worldChoice.setBackground(SystemColor.text);
|
||||
worldChoice.add("World # 1");
|
||||
worldChoice.add("World # 2");
|
||||
worldChoice.add("World # 3");
|
||||
worldChoice.add("World # 4");
|
||||
worldChoice.add("World # 5");
|
||||
worldChoice.select(defaultWorld - 1);
|
||||
worldChoice.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent event) {
|
||||
updateWorld(worldChoice.getSelectedIndex() + 1);
|
||||
}
|
||||
});
|
||||
this.worldChoice = worldChoice;
|
||||
|
||||
final Button chooseButton = new Button("Choose script");
|
||||
chooseButton.setPreferredSize(buttonSize);
|
||||
setButtonColours(chooseButton);
|
||||
chooseButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (scriptFrame == null) {
|
||||
scriptFrame = new ScriptFrame(client);
|
||||
}
|
||||
scriptFrame.setLocationRelativeTo(BotFrame.this);
|
||||
scriptFrame.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
startButton = new Button("Start script");
|
||||
startButton.setPreferredSize(buttonSize);
|
||||
setButtonColours(startButton);
|
||||
startButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (client.getScriptListener().isScriptRunning()) {
|
||||
stopScript();
|
||||
} else {
|
||||
startScript();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Button debugButton = new Button("Debugger");
|
||||
debugButton.setPreferredSize(buttonSize);
|
||||
setButtonColours(debugButton);
|
||||
debugButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (debugger == null) {
|
||||
debugger = new Debugger(client);
|
||||
}
|
||||
debugger.setLocationRelativeTo(BotFrame.this);
|
||||
debugger.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
final Button scrButton = new Button("Screenshot");
|
||||
scrButton.setPreferredSize(buttonSize);
|
||||
setButtonColours(scrButton);
|
||||
scrButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
takeScreenshot(String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
}, "ScreenshotThread").start();
|
||||
}
|
||||
});
|
||||
|
||||
final Button exitButton = new Button("Exit");
|
||||
exitButton.setPreferredSize(buttonSize);
|
||||
setButtonColours(exitButton);
|
||||
exitButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
quit();
|
||||
}
|
||||
});
|
||||
|
||||
sidePanel.add(worldChoice);
|
||||
sidePanel.add(chooseButton);
|
||||
sidePanel.add(startButton);
|
||||
sidePanel.add(debugButton);
|
||||
sidePanel.add(scrButton);
|
||||
sidePanel.add(exitButton);
|
||||
|
||||
final Panel checkPanel = new Panel();
|
||||
setColours(checkPanel, true);
|
||||
checkPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 15, 0));
|
||||
|
||||
loginCheck = new Checkbox("Autologin");
|
||||
setColours(loginCheck, true);
|
||||
loginCheck.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final IAutoLogin al = client.getAutoLogin();
|
||||
al.setEnabled(loginCheck.getState());
|
||||
}
|
||||
});
|
||||
|
||||
gfxCheck = new Checkbox("Rendering", true);
|
||||
setColours(gfxCheck, true);
|
||||
gfxCheck.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
client.setRendering(gfxCheck.getState());
|
||||
}
|
||||
});
|
||||
gfxCheck.setEnabled(false);
|
||||
|
||||
final Checkbox paintCheck = new Checkbox("Show bot layer",
|
||||
true);
|
||||
setColours(paintCheck, true);
|
||||
paintCheck.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final IPaintListener paint = client.getPaintListener();
|
||||
paint.setPaintingEnabled(paintCheck.getState());
|
||||
}
|
||||
});
|
||||
|
||||
final Checkbox r3d = new Checkbox("Plain 3D", true);
|
||||
setColours(r3d, true);
|
||||
r3d.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final IPaintListener paint = client.getPaintListener();
|
||||
paint.setRenderSolid(r3d.getState());
|
||||
}
|
||||
});
|
||||
|
||||
final Checkbox t3d = new Checkbox("Textured 3D", true);
|
||||
setColours(t3d, true);
|
||||
t3d.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final IPaintListener paint = client.getPaintListener();
|
||||
paint.setRenderTextures(t3d.getState());
|
||||
}
|
||||
});
|
||||
|
||||
checkPanel.add(loginCheck);
|
||||
checkPanel.add(gfxCheck);
|
||||
checkPanel.add(paintCheck);
|
||||
checkPanel.add(r3d);
|
||||
checkPanel.add(t3d);
|
||||
|
||||
((Component)client)
|
||||
.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
int w = ((Component)client).getWidth();
|
||||
int h = ((Component)client).getHeight();
|
||||
client.getPaintListener().doResize(w, h);
|
||||
}
|
||||
});
|
||||
|
||||
add((Component)client, BorderLayout.CENTER);
|
||||
add(sidePanel, BorderLayout.EAST);
|
||||
|
||||
if (cTextArea != null) {
|
||||
final Panel bottomPanel = new Panel();
|
||||
setColours(bottomPanel, true);
|
||||
bottomPanel.setLayout(new BorderLayout());
|
||||
cTextArea.setPreferredSize(new Dimension(0, 150));
|
||||
bottomPanel.add(cTextArea, BorderLayout.CENTER);
|
||||
bottomPanel.add(checkPanel, BorderLayout.SOUTH);
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
} else {
|
||||
add(checkPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
pack();
|
||||
setMinimumSize(getSize());
|
||||
|
||||
client.init();
|
||||
stub.setActive(true);
|
||||
client.start();
|
||||
}
|
||||
|
||||
private void quit() {
|
||||
client.getScriptListener().setScriptRunning(false);
|
||||
if (stub != null) {
|
||||
stub.setActive(false);
|
||||
}
|
||||
if (client != null) {
|
||||
client.stop();
|
||||
}
|
||||
final IJokerFOCR joker = client.getJoker();
|
||||
if (joker.isLibraryLoaded()) {
|
||||
joker.close();
|
||||
}
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
setLocationRelativeTo(null);
|
||||
toFront();
|
||||
requestFocus();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
|
||||
static void setColours(Component c, boolean invert) {
|
||||
c.setFont(Constants.UI_FONT);
|
||||
if (invert) {
|
||||
c.setBackground(Color.BLACK);
|
||||
c.setForeground(Color.WHITE);
|
||||
} else {
|
||||
c.setBackground(Color.WHITE);
|
||||
c.setForeground(Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setButtonColours(Button b) {
|
||||
b.setFont(Constants.UI_FONT);
|
||||
b.setForeground(SystemColor.controlText);
|
||||
b.setBackground(SystemColor.control);
|
||||
}
|
||||
|
||||
void startScript() {
|
||||
final IScriptListener listener = client.getScriptListener();
|
||||
if (listener.hasScript()) {
|
||||
listener.setScriptRunning(true);
|
||||
startButton.setLabel("Stop script");
|
||||
System.out.println(listener.getScriptName() + " started.");
|
||||
} else {
|
||||
System.out.println("No script selected!");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopScript() {
|
||||
final IScriptListener listener = client.getScriptListener();
|
||||
listener.setScriptRunning(false);
|
||||
startButton.setLabel("Start script");
|
||||
client.setKeysDisabled(false);
|
||||
System.out.println(listener.getScriptName() + " stopped.");
|
||||
}
|
||||
|
||||
public void takeScreenshot(String fileName) {
|
||||
final String name = "." + File.separator + "Screenshots" + File.separator + fileName + ".png";
|
||||
final Image image = client.getImage();
|
||||
final BufferedImage b = new BufferedImage(image.getWidth(null),
|
||||
image.getHeight(null), BufferedImage.TYPE_INT_RGB);
|
||||
final Graphics g = b.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
try {
|
||||
ImageIO.write(b, "png", new File(name));
|
||||
System.out.println("Saved " + name + ".");
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error taking screenshot: " + t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String getCodeBase() {
|
||||
return stub.getCodeBase().toString();
|
||||
}
|
||||
|
||||
public void updateWorld(int i) {
|
||||
try {
|
||||
final URL url = new URL("http://classic" + i + ".runescape.com/");
|
||||
stub.setDocumentBase(url);
|
||||
stub.setCodeBase(url);
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
stub.setParameter("nodeid", String.valueOf(5000 + i));
|
||||
stub.setParameter("servertype", i == 1 ? "3" : "1");
|
||||
worldChoice.select(i - 1);
|
||||
}
|
||||
|
||||
public void setAutoLogin(boolean b) {
|
||||
loginCheck.setState(b);
|
||||
client.getAutoLogin().setEnabled(b);
|
||||
}
|
||||
|
||||
public void enableRenderingToggle() {
|
||||
gfxCheck.setEnabled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.Insets;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.aposbot._default.IClientInit;
|
||||
|
||||
public final class BotLoader {
|
||||
|
||||
private static final String VERSION = "2.7";
|
||||
static final String PROPERTIES_FILE = "." + File.separator + "bot.properties";
|
||||
private String username;
|
||||
private String password;
|
||||
private int defaultOCR;
|
||||
private TextArea cTextArea;
|
||||
private Frame cFrame;
|
||||
private final IClientInit init;
|
||||
private String font;
|
||||
|
||||
private final class Authenticator implements Runnable {
|
||||
|
||||
private boolean invalid;
|
||||
private int failed_secs = 5;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(60 * 60 * 1000);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
for (;;) {
|
||||
int sleep;
|
||||
int mins = 60 + (7 & Constants.RANDOM.nextInt());
|
||||
try {
|
||||
if (!authenticate()) {
|
||||
System.out.println("Auth invalid. Stopping, and retrying in " + mins + " minutes...");
|
||||
init.getScriptListener().setBanned(true);
|
||||
init.getAutoLogin().setBanned(true);
|
||||
init.getPaintListener().setBanned(true);
|
||||
invalid = true;
|
||||
} else {
|
||||
if (invalid) {
|
||||
System.out.println("Auth valid. Starting.");
|
||||
init.getScriptListener().setBanned(false);
|
||||
init.getAutoLogin().setBanned(false);
|
||||
init.getPaintListener().setBanned(false);
|
||||
invalid = false;
|
||||
}
|
||||
}
|
||||
sleep = mins * 60 * 1000;
|
||||
failed_secs = 5;
|
||||
} catch (IOException ex) {
|
||||
System.out.println("Error connecting: " + ex.toString());
|
||||
System.out.println("Note that the bot can only authenticate when the forums are online.");
|
||||
System.out.println("Retrying in " + failed_secs + " seconds...");
|
||||
init.getScriptListener().setBanned(true);
|
||||
init.getAutoLogin().setBanned(true);
|
||||
init.getPaintListener().setBanned(true);
|
||||
invalid = true;
|
||||
sleep = (failed_secs++) * 1000;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BotLoader(String[] argv, IClientInit init) {
|
||||
this.init = init;
|
||||
if (argv.length == 0) {
|
||||
System.out.println("To launch the bot without the built-in console, use at least one command-line argument.");
|
||||
|
||||
final TextArea cTextArea = new TextArea(null, 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
BotFrame.setColours(cTextArea, true);
|
||||
cTextArea.setEditable(false);
|
||||
this.cTextArea = cTextArea;
|
||||
|
||||
final Frame cFrame = new Frame("Console");
|
||||
cFrame.addWindowListener(new StandardCloseHandler(cFrame, StandardCloseHandler.EXIT));
|
||||
cFrame.add(cTextArea);
|
||||
final Insets in = cFrame.getInsets();
|
||||
cFrame.setSize(in.right + in.left + 545, in.top + in.bottom + 320);
|
||||
cFrame.setIconImages(Constants.ICONS);
|
||||
cFrame.setLocationRelativeTo(null);
|
||||
cFrame.setVisible(true);
|
||||
cFrame.toFront();
|
||||
cFrame.requestFocus();
|
||||
this.cFrame = cFrame;
|
||||
|
||||
final PrintStream ps = new PrintStream(new TextAreaOutputStream(cTextArea));
|
||||
System.setOut(ps);
|
||||
System.setErr(ps);
|
||||
}
|
||||
System.out.println("APOS - contact address: rsc@entering.space");
|
||||
Properties p = getProperties(PROPERTIES_FILE);
|
||||
if (p != null) {
|
||||
try {
|
||||
username = p.getProperty("auth_user");
|
||||
password = p.getProperty("auth_pass");
|
||||
font = p.getProperty("font");
|
||||
if (font != null && font.trim().isEmpty()) {
|
||||
font = null;
|
||||
}
|
||||
final String str = p.getProperty("default_ocr");
|
||||
defaultOCR = str == null ? 0 : Integer.parseInt(str);
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Settings error:");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (username != null) {
|
||||
System.out.println("Attempting to authenticate...");
|
||||
try {
|
||||
if (authenticate()) {
|
||||
System.out.println("Auth valid.");
|
||||
new Thread(new Authenticator()).start();
|
||||
new EntryFrame(this).setVisible(true);
|
||||
} else {
|
||||
System.out.println("Auth invalid.");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
System.out.println("Error connecting: " + ex.toString());
|
||||
System.out.println("Note that the bot can only authenticate when the forums are online.");
|
||||
}
|
||||
} else {
|
||||
final AuthFrame authFrame = new AuthFrame("APOS", "Enter your forum login details.", null);
|
||||
authFrame.setIconImages(Constants.ICONS);
|
||||
authFrame.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println("Attempting to authenticate...");
|
||||
username = authFrame.getUsername();
|
||||
password = authFrame.getPassword();
|
||||
try {
|
||||
if (authenticate()) {
|
||||
storeProperties(new Properties());
|
||||
System.out.println("Auth valid.");
|
||||
authFrame.dispose();
|
||||
new Thread(new Authenticator()).start();
|
||||
new EntryFrame(BotLoader.this).setVisible(true);
|
||||
} else {
|
||||
System.out.println("Auth invalid. Try again.");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
System.out.println("Error connecting: " + ex.toString());
|
||||
System.out.println("Note that the bot can only authenticate when the forums are online.");
|
||||
}
|
||||
}
|
||||
});
|
||||
authFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
static Properties getProperties(String path) {
|
||||
Properties p = new Properties();
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(path);
|
||||
p.load(in);
|
||||
if (!p.containsKey("font")) {
|
||||
p.put("font", "");
|
||||
}
|
||||
return p;
|
||||
} catch (Throwable t) {
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void storeProperties(Properties p) {
|
||||
if (p == null) {
|
||||
p = getProperties(PROPERTIES_FILE);
|
||||
}
|
||||
p.put("auth_user", username);
|
||||
p.put("auth_pass", password);
|
||||
p.put("default_ocr", String.valueOf(defaultOCR));
|
||||
p.put("font", font == null ? "" : font);
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(PROPERTIES_FILE);
|
||||
p.store(out, null);
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error storing updated properties: " + t.toString());
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
public void setDefaultOCR(int i) {
|
||||
defaultOCR = i;
|
||||
}
|
||||
|
||||
public int getDefaultOCR() {
|
||||
return defaultOCR;
|
||||
}
|
||||
|
||||
TextArea getConsoleTextArea() {
|
||||
return cTextArea;
|
||||
}
|
||||
|
||||
void setConsoleFrameVisible(boolean b) {
|
||||
if (cFrame != null) {
|
||||
cFrame.setVisible(b);
|
||||
}
|
||||
}
|
||||
|
||||
IClientInit getClientInit() {
|
||||
return init;
|
||||
}
|
||||
|
||||
boolean authenticate() throws IOException {
|
||||
if (true) return true;
|
||||
if (username == null || password == null) {
|
||||
return false;
|
||||
}
|
||||
byte[] dumb_seed = new byte[16];
|
||||
Constants.RANDOM.nextBytes(dumb_seed);
|
||||
String seed_hex = hexString(dumb_seed);
|
||||
|
||||
String server_response = new String(HTTPClient.load(
|
||||
"http://aposbot.com/newauth.php?user="
|
||||
+ username.trim().replace(" ", "%20") + "&pass="
|
||||
+ password.trim().replace(" ", "%20") + "&seed=" + seed_hex
|
||||
+ "&ver=" + VERSION, null, false), Constants.UTF_8);
|
||||
if (server_response.length() == 1) {
|
||||
switch (server_response.charAt(0)) {
|
||||
case '3':
|
||||
System.out.println("A new version of APOS has been released. Please update.");
|
||||
return false;
|
||||
case '5':
|
||||
case '7':
|
||||
System.out.println("You have been banned from using APOS.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return md5($username.$password.$seed.$response);
|
||||
*/
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
digest.update(username.getBytes(Constants.UTF_8));
|
||||
digest.update(password.getBytes(Constants.UTF_8));
|
||||
digest.update(seed_hex.getBytes(Constants.UTF_8));
|
||||
digest.update(new byte[] {
|
||||
'1'
|
||||
});
|
||||
if (hexString(digest.digest()).equals(server_response)) {
|
||||
return true;
|
||||
}
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new IOException("no such algorithm");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String hexString(byte[] in) {
|
||||
final char[] alphabet = "0123456789abcdef".toCharArray();
|
||||
char[] out = new char[in.length * 2];
|
||||
for (int i = 0; i < in.length; i++) {
|
||||
int v = in[i] & 0xFF;
|
||||
out[i * 2] = alphabet[v >>> 4];
|
||||
out[i * 2 + 1] = alphabet[v & 0x0F];
|
||||
}
|
||||
return new String(out);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public final class Constants {
|
||||
|
||||
public static final Image ICON_16 = readImage("icon16.png");
|
||||
public static final Image ICON_22 = readImage("icon22.png");
|
||||
public static final Image ICON_32 = readImage("icon32.png");
|
||||
public static final List<Image> ICONS = new ArrayList<>();
|
||||
|
||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
public static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
|
||||
|
||||
public static final Random RANDOM = new BobRand();
|
||||
|
||||
public static final int OP_NPC_ATTACK = 190;
|
||||
public static final int OP_NPC_ACTION = 202;
|
||||
public static final int OP_NPC_TALK = 153;
|
||||
public static final int OP_NPC_USEWITH = 135;
|
||||
public static final int OP_NPC_CAST = 50;
|
||||
|
||||
public static final int OP_PLAYER_CAST = 229;
|
||||
public static final int OP_PLAYER_ATTACK = 171;
|
||||
public static final int OP_PLAYER_TRADE = 142;
|
||||
public static final int OP_PLAYER_FOLLOW = 165;
|
||||
public static final int OP_PLAYER_USEWITH = 113;
|
||||
|
||||
public static final int OP_INV_ACTION = 90;
|
||||
public static final int OP_INV_DROP = 246;
|
||||
public static final int OP_INV_EQUIP = 169;
|
||||
public static final int OP_INV_UNEQUIP = 170;
|
||||
public static final int OP_INV_USEWITH = 91;
|
||||
public static final int OP_INV_CAST = 4;
|
||||
|
||||
public static final int OP_GITEM_TAKE = 247;
|
||||
public static final int OP_GITEM_USEWITH = 53;
|
||||
public static final int OP_GITEM_CAST = 249;
|
||||
|
||||
public static final int OP_OBJECT_USEWITH = 115;
|
||||
public static final int OP_OBJECT_ACTION1 = 136;
|
||||
public static final int OP_OBJECT_ACTION2 = 79;
|
||||
|
||||
public static final int OP_BOUND_USEWITH = 161;
|
||||
public static final int OP_BOUND_ACTION1 = 14;
|
||||
public static final int OP_BOUND_ACTION2 = 127;
|
||||
|
||||
// don't forget the trap
|
||||
public static final int OP_BANK_DEPOSIT = 23;
|
||||
public static final int OP_BANK_WITHDRAW = 22;
|
||||
public static final int OP_BANK_CLOSE = 212;
|
||||
|
||||
public static final int OP_TRADE_ACCEPT = 55;
|
||||
public static final int OP_TRADE_CONFIRM = 104;
|
||||
public static final int OP_TRADE_DECLINE = 230;
|
||||
|
||||
public static final int OP_SHOP_BUY = 236;
|
||||
public static final int OP_SHOP_SELL = 221;
|
||||
public static final int OP_SHOP_CLOSE = 166;
|
||||
|
||||
public static final int OP_PRAYER_ENABLE = 60;
|
||||
public static final int OP_PRAYER_DISABLE = 254;
|
||||
|
||||
public static final int OP_SELF_CAST = 137;
|
||||
public static final int OP_DIALOG_ANSWER = 116;
|
||||
public static final int OP_SET_COMBAT_STYLE = 29;
|
||||
public static final int OP_LOGOUT = 102;
|
||||
public static final Font UI_FONT = getUIFont();
|
||||
|
||||
public static final String DEFAULT_JAR = "rsclassic.jar";
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
|
||||
private static Image readImage(String image) {
|
||||
try {
|
||||
return ImageIO.read(new File("." + File.separator +
|
||||
"lib" + File.separator + image));
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error loading icon: " + t.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Font getUIFont() {
|
||||
Font _default = new Canvas().getFont();
|
||||
int style = Font.PLAIN;
|
||||
int size = 12;
|
||||
if (_default != null) {
|
||||
style = _default.getStyle();
|
||||
size = _default.getSize();
|
||||
}
|
||||
Properties p = BotLoader.getProperties(BotLoader.PROPERTIES_FILE);
|
||||
String name = null;
|
||||
if (p != null) {
|
||||
name = p.getProperty("font");
|
||||
}
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = Font.SANS_SERIF;
|
||||
}
|
||||
return new Font(name, style, size);
|
||||
}
|
||||
|
||||
static {
|
||||
ICONS.add(ICON_16);
|
||||
ICONS.add(ICON_22);
|
||||
ICONS.add(ICON_32);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IStaticAccess;
|
||||
|
||||
public final class Debugger extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 4433346449171745421L;
|
||||
private final JTable table;
|
||||
private final IClient client;
|
||||
private int selected;
|
||||
|
||||
public Debugger(final IClient client) {
|
||||
super("APOS Debugger");
|
||||
setFont(Constants.UI_FONT);
|
||||
this.client = client;
|
||||
setIconImages(Constants.ICONS);
|
||||
|
||||
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||
final JComboBox<String> choice = new JComboBox<String>();
|
||||
choice.setFont(Constants.UI_FONT);
|
||||
choice.addItem("NPCs");
|
||||
choice.addItem("Players");
|
||||
choice.addItem("Objects");
|
||||
choice.addItem("Wall objects");
|
||||
choice.addItem("Inventory items");
|
||||
choice.addItem("Ground items");
|
||||
choice.addItem("Skills");
|
||||
choice.addItem("Bank");
|
||||
choice.addItem("Shop");
|
||||
choice.addItem("Friends list");
|
||||
choice.addItem("Ignore list");
|
||||
choice.addItem("Local trade");
|
||||
choice.addItem("Remote trade");
|
||||
choice.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
selected = choice.getSelectedIndex();
|
||||
populate();
|
||||
}
|
||||
});
|
||||
|
||||
table = new JTable();
|
||||
table.setFont(Constants.UI_FONT);
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
scroll.setFont(Constants.UI_FONT);
|
||||
add(scroll, BorderLayout.CENTER);
|
||||
|
||||
final JPanel panel = new JPanel();
|
||||
panel.add(choice);
|
||||
|
||||
JButton button = new JButton("Refresh");
|
||||
button.setFont(Constants.UI_FONT);
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
populate();
|
||||
}
|
||||
});
|
||||
panel.add(button);
|
||||
button = new JButton("Hide");
|
||||
button.setFont(Constants.UI_FONT);
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
panel.add(button);
|
||||
|
||||
add(panel, BorderLayout.SOUTH);
|
||||
|
||||
pack();
|
||||
setMinimumSize(getSize());
|
||||
final Insets in = getInsets();
|
||||
setSize(in.right + in.left + 480, in.top + in.bottom + 500);
|
||||
}
|
||||
|
||||
private void populate() {
|
||||
final DecimalFormat iformat = new DecimalFormat("#,##0");
|
||||
final IStaticAccess statica = client.getStatic();
|
||||
int count, i;
|
||||
String[] columns;
|
||||
Object[][] rows;
|
||||
switch (selected) {
|
||||
case 0:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "sidx", "X", "Y"
|
||||
};
|
||||
count = client.getNpcCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final int id = client.getNpcId(client.getNpc(i));
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getNpcName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getMobServerIndex(client.getNpc(i));
|
||||
row[3] = client.getMobLocalX(client.getNpc(i)) + client.getAreaX();
|
||||
row[4] = client.getMobLocalY(client.getNpc(i)) + client.getAreaY();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
columns = new String[] {
|
||||
"Name", "sidx", "HP lvl (in cmb)", "X", "Y"
|
||||
};
|
||||
count = client.getPlayerCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final Object[] row = rows[i];
|
||||
row[0] = client.getPlayerName(client.getPlayer(i));
|
||||
row[1] = client.getMobServerIndex(client.getPlayer(i));
|
||||
row[2] = client.getMobBaseHitpoints(client.getPlayer(i));
|
||||
row[3] = client.getMobLocalX(client.getPlayer(i)) + client.getAreaX();
|
||||
row[4] = client.getMobLocalY(client.getPlayer(i)) + client.getAreaY();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "X", "Y"
|
||||
};
|
||||
count = client.getObjectCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final int id = client.getObjectId(i);
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getObjectName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getObjectLocalX(i) + client.getAreaX();
|
||||
row[3] = client.getObjectLocalY(i) + client.getAreaY();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "X", "Y"
|
||||
};
|
||||
count = client.getBoundCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final int id = client.getBoundId(i);
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getBoundName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getBoundLocalX(i) + client.getAreaX();
|
||||
row[3] = client.getBoundLocalY(i) + client.getAreaY();
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "Stack", "Equipped"
|
||||
};
|
||||
count = client.getInventorySize();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final int id = client.getInventoryId(i);
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = iformat.format(client.getInventoryStack(i));
|
||||
row[3] = client.isEquipped(i);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "X", "Y"
|
||||
};
|
||||
count = client.getGroundItemCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final int id = client.getGroundItemId(i);
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getGroundItemLocalX(i) + client.getAreaX();
|
||||
row[3] = client.getGroundItemLocalY(i) + client.getAreaY();
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
final DecimalFormat dformat = new DecimalFormat("#,##0.0#");
|
||||
columns = new String[] {
|
||||
"Name", "Current", "Base", "XP"
|
||||
};
|
||||
count = statica.getSkillNames().length;
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getSkillNames()[i];
|
||||
row[1] = client.getCurrentLevel(i);
|
||||
row[2] = client.getBaseLevel(i);
|
||||
row[3] = dformat.format(client.getExperience(i));
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "Stack"
|
||||
};
|
||||
count = client.getBankSize();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final Object[] row = rows[i];
|
||||
final int id = client.getBankId(i);
|
||||
row[0] = statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = iformat.format(client.getBankStack(i));
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "Stack"
|
||||
};
|
||||
count = client.getShopSize();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; i++) {
|
||||
final Object[] row = rows[i];
|
||||
final int id = client.getShopId(i);
|
||||
row[0] = id == -1 ? "null" : statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = iformat.format(client.getShopStack(i));
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
columns = new String[] {
|
||||
"Name"
|
||||
};
|
||||
count = statica.getFriendCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; ++i) {
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getFriendName(i);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
columns = new String[] {
|
||||
"Name"
|
||||
};
|
||||
count = statica.getIgnoredCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; ++i) {
|
||||
final Object[] row = rows[i];
|
||||
row[0] = statica.getIgnoredName(i);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "Stack"
|
||||
};
|
||||
count = client.getLocalTradeItemCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; ++i) {
|
||||
final Object[] row = rows[i];
|
||||
int id = client.getLocalTradeItemId(i);
|
||||
row[0] = statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getLocalTradeItemStack(i);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
columns = new String[] {
|
||||
"Name", "ID", "Stack"
|
||||
};
|
||||
count = client.getRemoteTradeItemCount();
|
||||
rows = new Object[count][columns.length];
|
||||
for (i = 0; i < count; ++i) {
|
||||
final Object[] row = rows[i];
|
||||
int id = client.getRemoteTradeItemId(i);
|
||||
row[0] = statica.getItemName(id);
|
||||
row[1] = id;
|
||||
row[2] = client.getRemoteTradeItemStack(i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rows = new Object[0][0];
|
||||
columns = new String[0];
|
||||
break;
|
||||
}
|
||||
table.setModel(new DefaultTableModel(rows, columns));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
populate();
|
||||
toFront();
|
||||
requestFocus();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.CheckboxGroup;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.aposbot._default.IClientInit;
|
||||
import com.aposbot._default.ISleepListener;
|
||||
|
||||
public final class EntryFrame extends Frame {
|
||||
|
||||
public static final String LABEL_NUM3 = "Num3l (Internal)";
|
||||
public static final String LABEL_JOKER = "Joker (Internal/Win32/JNI)";
|
||||
public static final String LABEL_EXTERNAL = "External (HC.BMP/slword.txt)";
|
||||
public static final String LABEL_MANUAL = "Manual";
|
||||
|
||||
private AuthFrame authFrame;
|
||||
private String[] accountNames;
|
||||
private String account;
|
||||
|
||||
EntryFrame(final BotLoader bl) {
|
||||
super("APOS");
|
||||
|
||||
setFont(Constants.UI_FONT);
|
||||
addWindowListener(new StandardCloseHandler(this, StandardCloseHandler.EXIT));
|
||||
setIconImages(Constants.ICONS);
|
||||
setResizable(false);
|
||||
|
||||
loadAccounts();
|
||||
|
||||
final Panel accountPanel = new Panel();
|
||||
accountPanel.add(new Label("Autologin account:"));
|
||||
|
||||
final Choice accountChoice = new Choice();
|
||||
accountChoice.setPreferredSize(new Dimension(150, 15));
|
||||
for (final String accountName : accountNames) {
|
||||
accountChoice.add(accountName);
|
||||
}
|
||||
if (accountNames.length > 0) {
|
||||
account = accountNames[0];
|
||||
}
|
||||
accountChoice.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent event) {
|
||||
account = String.valueOf(event.getItem());
|
||||
}
|
||||
});
|
||||
|
||||
accountPanel.add(accountChoice);
|
||||
|
||||
final Button addButton = new Button("Add");
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (authFrame == null) {
|
||||
final AuthFrame authFrame = new AuthFrame("Add an account", null, EntryFrame.this);
|
||||
authFrame.setFont(Constants.UI_FONT);
|
||||
authFrame.setIconImages(Constants.ICONS);
|
||||
authFrame.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final Properties p = new Properties();
|
||||
final String u = EntryFrame.this.authFrame.getUsername();
|
||||
p.put("username", u);
|
||||
p.put("password", EntryFrame.this.authFrame.getPassword());
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream("." + File.separator + "Accounts" + File.separator + u + ".properties");
|
||||
p.store(out, null);
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error saving account details: " + t.toString());
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
accountChoice.add(u);
|
||||
accountChoice.select(u);
|
||||
account = u;
|
||||
EntryFrame.this.authFrame.setVisible(false);
|
||||
}
|
||||
});
|
||||
EntryFrame.this.authFrame = authFrame;
|
||||
}
|
||||
authFrame.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
accountPanel.add(addButton);
|
||||
|
||||
final Panel ocrPanel = new Panel(new GridLayout(0, 1, 2, 2));
|
||||
ocrPanel.add(new Label("OCR/Sleeper:"));
|
||||
final CheckboxGroup ocrGroup = new CheckboxGroup();
|
||||
final int i = bl.getDefaultOCR();
|
||||
ocrPanel.add(new Checkbox(LABEL_NUM3, ocrGroup, i == 0));
|
||||
ocrPanel.add(new Checkbox(LABEL_JOKER, ocrGroup, i == 1));
|
||||
ocrPanel.add(new Checkbox(LABEL_EXTERNAL, ocrGroup, i == 2));
|
||||
ocrPanel.add(new Checkbox(LABEL_MANUAL, ocrGroup, i == 3));
|
||||
|
||||
final Panel buttonPanel = new Panel();
|
||||
|
||||
final Button okButton = new Button("OK");
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (authFrame != null) {
|
||||
authFrame.dispose();
|
||||
}
|
||||
try {
|
||||
final IClientInit init = bl.getClientInit();
|
||||
loadUsername(init, account);
|
||||
final ISleepListener sleepy = init.getSleepListener();
|
||||
sleepy.setSolver(bl, ocrGroup.getSelectedCheckbox().getLabel());
|
||||
dispose();
|
||||
new BotFrame(init, bl.getConsoleTextArea(), account).setVisible(true);
|
||||
bl.setConsoleFrameVisible(false);
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
buttonPanel.add(okButton);
|
||||
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
add(accountPanel, BorderLayout.NORTH);
|
||||
add(ocrPanel, BorderLayout.CENTER);
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
setLocationRelativeTo(null);
|
||||
toFront();
|
||||
requestFocus();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
|
||||
private void loadAccounts() {
|
||||
try {
|
||||
final File dir = new File("." + File.separator + "Accounts" + File.separator);
|
||||
final String[] account_list = dir.list();
|
||||
accountNames = new String[account_list.length];
|
||||
for (int i = 0; i < account_list.length; ++i) {
|
||||
accountNames[i] = account_list[i].replace(".properties", "");
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error loading accounts: " + t.toString());
|
||||
accountNames = new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadUsername(IClientInit init, String name) {
|
||||
if (name == null) {
|
||||
System.out.println("You didn't enter an account to use with autologin.");
|
||||
System.out.println("You can still use APOS, but it won't be able to log you back in if you disconnect.");
|
||||
return;
|
||||
}
|
||||
final Properties p = new Properties();
|
||||
FileInputStream stream = null;
|
||||
try {
|
||||
stream = new FileInputStream("." + File.separator + "Accounts" + File.separator + name + ".properties");
|
||||
p.load(stream);
|
||||
init.getAutoLogin().setAccount(p.getProperty("username"), p.getProperty("password"));
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Error loading account " + name + ": " + t.toString());
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextField;
|
||||
|
||||
public final class FieldPair extends Panel {
|
||||
|
||||
private static final long serialVersionUID = -7845847154396333166L;
|
||||
private final TextField field;
|
||||
|
||||
public FieldPair(String text, String value, boolean enabled) {
|
||||
final GridLayout layout = new GridLayout(1, 2);
|
||||
setLayout(layout);
|
||||
field = new TextField(value);
|
||||
field.setEnabled(enabled);
|
||||
add(new Label(text));
|
||||
add(field);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return field.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
field.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return field.getText();
|
||||
}
|
||||
|
||||
public void setValue(String str) {
|
||||
field.setText(str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class HTTPClient {
|
||||
|
||||
private static final String USER_AGENT;
|
||||
|
||||
private HTTPClient() {
|
||||
}
|
||||
|
||||
public static byte[] load(String dest,
|
||||
String via, boolean fakeUserAgent) throws IOException
|
||||
{
|
||||
final URL url = new URL(dest);
|
||||
final URLConnection connect = url.openConnection();
|
||||
connect.addRequestProperty("Accept",
|
||||
"text/html, application/xhtml+xml, */*");
|
||||
if (via != null) {
|
||||
connect.addRequestProperty("Referer", via);
|
||||
}
|
||||
connect.addRequestProperty("Accept-Language", "en-US");
|
||||
connect.addRequestProperty("User-Agent",
|
||||
fakeUserAgent ? USER_AGENT : "APOS");
|
||||
connect.setConnectTimeout(5000);
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = connect.getInputStream();
|
||||
int read = 0;
|
||||
final int block_size = 4096;
|
||||
byte b[] = new byte[block_size];
|
||||
for (;;) {
|
||||
final int r = in.read(b, read, block_size);
|
||||
if (r == -1)
|
||||
break;
|
||||
read += r;
|
||||
b = Arrays.copyOf(b, b.length + block_size);
|
||||
}
|
||||
return Arrays.copyOf(b, read);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getParameters(String document)
|
||||
{
|
||||
final String PATTERN =
|
||||
"<param name=([^\\s]+)\\s+value=([^>]*)>";
|
||||
final Map<String, String> params = new HashMap<>();
|
||||
final Pattern regex = Pattern.compile(PATTERN,
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
|
||||
final Matcher matcher = regex.matcher(document);
|
||||
while (matcher.find()) {
|
||||
final String key = matcher.group(1).replace("\"", "");
|
||||
final String value = matcher.group(2).replace("\"", "");
|
||||
if (!params.containsKey(key)) {
|
||||
params.put(key, value);
|
||||
}
|
||||
}
|
||||
if (params.containsKey("haveie6")) {
|
||||
params.put("haveie6", "false");
|
||||
}
|
||||
for (final String str : params.keySet()) {
|
||||
System.out.println(str + "=" + params.get(str));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public static String getArchive(String document)
|
||||
{
|
||||
final String PATTERN = "archive=([^\\s]+)";
|
||||
final Pattern regex = Pattern.compile(PATTERN,
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
|
||||
final Matcher matcher = regex.matcher(document);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).replace("\"", "");
|
||||
}
|
||||
return Constants.DEFAULT_JAR;
|
||||
}
|
||||
|
||||
static {
|
||||
final StringBuilder b = new StringBuilder("Mozilla/5.0 (compatible; Windows NT 6.1");
|
||||
boolean x64 = true;
|
||||
try {
|
||||
x64 = !System.getProperty("sun.arch.data.model").contains("32");
|
||||
} catch (final Throwable t) {
|
||||
}
|
||||
if (x64) {
|
||||
b.append("; WOW64) like Gecko");
|
||||
} else {
|
||||
b.append(") like Gecko");
|
||||
}
|
||||
USER_AGENT = b.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Panel;
|
||||
|
||||
public class ImagePanel extends Panel {
|
||||
|
||||
private static final long serialVersionUID = 4557522767188007469L;
|
||||
private final Image image;
|
||||
|
||||
public ImagePanel(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
if (image != null) {
|
||||
g.drawImage(image, 0, 0, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
import com.aposbot.Constants;
|
||||
import com.aposbot.StandardCloseHandler;
|
||||
|
||||
public final class JSONgui
|
||||
implements ActionListener {
|
||||
|
||||
private final ScriptEngineManager manager = new ScriptEngineManager();
|
||||
private TextArea editor;
|
||||
private Frame frame;
|
||||
private final String script_name;
|
||||
private final Object config;
|
||||
private final String[] help_contents;
|
||||
private final Runnable completion;
|
||||
|
||||
public JSONgui(String script, Object config, String[] help, Runnable completion) {
|
||||
this.script_name = script;
|
||||
this.config = config;
|
||||
this.help_contents = help;
|
||||
this.completion = completion;
|
||||
}
|
||||
|
||||
public void showFrame() {
|
||||
|
||||
editor = new TextArea(create_json(config), 0, 0,
|
||||
TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
editor.setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||
|
||||
Menu file = new Menu("File");
|
||||
file.add(menu_item("Save"));
|
||||
file.add(menu_item("Load"));
|
||||
file.addSeparator();
|
||||
file.add(menu_item("Exit"));
|
||||
|
||||
Menu edit = new Menu("Edit");
|
||||
edit.add(menu_item("Cut"));
|
||||
edit.add(menu_item("Copy"));
|
||||
edit.add(menu_item("Paste"));
|
||||
edit.add(menu_item("Select all"));
|
||||
edit.addSeparator();
|
||||
edit.add(menu_item("Reset (safety net)"));
|
||||
|
||||
Menu help = new Menu("Help");
|
||||
help.add(menu_item("Help for " + script_name));
|
||||
help.add(menu_item("About"));
|
||||
|
||||
MenuBar bar = new MenuBar();
|
||||
bar.add(file);
|
||||
bar.add(edit);
|
||||
bar.add(help);
|
||||
|
||||
Button done = new Button("Done");
|
||||
done.addActionListener(this);
|
||||
|
||||
Panel button_pane = new Panel();
|
||||
button_pane.add(done);
|
||||
|
||||
frame = new Frame("Configure " + script_name);
|
||||
frame.setMenuBar(bar);
|
||||
frame.addWindowListener(
|
||||
new StandardCloseHandler(frame, StandardCloseHandler.DISPOSE)
|
||||
);
|
||||
frame.setIconImages(Constants.ICONS);
|
||||
|
||||
frame.add(editor, BorderLayout.CENTER);
|
||||
frame.add(button_pane, BorderLayout.SOUTH);
|
||||
|
||||
frame.setSize(500, 400);
|
||||
|
||||
show_window(frame, null);
|
||||
}
|
||||
|
||||
// JSON.stringify() == broken for java primitives
|
||||
// so, this hack is currently required
|
||||
private static final String create_json(Object object) {
|
||||
StringBuilder b = new StringBuilder("{\n");
|
||||
Field[] fields = object.getClass().getFields();
|
||||
for (int i = 0; i < fields.length; ++i) {
|
||||
Field f = fields[i];
|
||||
int mod = f.getModifiers();
|
||||
if ((mod & Modifier.FINAL) != 0 || (mod & Modifier.PUBLIC) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String property_name = f.getName();
|
||||
Class<?> c = f.getType();
|
||||
|
||||
b.append("\t\"");
|
||||
b.append(property_name);
|
||||
b.append("\": ");
|
||||
|
||||
try {
|
||||
if (Object[].class.isAssignableFrom(c)) {
|
||||
b.append(Arrays.deepToString((Object[]) f.get(object)));
|
||||
} else if (c.equals(int[].class)) {
|
||||
b.append(Arrays.toString((int[]) f.get(object)));
|
||||
} else if (c.equals(boolean[].class)) {
|
||||
b.append(Arrays.toString((boolean[]) f.get(object)));
|
||||
} else if (c.equals(long[].class)) {
|
||||
b.append(Arrays.toString((long[]) f.get(object)));
|
||||
} else if (c.equals(char[].class)) {
|
||||
b.append(Arrays.toString((char[]) f.get(object)));
|
||||
} else if (c.equals(byte[].class)) {
|
||||
b.append(Arrays.toString((byte[]) f.get(object)));
|
||||
} else if (c.equals(short[].class)) {
|
||||
b.append(Arrays.toString((short[]) f.get(object)));
|
||||
} else if (c.equals(float[].class)) {
|
||||
b.append(Arrays.toString((float[]) f.get(object)));
|
||||
} else if (c.equals(double[].class)) {
|
||||
b.append(Arrays.toString((double[]) f.get(object)));
|
||||
} else if (CharSequence.class.isAssignableFrom(c)) {
|
||||
b.append('"');
|
||||
b.append(f.get(object).toString());
|
||||
b.append('"');
|
||||
} else {
|
||||
b.append(f.get(object).toString());
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
b.append("ERROR");
|
||||
}
|
||||
if (i != (fields.length - 1)) {
|
||||
b.append(",\n");
|
||||
} else {
|
||||
b.append("\n");
|
||||
}
|
||||
}
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private MenuItem menu_item(String str) {
|
||||
MenuItem item = new MenuItem(str);
|
||||
item.addActionListener(this);
|
||||
return item;
|
||||
}
|
||||
|
||||
private static void show_window(Window w, Window parent) {
|
||||
w.setLocationRelativeTo(parent);
|
||||
w.toFront();
|
||||
w.requestFocus();
|
||||
w.setVisible(true);
|
||||
}
|
||||
|
||||
private static void set_clipbard(String str) {
|
||||
try {
|
||||
StringSelection sel = new StringSelection(str);
|
||||
Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard().setContents(sel, null);
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Couldn't set clipboard contents: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String cmd = e.getActionCommand();
|
||||
|
||||
if (cmd.equals("Done")) {
|
||||
try {
|
||||
ScriptEngine engine = manager.getEngineByExtension("js");
|
||||
engine.put("text", editor.getText());
|
||||
engine.put("config", config);
|
||||
engine.eval("var o = JSON.parse(text);"
|
||||
+ "\nfor (var p in o) {"
|
||||
+ "\n config[p] = o[p];"
|
||||
+ "\n}");
|
||||
frame.dispose();
|
||||
if (completion != null) {
|
||||
completion.run();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Error processing config: " + t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
} else if (cmd.equals("Save")) {
|
||||
FileDialog d = new FileDialog(frame, "Save configuration", FileDialog.SAVE);
|
||||
d.setFile(script_name + ".json");
|
||||
d.setIconImages(Constants.ICONS);
|
||||
show_window(d, frame);
|
||||
String dir = d.getDirectory();
|
||||
String file = d.getFile();
|
||||
if (dir != null && file != null) {
|
||||
try {
|
||||
Files.write(Paths.get(dir + file),
|
||||
editor.getText().getBytes(Constants.UTF_8));
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Write error: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (cmd.equals("Load")) {
|
||||
FileDialog d = new FileDialog(frame, "Load configuration", FileDialog.LOAD);
|
||||
d.setFile(script_name + ".json");
|
||||
d.setIconImages(Constants.ICONS);
|
||||
show_window(d, frame);
|
||||
String dir = d.getDirectory();
|
||||
String file = d.getFile();
|
||||
if (dir != null && file != null) {
|
||||
try {
|
||||
editor.setText(new String(
|
||||
Files.readAllBytes(Paths.get(dir + file)),
|
||||
Constants.UTF_8));
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Read error: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (cmd.equals("Cut")) {
|
||||
String str = editor.getText();
|
||||
String start = str.substring(0, editor.getSelectionStart());
|
||||
String end = str.substring(editor.getSelectionEnd(), str.length());
|
||||
set_clipbard(editor.getSelectedText());
|
||||
editor.setText(start + end);
|
||||
|
||||
} else if (cmd.equals("Copy")) {
|
||||
set_clipbard(editor.getSelectedText());
|
||||
|
||||
} else if (cmd.equals("Paste")) {
|
||||
try {
|
||||
editor.append((String) Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard().getContents(editor)
|
||||
.getTransferData(DataFlavor.stringFlavor));
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Couldn't paste: " + t);
|
||||
}
|
||||
|
||||
} else if (cmd.equals("Select all")) {
|
||||
String str = editor.getText();
|
||||
editor.select(0, str.length());
|
||||
|
||||
} else if (cmd.startsWith("Reset")) {
|
||||
editor.setText(create_json(config));
|
||||
|
||||
} else if (cmd.startsWith("Help")) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (help_contents != null) {
|
||||
for (String str : help_contents) {
|
||||
b.append(str);
|
||||
b.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
TextArea t = new TextArea(b.toString(), 0, 0,
|
||||
TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
t.setEditable(false);
|
||||
|
||||
final Dialog d = new Dialog(frame, "Script configuration help");
|
||||
d.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
d.setIconImages(Constants.ICONS);
|
||||
d.add(t, BorderLayout.CENTER);
|
||||
d.setSize(500, 400);
|
||||
show_window(d, frame);
|
||||
|
||||
} else if (cmd.equals("About")) {
|
||||
System.out.println("JSON script config editor by S");
|
||||
|
||||
} else if (cmd.equals("Exit")) {
|
||||
frame.dispose();
|
||||
|
||||
} else {
|
||||
System.out.println("unrecognized: " + cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.aposbot;
|
||||
|
||||
public final class LocalRouteCalc {
|
||||
|
||||
private final int[][] route_dir;
|
||||
private final int[] route_x;
|
||||
private final int[] route_y;
|
||||
|
||||
public LocalRouteCalc() {
|
||||
route_dir = new int[96][96];
|
||||
route_x = new int[8000];
|
||||
route_y = new int[8000];
|
||||
}
|
||||
|
||||
public int calculate(int[][] adjacency, int start_x, int start_y,
|
||||
int min_x, int min_y, int max_x, int max_y, boolean approximate) {
|
||||
final int route_dir[][] = this.route_dir;
|
||||
for (int k1 = 0; k1 < 96; k1++) {
|
||||
for (int l1 = 0; l1 < 96; l1++) {
|
||||
route_dir[k1][l1] = 0;
|
||||
}
|
||||
}
|
||||
final int[] route_x = this.route_x;
|
||||
final int[] route_y = this.route_y;
|
||||
int tail = 0;
|
||||
int head = 0;
|
||||
int x = start_x;
|
||||
int y = start_y;
|
||||
route_dir[start_x][start_y] = 99;
|
||||
route_x[tail] = start_x;
|
||||
route_y[tail++] = start_y;
|
||||
final int len = route_x.length;
|
||||
boolean success = false;
|
||||
while (head != tail) {
|
||||
x = route_x[head];
|
||||
y = route_y[head];
|
||||
head = (head + 1) % len;
|
||||
if (x >= min_x && x <= max_x && y >= min_y && y <= max_y) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
if (approximate) {
|
||||
if (x > 0 && x - 1 >= min_x && x - 1 <= max_x && y >= min_y && y <= max_y && (adjacency[x - 1][y] & 8) == 0) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
if (x < 95 && x + 1 >= min_x && x + 1 <= max_x && y >= min_y && y <= max_y && (adjacency[x + 1][y] & 2) == 0) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
if (y > 0 && x >= min_x && x <= max_x && y - 1 >= min_y && y - 1 <= max_y && (adjacency[x][y - 1] & 4) == 0) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
if (y < 95 && x >= min_x && x <= max_x && y + 1 >= min_y && y + 1 <= max_y && (adjacency[x][y + 1] & 1) == 0) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x > 0 && route_dir[x - 1][y] == 0 && (adjacency[x - 1][y] & 0x78) == 0) {
|
||||
route_x[tail] = x - 1;
|
||||
route_y[tail] = y;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x - 1][y] = 2;
|
||||
}
|
||||
if (x < 95 && route_dir[x + 1][y] == 0 && (adjacency[x + 1][y] & 0x72) == 0) {
|
||||
route_x[tail] = x + 1;
|
||||
route_y[tail] = y;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x + 1][y] = 8;
|
||||
}
|
||||
if (y > 0 && route_dir[x][y - 1] == 0 && (adjacency[x][y - 1] & 0x74) == 0) {
|
||||
route_x[tail] = x;
|
||||
route_y[tail] = y - 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x][y - 1] = 1;
|
||||
}
|
||||
if (y < 95 && route_dir[x][y + 1] == 0 && (adjacency[x][y + 1] & 0x71) == 0) {
|
||||
route_x[tail] = x;
|
||||
route_y[tail] = y + 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x][y + 1] = 4;
|
||||
}
|
||||
if (x > 0 && y > 0 && (adjacency[x][y - 1] & 0x74) == 0 && (adjacency[x - 1][y] & 0x78) == 0 && (adjacency[x - 1][y - 1] & 0x7c) == 0 && route_dir[x - 1][y - 1] == 0) {
|
||||
route_x[tail] = x - 1;
|
||||
route_y[tail] = y - 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x - 1][y - 1] = 3;
|
||||
}
|
||||
if (x < 95 && y > 0 && (adjacency[x][y - 1] & 0x74) == 0 && (adjacency[x + 1][y] & 0x72) == 0 && (adjacency[x + 1][y - 1] & 0x76) == 0 && route_dir[x + 1][y - 1] == 0) {
|
||||
route_x[tail] = x + 1;
|
||||
route_y[tail] = y - 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x + 1][y - 1] = 9;
|
||||
}
|
||||
if (x > 0 && y < 95 && (adjacency[x][y + 1] & 0x71) == 0 && (adjacency[x - 1][y] & 0x78) == 0 && (adjacency[x - 1][y + 1] & 0x79) == 0 && route_dir[x - 1][y + 1] == 0) {
|
||||
route_x[tail] = x - 1;
|
||||
route_y[tail] = y + 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x - 1][y + 1] = 6;
|
||||
}
|
||||
if (x < 95 && y < 95 && (adjacency[x][y + 1] & 0x71) == 0 && (adjacency[x + 1][y] & 0x72) == 0 && (adjacency[x + 1][y + 1] & 0x73) == 0 && route_dir[x + 1][y + 1] == 0) {
|
||||
route_x[tail] = x + 1;
|
||||
route_y[tail] = y + 1;
|
||||
tail = (tail + 1) % len;
|
||||
route_dir[x + 1][y + 1] = 12;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
return -1;
|
||||
}
|
||||
head = 0;
|
||||
route_x[head] = x;
|
||||
route_y[head++] = y;
|
||||
int _dir;
|
||||
for (int dir = _dir = route_dir[x][y]; x != start_x || y != start_y; dir = route_dir[x][y]) {
|
||||
if (dir != _dir) {
|
||||
_dir = dir;
|
||||
route_x[head] = x;
|
||||
route_y[head++] = y;
|
||||
}
|
||||
if ((dir & 2) != 0) {
|
||||
x++;
|
||||
} else if ((dir & 8) != 0) {
|
||||
x--;
|
||||
}
|
||||
if ((dir & 1) != 0) {
|
||||
y++;
|
||||
} else if ((dir & 4) != 0) {
|
||||
y--;
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.aposbot;
|
||||
|
||||
public final class RasterOps {
|
||||
|
||||
private RasterOps() {
|
||||
}
|
||||
|
||||
public static void fillRectAlpha(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y, int width, int height,
|
||||
int trans, int colour) {
|
||||
if (x < 0) {
|
||||
width -= 0 - x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
height -= 0 - y;
|
||||
y = 0;
|
||||
}
|
||||
if (x + width > rw) {
|
||||
width = rw - x;
|
||||
}
|
||||
if (y + height > rh) {
|
||||
height = rh - y;
|
||||
}
|
||||
final int a = 256 - trans;
|
||||
final int r = (colour >> 16 & 0xff) * trans;
|
||||
final int g = (colour >> 8 & 0xff) * trans;
|
||||
final int b = (colour & 0xff) * trans;
|
||||
final int l1 = rw - width;
|
||||
int p = x + y * rw;
|
||||
for (int j2 = 0; j2 < height; j2++ /* or skip */) {
|
||||
for (int k2 = -width; k2 < 0; k2++) {
|
||||
final int r_ = (pixels[p] >> 16 & 0xff) * a;
|
||||
final int g_ = (pixels[p] >> 8 & 0xff) * a;
|
||||
final int b_ = (pixels[p] & 0xff) * a;
|
||||
pixels[p++] = ((r + r_ >> 8) << 16) |
|
||||
((g + g_ >> 8) << 8) |
|
||||
(b + b_ >> 8);
|
||||
}
|
||||
p += l1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void fillRect(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y,
|
||||
int width, int height, int colour) {
|
||||
if (x < 0) {
|
||||
width -= 0 - x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
height -= 0 - y;
|
||||
y = 0;
|
||||
}
|
||||
if (x + width > rw) {
|
||||
width = rw - x;
|
||||
}
|
||||
if (y + height > rh) {
|
||||
height = rh - y;
|
||||
}
|
||||
final int i = rw - width;
|
||||
int j = x + y * rw;
|
||||
for (int k = -height; k < 0; k++ /* or skip */) {
|
||||
for (int l = -width; l < 0; l++) {
|
||||
pixels[j++] = colour;
|
||||
}
|
||||
j += i;
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawHLine(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y, int length, int colour) {
|
||||
if (y < 0 || y >= rh) {
|
||||
return;
|
||||
}
|
||||
if (x < 0) {
|
||||
length -= 0 - x;
|
||||
x = 0;
|
||||
}
|
||||
if (x + length > rw) {
|
||||
length = rw - x;
|
||||
}
|
||||
final int i = x + y * rw;
|
||||
for (int j = 0; j < length; j++) {
|
||||
pixels[i + j] = colour;
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawVLine(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y,
|
||||
int length, int colour) {
|
||||
if (x < 0 || x >= rw) {
|
||||
return;
|
||||
}
|
||||
if (y < 0) {
|
||||
length -= 0 - y;
|
||||
y = 0;
|
||||
}
|
||||
if (y + length > rw) {
|
||||
length = rh - y;
|
||||
}
|
||||
final int i = x + y * rw;
|
||||
for (int j = 0; j < length; j++) {
|
||||
pixels[i + j * rw] = colour;
|
||||
}
|
||||
}
|
||||
|
||||
public static void fillCircle(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y,
|
||||
int radius, int colour, int trans) {
|
||||
final int a = 256 - trans;
|
||||
final int r = (colour >> 16 & 0xff) * trans;
|
||||
final int g = (colour >> 8 & 0xff) * trans;
|
||||
final int b = (colour & 0xff) * trans;
|
||||
int start_y = y - radius;
|
||||
if (start_y < 0) {
|
||||
start_y = 0;
|
||||
}
|
||||
int end_y = y + radius;
|
||||
if (end_y >= rh) {
|
||||
end_y = rh - 1;
|
||||
}
|
||||
for (int _y = start_y; _y <= end_y; _y++ /* or skip */) {
|
||||
final int k2 = _y - y;
|
||||
final int l2 = (int) Math.sqrt(radius * radius - k2 * k2);
|
||||
int i3 = x - l2;
|
||||
if (i3 < 0) {
|
||||
i3 = 0;
|
||||
}
|
||||
int j3 = x + l2;
|
||||
if (j3 >= rw) {
|
||||
j3 = rw - 1;
|
||||
}
|
||||
int p = i3 + _y * rw;
|
||||
for (int l3 = i3; l3 <= j3; l3++) {
|
||||
final int r_ = (pixels[p] >> 16 & 0xff) * a;
|
||||
final int g_ = (pixels[p] >> 8 & 0xff) * a;
|
||||
final int b_ = (pixels[p] & 0xff) * a;
|
||||
pixels[p++] = ((r + r_ >> 8) << 16) |
|
||||
((g + g_ >> 8) << 8) |
|
||||
(b + b_ >> 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setPixel(int[] pixels,
|
||||
int rw, int rh,
|
||||
int x, int y, int colour) {
|
||||
if (x < 0 || y < 0 || x >= rw || y >= rh) {
|
||||
return;
|
||||
} else {
|
||||
pixels[x + y * rw] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class ScriptClassLoader extends ClassLoader {
|
||||
|
||||
private final HashMap<String, Class<?>> classes = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
final File file = new File(ScriptFrame.dir, name + ".class");
|
||||
if (!file.exists()) {
|
||||
return super.loadClass(name);
|
||||
}
|
||||
if (classes.containsKey(name)) {
|
||||
return classes.get(name);
|
||||
}
|
||||
final int len = (int) file.length();
|
||||
final byte[] b = new byte[len];
|
||||
FileInputStream in = null;
|
||||
int read = 0;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
do {
|
||||
final int i = in.read(b, read, len - read);
|
||||
if (i == -1)
|
||||
throw new EOFException();
|
||||
read += i;
|
||||
} while (read < len);
|
||||
} catch (final Throwable t) {
|
||||
throw new ClassNotFoundException(t.getMessage(), t);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (final IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
final Class<?> c = defineClass(name, b, 0, len);
|
||||
classes.put(name, c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
import com.aposbot._default.IClient;
|
||||
import com.aposbot._default.IScript;
|
||||
import com.aposbot._default.IScriptListener;
|
||||
|
||||
public final class ScriptFrame extends Frame {
|
||||
|
||||
private static final long serialVersionUID = -7439187170235715096L;
|
||||
private static final String PROCESSING_ERROR = "Error processing script. Send this output to the script's author:";
|
||||
static final File dir = new File("." + File.separator + "Scripts" + File.separator);
|
||||
|
||||
private ScriptEngineManager manager;
|
||||
private final java.awt.List displayed_list;
|
||||
private final TextField field;
|
||||
private final IClient client;
|
||||
|
||||
public ScriptFrame(IClient client) {
|
||||
super("Scripts");
|
||||
setFont(Constants.UI_FONT);
|
||||
|
||||
this.client = client;
|
||||
|
||||
setIconImages(Constants.ICONS);
|
||||
addWindowListener(new StandardCloseHandler(this, StandardCloseHandler.HIDE));
|
||||
|
||||
Panel fpanel = new Panel();
|
||||
fpanel.setLayout(new GridLayout(1, 0));
|
||||
Label l = new Label("Parameters:");
|
||||
l.setFont(Constants.UI_FONT);
|
||||
fpanel.add(l);
|
||||
fpanel.add(field = new TextField(""));
|
||||
field.setFont(Constants.UI_FONT);
|
||||
add(fpanel, BorderLayout.NORTH);
|
||||
|
||||
displayed_list = new java.awt.List();
|
||||
displayed_list.setFont(Constants.UI_FONT);
|
||||
final ScrollPane scroll = new ScrollPane();
|
||||
scroll.setFont(Constants.UI_FONT);
|
||||
scroll.add(displayed_list);
|
||||
add(scroll, BorderLayout.CENTER);
|
||||
|
||||
final Panel buttonPanel = new Panel();
|
||||
|
||||
final Button okButton = new Button("OK");
|
||||
okButton.setFont(Constants.UI_FONT);
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initScript();
|
||||
}
|
||||
}, "ScriptInit").start();
|
||||
}
|
||||
});
|
||||
buttonPanel.add(okButton);
|
||||
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.setFont(Constants.UI_FONT);
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
pack();
|
||||
setMinimumSize(getSize());
|
||||
|
||||
final Insets in = getInsets();
|
||||
|
||||
setSize(in.right + in.left + 310, in.top + in.bottom + 240);
|
||||
}
|
||||
|
||||
private void initScript() {
|
||||
final IScriptListener listener = client.getScriptListener();
|
||||
if (listener.isScriptRunning()) {
|
||||
System.out.println("Stop the script you are running first.");
|
||||
return;
|
||||
}
|
||||
listener.setIScript(null);
|
||||
System.gc();
|
||||
|
||||
final String selected_name = displayed_list.getSelectedItem();
|
||||
IScript script = null;
|
||||
if (selected_name.endsWith(".class")) {
|
||||
script = initJavaScript(selected_name);
|
||||
} else {
|
||||
script = initJSEScript(selected_name);
|
||||
}
|
||||
if (script == null) return;
|
||||
System.out.println("Selected script: " + script);
|
||||
try {
|
||||
script.init(field.getText());
|
||||
} catch (Throwable t) {
|
||||
System.out.println(PROCESSING_ERROR);
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
field.setText("");
|
||||
client.getScriptListener().setIScript(script);
|
||||
System.out.println("Press the \"Start script\" button to start it.");
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
private IScript initJSEScript(String name) {
|
||||
if (manager == null) {
|
||||
manager = new ScriptEngineManager();
|
||||
}
|
||||
int dot = name.indexOf('.');
|
||||
if (dot == -1) {
|
||||
System.out.println("Error: " + name + " has no file extension.");
|
||||
return null;
|
||||
}
|
||||
String ext = name.substring(dot + 1);
|
||||
ScriptEngine engine = manager.getEngineByExtension(ext);
|
||||
if (engine == null) {
|
||||
System.out.println("Error: No script engine found for " + ext);
|
||||
return null;
|
||||
}
|
||||
if (!(engine instanceof Invocable)) {
|
||||
System.out.println("Error: Engine for " + ext + " is not invocable.");
|
||||
}
|
||||
BufferedReader r = null;
|
||||
try {
|
||||
r = new BufferedReader(
|
||||
new InputStreamReader(
|
||||
new FileInputStream(new File(dir, name))
|
||||
, Constants.UTF_8
|
||||
)
|
||||
);
|
||||
engine.eval(r);
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Error loading script:");
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (r != null) {
|
||||
try {
|
||||
r.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return client.createInvocableScript((Invocable) engine, name);
|
||||
}
|
||||
|
||||
private IScript initJavaScript(String name) {
|
||||
Class<?> c;
|
||||
try {
|
||||
c = new ScriptClassLoader().loadClass(
|
||||
name.substring(0, name.length() - 6)
|
||||
);
|
||||
} catch (final ClassNotFoundException t) {
|
||||
System.out.println("Error loading script:");
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!IScript.class.isAssignableFrom(c)) {
|
||||
System.out.println("Error: " + name + " is not a valid Java script.");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (IScript) c.getConstructor(Class.forName("Extension")).newInstance(client);
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Failed to load script " + name + ":");
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
final String[] files = dir.list();
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
final java.util.List<String> list = new ArrayList<>();
|
||||
|
||||
final int len = files.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
final String name = files[i];
|
||||
if (new File(name).isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
if (name.endsWith(".java") ||
|
||||
name.indexOf('$') != -1 ||
|
||||
name.startsWith("_") ||
|
||||
name.indexOf('.') == -1) {
|
||||
continue;
|
||||
}
|
||||
list.add(name);
|
||||
}
|
||||
Collections.sort(list);
|
||||
|
||||
displayed_list.removeAll();
|
||||
for (final String str : list) {
|
||||
displayed_list.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
if (visible) {
|
||||
update();
|
||||
toFront();
|
||||
requestFocus();
|
||||
}
|
||||
super.setVisible(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
public final class StandardCloseHandler extends WindowAdapter {
|
||||
|
||||
public static final int HIDE = 0;
|
||||
public static final int EXIT = 1;
|
||||
public static final int DISPOSE = 2;
|
||||
|
||||
private final Window frame;
|
||||
private final int op;
|
||||
|
||||
public StandardCloseHandler(Frame frame, int op) {
|
||||
this.frame = frame;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public StandardCloseHandler(Dialog frame, int op) {
|
||||
this.frame = frame;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public StandardCloseHandler(Window frame, int op) {
|
||||
this.frame = frame;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
switch (op) {
|
||||
case HIDE:
|
||||
frame.setVisible(false);
|
||||
break;
|
||||
case EXIT:
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
System.exit(0);
|
||||
break;
|
||||
case DISPOSE:
|
||||
frame.dispose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.aposbot;
|
||||
|
||||
import java.awt.TextArea;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class TextAreaOutputStream extends OutputStream {
|
||||
|
||||
private final TextArea area;
|
||||
|
||||
public TextAreaOutputStream(TextArea area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
area.append(new String(new byte[] {
|
||||
(byte) b
|
||||
}).intern());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
area.append(new String(b, off, len));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) {
|
||||
area.append(new String(b));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
public interface IAutoLogin {
|
||||
|
||||
public void onLoginTick();
|
||||
|
||||
public void onWelcomeBoxTick();
|
||||
|
||||
public boolean isEnabled();
|
||||
|
||||
public void setEnabled(boolean b);
|
||||
|
||||
public void setAccount(String username, String password);
|
||||
|
||||
public void setBanned(boolean b);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
import java.applet.AppletStub;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.script.Invocable;
|
||||
|
||||
public interface IClient {
|
||||
|
||||
public Dimension getPreferredSize();
|
||||
|
||||
public void keyPressed(KeyEvent event);
|
||||
|
||||
public void setRendering(boolean enabled);
|
||||
|
||||
public boolean isRendering();
|
||||
|
||||
public void setAutoLogin(boolean b);
|
||||
|
||||
public void setKeysDisabled(boolean b);
|
||||
|
||||
public void stopScript();
|
||||
|
||||
public void takeScreenshot(String fileName);
|
||||
|
||||
public void setServer(int id);
|
||||
|
||||
public int getServer();
|
||||
|
||||
public int getCameraNSOffset();
|
||||
|
||||
public void setCameraNSOffset(int i);
|
||||
|
||||
public int getCameraEWOffset();
|
||||
|
||||
public void setCameraEWOffset(int i);
|
||||
|
||||
public int getCameraHeight();
|
||||
|
||||
public void setCameraHeight(int i);
|
||||
|
||||
public void setActionInd(int i);
|
||||
|
||||
public void closeWelcomeBox();
|
||||
|
||||
public int getLocalX();
|
||||
|
||||
public int getLocalY();
|
||||
|
||||
public void setLogoutTimer(int i);
|
||||
|
||||
public int getAreaX();
|
||||
|
||||
public int getAreaY();
|
||||
|
||||
public int getBaseLevel(int skill);
|
||||
|
||||
public int getCurrentLevel(int skill);
|
||||
|
||||
public double getExperience(int skill);
|
||||
|
||||
public int getCombatStyle();
|
||||
|
||||
public void setCombatStyle(int i);
|
||||
|
||||
public String[] getDialogOptions();
|
||||
|
||||
public int getDialogOptionCount();
|
||||
|
||||
public boolean isDialogVisible();
|
||||
|
||||
public void setDialogVisible(boolean b);
|
||||
|
||||
public boolean isSleeping();
|
||||
|
||||
public int getInventorySize();
|
||||
|
||||
public int getInventoryId(int i);
|
||||
|
||||
public int getInventoryStack(int i);
|
||||
|
||||
public boolean isBankVisible();
|
||||
|
||||
public void setBankVisible(boolean b);
|
||||
|
||||
public int getBankSize();
|
||||
|
||||
public int getBankId(int i);
|
||||
|
||||
public int getBankStack(int i);
|
||||
|
||||
public int getGroundItemCount();
|
||||
|
||||
public int getGroundItemLocalX(int i);
|
||||
|
||||
public int getGroundItemLocalY(int i);
|
||||
|
||||
public int getGroundItemId(int i);
|
||||
|
||||
public int getObjectCount();
|
||||
|
||||
public int getObjectLocalX(int i);
|
||||
|
||||
public int getObjectLocalY(int i);
|
||||
|
||||
public int getObjectId(int i);
|
||||
|
||||
public int getObjectDir(int i);
|
||||
|
||||
public int getBoundCount();
|
||||
|
||||
public int getBoundLocalX(int i);
|
||||
|
||||
public int getBoundLocalY(int i);
|
||||
|
||||
public int getBoundDir(int i);
|
||||
|
||||
public int getBoundId(int i);
|
||||
|
||||
public void typeChar(char key_char, int key_code);
|
||||
|
||||
public boolean isShopVisible();
|
||||
|
||||
public void setShopVisible(boolean b);
|
||||
|
||||
public int getShopSize();
|
||||
|
||||
public int getShopId(int i);
|
||||
|
||||
public int getShopStack(int i);
|
||||
|
||||
public boolean isEquipped(int slot);
|
||||
|
||||
public boolean isPrayerEnabled(int id);
|
||||
|
||||
public void setPrayerEnabled(int i, boolean flag);
|
||||
|
||||
public boolean isInTradeOffer();
|
||||
|
||||
public void setInTradeOffer(boolean b);
|
||||
|
||||
public boolean isInTradeConfirm();
|
||||
|
||||
public void setInTradeConfirm(boolean b);
|
||||
|
||||
public boolean hasLocalAcceptedTrade();
|
||||
|
||||
public boolean hasLocalConfirmedTrade();
|
||||
|
||||
public boolean hasRemoteAcceptedTrade();
|
||||
|
||||
public int getLocalTradeItemCount();
|
||||
|
||||
public int getLocalTradeItemId(int i);
|
||||
|
||||
public int getLocalTradeItemStack(int i);
|
||||
|
||||
public int getRemoteTradeItemCount();
|
||||
|
||||
public int getRemoteTradeItemId(int i);
|
||||
|
||||
public int getRemoteTradeItemStack(int i);
|
||||
|
||||
public int[] getPixels();
|
||||
|
||||
public int[][] getAdjacency();
|
||||
|
||||
public void drawString(String str, int x, int y, int size, int colour);
|
||||
|
||||
public void displayMessage(String str);
|
||||
|
||||
public void offerItemTrade(int slot, int amount);
|
||||
|
||||
public void login(String username, String password);
|
||||
|
||||
public void walkDirectly(int destLX, int destLY, boolean action);
|
||||
|
||||
public void walkAround(int destLX, int destLY);
|
||||
|
||||
public void walkToBound(int destLX, int destLY, int dir);
|
||||
|
||||
public void walkToObject(int destLX, int destLY, int dir, int id);
|
||||
|
||||
public void createPacket(int opcode);
|
||||
|
||||
public void put1(int val);
|
||||
|
||||
public void put2(int val);
|
||||
|
||||
public void put4(int val);
|
||||
|
||||
public void finishPacket();
|
||||
|
||||
public void sendCAPTCHA(String str);
|
||||
|
||||
public boolean isSkipLines();
|
||||
|
||||
public void setSkipLines(boolean flag);
|
||||
|
||||
public void sendPrivateMessage(String msg, String name);
|
||||
|
||||
public void addFriend(String str);
|
||||
|
||||
public void addIgnore(String str);
|
||||
|
||||
public void removeIgnore(String str);
|
||||
|
||||
public void removeFriend(String str);
|
||||
|
||||
public boolean isLoggedIn();
|
||||
|
||||
public int getQuestCount();
|
||||
|
||||
public String getQuestName(int i);
|
||||
|
||||
public boolean isQuestComplete(int i);
|
||||
|
||||
public Image getImage();
|
||||
|
||||
public double getFatigue();
|
||||
|
||||
public double getSleepingFatigue();
|
||||
|
||||
public int getPlayerCount();
|
||||
|
||||
public Object getPlayer();
|
||||
|
||||
public Object getPlayer(int index);
|
||||
|
||||
public String getPlayerName(Object mob);
|
||||
|
||||
public int getPlayerCombatLevel(Object mob);
|
||||
|
||||
public int getNpcCount();
|
||||
|
||||
public Object getNpc(int index);
|
||||
|
||||
public int getNpcId(Object mob);
|
||||
|
||||
public boolean isMobWalking(Object mob);
|
||||
|
||||
public boolean isMobTalking(Object mob);
|
||||
|
||||
public boolean isHeadIconVisible(Object mob);
|
||||
|
||||
public boolean isHpBarVisible(Object mob);
|
||||
|
||||
public int getMobBaseHitpoints(Object mob);
|
||||
|
||||
public int getMobServerIndex(Object mob);
|
||||
|
||||
public int getMobLocalX(Object mob);
|
||||
|
||||
public int getMobLocalY(Object mob);
|
||||
|
||||
public int getMobDirection(Object mob);
|
||||
|
||||
public boolean isMobInCombat(Object mob);
|
||||
|
||||
public IStaticAccess getStatic();
|
||||
|
||||
public IScriptListener getScriptListener();
|
||||
|
||||
public IAutoLogin getAutoLogin();
|
||||
|
||||
public IPaintListener getPaintListener();
|
||||
|
||||
public IJokerFOCR getJoker();
|
||||
|
||||
public IScript createInvocableScript(Invocable inv, String name);
|
||||
|
||||
public void stop();
|
||||
|
||||
public void init();
|
||||
|
||||
public void start();
|
||||
|
||||
public void setStub(AppletStub stub);
|
||||
|
||||
public void setFont(String name);
|
||||
|
||||
public int getCombatTimer();
|
||||
|
||||
public void resizeGame(int width, int height);
|
||||
|
||||
public int getGameWidth();
|
||||
|
||||
public int getGameHeight();
|
||||
|
||||
public void onLoggedIn();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
import com.aposbot.BotFrame;
|
||||
|
||||
public interface IClientInit {
|
||||
|
||||
public IClient createClient(BotFrame frame);
|
||||
|
||||
public IAutoLogin getAutoLogin();
|
||||
|
||||
public ISleepListener getSleepListener();
|
||||
|
||||
public IScriptListener getScriptListener();
|
||||
|
||||
public IPaintListener getPaintListener();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
public interface IJokerFOCR
|
||||
extends Closeable {
|
||||
|
||||
@Override
|
||||
public void close();
|
||||
|
||||
public void setFilePaths(String file_model, String file_dict);
|
||||
|
||||
public String getGuess();
|
||||
|
||||
public boolean loadNativeLibrary();
|
||||
|
||||
public boolean isLibraryLoaded();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
public interface IPaintListener {
|
||||
|
||||
public void onPaint();
|
||||
|
||||
public void resetDisplayedXp();
|
||||
|
||||
public boolean isPaintingEnabled();
|
||||
|
||||
public void setPaintingEnabled(boolean b);
|
||||
|
||||
public void setBanned(boolean b);
|
||||
|
||||
public void doResize(int w, int h);
|
||||
|
||||
public void setRenderTextures(boolean b);
|
||||
|
||||
public void setRenderSolid(boolean b);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
public interface IScript {
|
||||
|
||||
public void init(String params);
|
||||
|
||||
public int main();
|
||||
|
||||
public void paint();
|
||||
|
||||
public void onServerMessage(String str);
|
||||
|
||||
public void onTradeRequest(String name);
|
||||
|
||||
public void onChatMessage(String msg, String name, boolean mod,
|
||||
boolean admin);
|
||||
|
||||
public void onPrivateMessage(String msg, String name, boolean mod,
|
||||
boolean admin);
|
||||
|
||||
public void onKeyPress(int keycode);
|
||||
|
||||
public boolean isSleeping();
|
||||
|
||||
public int getFatigue();
|
||||
|
||||
public boolean isTricking();
|
||||
|
||||
public void logout();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
public interface IScriptListener {
|
||||
|
||||
public void onGameTick();
|
||||
|
||||
public void onPaintTick();
|
||||
|
||||
public void onKeyPress(int code);
|
||||
|
||||
public void onGameMessage(boolean flag, String s1, int i1, String s2, int j1, int k1, String s3,
|
||||
String s4);
|
||||
|
||||
public void onNewSleepWord();
|
||||
|
||||
public void setIScript(IScript script);
|
||||
|
||||
public void setScriptRunning(boolean b);
|
||||
|
||||
public boolean isScriptRunning();
|
||||
|
||||
public String getScriptName();
|
||||
|
||||
public boolean hasScript();
|
||||
|
||||
public void setBanned(boolean b);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
import com.aposbot.BotLoader;
|
||||
|
||||
public interface ISleepListener {
|
||||
|
||||
public void setSolver(BotLoader bl, String type);
|
||||
|
||||
public void onNewWord(byte[] data);
|
||||
|
||||
public String getGuess();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.aposbot._default;
|
||||
|
||||
public interface IStaticAccess {
|
||||
|
||||
public String getNpcName(int id);
|
||||
|
||||
public String getNpcDesc(int id);
|
||||
|
||||
public int getNpcLevel(int id);
|
||||
|
||||
public String getItemName(int id);
|
||||
|
||||
public String getItemDesc(int id);
|
||||
|
||||
public String getItemCommand(int id);
|
||||
|
||||
public int getItemBasePrice(int id);
|
||||
|
||||
public boolean isItemStackable(int id);
|
||||
|
||||
public boolean isItemTradable(int id);
|
||||
|
||||
public String getObjectName(int id);
|
||||
|
||||
public String getObjectDesc(int id);
|
||||
|
||||
public String getBoundName(int id);
|
||||
|
||||
public String getBoundDesc(int id);
|
||||
|
||||
public int getSpellReqLevel(int id);
|
||||
|
||||
public int getSpellType(int i);
|
||||
|
||||
public int getReagentCount(int id);
|
||||
|
||||
public int getReagentId(int spell, int i);
|
||||
|
||||
public int getReagentAmount(int spell, int i);
|
||||
|
||||
public int getFriendCount();
|
||||
|
||||
public String getFriendName(int i);
|
||||
|
||||
public int getIgnoredCount();
|
||||
|
||||
public String getIgnoredName(int i);
|
||||
|
||||
public int getPrayerCount();
|
||||
|
||||
public int getPrayerLevel(int i);
|
||||
|
||||
public String getPrayerName(int i);
|
||||
|
||||
public String[] getSpellNames();
|
||||
|
||||
public String[] getSkillNames();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.aposbot.applet;
|
||||
|
||||
import java.applet.AudioClip;
|
||||
import java.net.URL;
|
||||
|
||||
public class AVClip
|
||||
implements AudioClip {
|
||||
|
||||
private static final byte STATE_PLAYING = 0;
|
||||
private static final byte STATE_LOOPING = 1;
|
||||
private static final byte STATE_STOPPED = 2;
|
||||
private byte state;
|
||||
private final URL url;
|
||||
|
||||
AVClip(URL url) {
|
||||
this.url = url;
|
||||
state = STATE_STOPPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
state = STATE_PLAYING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loop() {
|
||||
state = STATE_LOOPING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
state = STATE_STOPPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == null) {
|
||||
return false;
|
||||
}
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof AVClip) {
|
||||
final AVClip cmp = (AVClip) object;
|
||||
return (cmp.url.equals(url) && cmp.state == state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.aposbot.applet;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.applet.AppletContext;
|
||||
import java.applet.AudioClip;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
public class AVContext
|
||||
implements AppletContext {
|
||||
|
||||
private Map<String, InputStream> streamMap;
|
||||
private final Applet applet;
|
||||
private Toolkit toolkit;
|
||||
|
||||
AVContext(Applet applet) {
|
||||
this.applet = applet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioClip getAudioClip(URL url) {
|
||||
return new AVClip(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage(URL url) {
|
||||
if (toolkit == null) {
|
||||
toolkit = Toolkit.getDefaultToolkit();
|
||||
}
|
||||
return toolkit.getImage(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Applet getApplet(String name) {
|
||||
if (applet.getName().equals(name)) {
|
||||
return applet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Applet> getApplets() {
|
||||
final Vector<Applet> applets = new Vector<Applet>();
|
||||
applets.add(applet);
|
||||
return applets.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDocument(URL url) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDocument(URL url, String target) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showStatus(String status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStream(String key, InputStream stream) throws IOException {
|
||||
if (streamMap == null) {
|
||||
streamMap = new HashMap<String, InputStream>();
|
||||
}
|
||||
streamMap.put(key, stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getStream(String key) {
|
||||
if (streamMap == null) {
|
||||
streamMap = new HashMap<String, InputStream>();
|
||||
}
|
||||
return streamMap.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getStreamKeys() {
|
||||
return streamMap.keySet().iterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.aposbot.applet;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.applet.AppletContext;
|
||||
import java.applet.AppletStub;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
public class AVStub
|
||||
implements AppletStub {
|
||||
|
||||
private final Applet applet;
|
||||
private URL docBase;
|
||||
private URL codeBase;
|
||||
private final Map<String, String> params;
|
||||
private AVContext context;
|
||||
private boolean active;
|
||||
|
||||
public AVStub(Applet applet, URL docBase, URL codeBase, Map<String, String> params) {
|
||||
this.applet = applet;
|
||||
this.docBase = docBase;
|
||||
this.codeBase = codeBase;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDocumentBase() {
|
||||
return docBase;
|
||||
}
|
||||
|
||||
// unsafe
|
||||
public void setDocumentBase(URL url) {
|
||||
docBase = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getCodeBase() {
|
||||
return codeBase;
|
||||
}
|
||||
|
||||
// unsafe
|
||||
public void setCodeBase(URL url) {
|
||||
codeBase = url;
|
||||
}
|
||||
|
||||
public void setParameter(String key, String value) {
|
||||
params.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
return params.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppletContext getAppletContext() {
|
||||
if (context == null) {
|
||||
context = new AVContext(applet);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appletResize(int width, int height) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class DictSearch {
|
||||
|
||||
private final List<String> words;
|
||||
|
||||
public DictSearch(List<String> words) {
|
||||
this.words = words;
|
||||
}
|
||||
|
||||
public DictSearch(BufferedReader r) throws IOException {
|
||||
words = new ArrayList<String>();
|
||||
String line;
|
||||
while ((line = r.readLine()) != null) {
|
||||
words.add(line);
|
||||
}
|
||||
}
|
||||
|
||||
String getMatch(int len, double strProb[][]) {
|
||||
final int listSize = words.size();
|
||||
int result = -1;
|
||||
double best = -1;
|
||||
double cur;
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
final String str = words.get(i);
|
||||
if (str.length() != len) {
|
||||
continue;
|
||||
}
|
||||
cur = 0;
|
||||
for (int j = 0; j < len; ++j) {
|
||||
cur += Math.pow(strProb[j][str.charAt(j) - 'a'], 2);
|
||||
}
|
||||
if (cur > best) {
|
||||
best = cur;
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
if (result == -1) {
|
||||
return "unknown";
|
||||
}
|
||||
return words.get(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
class ImageTransform {
|
||||
|
||||
class ITHelperFuncs {
|
||||
|
||||
Point basePoint;
|
||||
|
||||
boolean sortPointFunc(Point p1, Point p2) {
|
||||
|
||||
/*
|
||||
* Let the basepoint be P0. P1 < P2 if the angle between P0P1 and Ox
|
||||
* is smaller than the angle between P0P2 and Ox or if the angles
|
||||
* are equal and P1 is farther than P2 from P0. This will let me
|
||||
* eliminate quickly the points with the same angle
|
||||
*/
|
||||
|
||||
int y1, x1, x2, y2;
|
||||
|
||||
x1 = p1.x - basePoint.x;
|
||||
y1 = p1.y - basePoint.y;
|
||||
|
||||
x2 = p2.x - basePoint.x;
|
||||
y2 = p2.y - basePoint.y;
|
||||
|
||||
if (y1 * x2 < y2 * x1) {
|
||||
return true;
|
||||
}
|
||||
if (y1 * x2 == y2 * x1) {
|
||||
return (x1 * x1 + y1 * y1 > x2 * x2 + y2 * y2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean areEqual(Point p1, Point p2) {
|
||||
int y1, x1, x2, y2;
|
||||
|
||||
x1 = p1.x - basePoint.x;
|
||||
y1 = p1.y - basePoint.y;
|
||||
|
||||
x2 = p2.x - basePoint.x;
|
||||
y2 = p2.y - basePoint.y;
|
||||
|
||||
return (y1 * x2 == y2 * x1);
|
||||
}
|
||||
}
|
||||
|
||||
private ITHelperFuncs ithelperfuncs = new ITHelperFuncs();
|
||||
|
||||
static int info(Point P0, Point P1, Point P2) {
|
||||
return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y);
|
||||
}
|
||||
|
||||
static Rectangle getMinAreaRectangle(Point p0, Point p1, ArrayList<Point> points) {
|
||||
Rectangle res = new Rectangle();
|
||||
res.area = -1.f;
|
||||
|
||||
// this function assumes that P0 P1 is a segment from the convex hull
|
||||
// !!!
|
||||
|
||||
Line baseLine = new Line();
|
||||
Line baseLineParallel;
|
||||
Line perpendicular1, perpendicular2;
|
||||
baseLine.init(p0, p1);
|
||||
|
||||
// now get the point that is farthest to the line
|
||||
double distance = baseLine.getDistance(points.get(0));
|
||||
int index = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < points.size(); i++) {
|
||||
double tmpDistance = baseLine.getDistance(points.get(i));
|
||||
if (distance < tmpDistance) {
|
||||
distance = tmpDistance;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// now index is the index of the farthest point from the line P0 P1
|
||||
if (distance < 10e-6) { // the distance is 0
|
||||
// error
|
||||
return res;
|
||||
}
|
||||
|
||||
// if distance != 0 then draw a parallel line through the point
|
||||
|
||||
baseLineParallel = baseLine.getParallel(points.get(index));
|
||||
|
||||
// now get a perpendicular on baseline and keep the points with the
|
||||
// smallest and the greatest signed distance
|
||||
|
||||
Line perp;
|
||||
|
||||
perp = baseLine.getPerpendicular(points.get(index));
|
||||
|
||||
// scan for the point with the smallest and greatest signed distance
|
||||
|
||||
int indexMin;
|
||||
int indexMax;
|
||||
double distMin;
|
||||
double distMax;
|
||||
|
||||
indexMin = 0;
|
||||
indexMax = 0;
|
||||
distMin = perp.getSignedDistance(points.get(indexMin));
|
||||
distMax = perp.getSignedDistance(points.get(indexMax));
|
||||
|
||||
for (i = 0; i < points.size(); i++) {
|
||||
double tmpDist = perp.getSignedDistance(points.get(i));
|
||||
if (distMin > tmpDist) {
|
||||
distMin = tmpDist;
|
||||
indexMin = i;
|
||||
}
|
||||
|
||||
if (distMax < tmpDist) {
|
||||
distMax = tmpDist;
|
||||
indexMax = i;
|
||||
}
|
||||
}
|
||||
|
||||
// we now have the 2 points
|
||||
|
||||
perpendicular1 = perp.getParallel(points.get(indexMin));
|
||||
perpendicular2 = perp.getParallel(points.get(indexMax));
|
||||
|
||||
res.l1 = baseLine;
|
||||
res.l2 = baseLineParallel;
|
||||
res.p1 = perpendicular1;
|
||||
res.p2 = perpendicular2;
|
||||
res.area = (distMax - distMin) * distance;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
Rectangle getMinAreaRectangle(ArrayList<Point> points) {
|
||||
points = getConvexHull(points);
|
||||
|
||||
Rectangle res = new Rectangle();
|
||||
res.area = -1.f;
|
||||
|
||||
if (points.size() <= 2) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < points.size() - 2; i++) {
|
||||
Rectangle tmp = getMinAreaRectangle(points.get(i),
|
||||
points.get(i + 1), points);
|
||||
if (tmp.area > 0) {
|
||||
if (res.area < 0) {
|
||||
res = tmp;
|
||||
} else {
|
||||
if (res.area > tmp.area) {
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now consider the last point and the first point
|
||||
Rectangle tmp = getMinAreaRectangle(points.get(points.size() - 1),
|
||||
points.get(0), points);
|
||||
if (tmp.area > 0) {
|
||||
if (res.area < 0) {
|
||||
res = tmp;
|
||||
} else {
|
||||
if (res.area > tmp.area) {
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ArrayList<Point> getConvexHull(ArrayList<Point> points) {
|
||||
/*
|
||||
* this function implements the Graham's scan algorithm for finding the
|
||||
* convex hull. Here is a link to some explanation:
|
||||
* http://en.wikipedia.org/wiki/Graham_scan
|
||||
*/
|
||||
|
||||
ArrayList<Point> result = new ArrayList<Point>();
|
||||
|
||||
// check to see if we have any points
|
||||
if (points.isEmpty())
|
||||
return result;
|
||||
|
||||
// first find the lowest, leftmost point
|
||||
ithelperfuncs.basePoint = points.get(0);
|
||||
|
||||
for (Point it : points) {
|
||||
if (ithelperfuncs.basePoint.y >= it.y) {
|
||||
// check for strict inequality
|
||||
if (ithelperfuncs.basePoint.y > it.y) {
|
||||
ithelperfuncs.basePoint = it;
|
||||
} else {
|
||||
if (ithelperfuncs.basePoint.x > it.x) {
|
||||
ithelperfuncs.basePoint = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now remove the basePoint
|
||||
|
||||
for (Point it : points) {
|
||||
if (!ithelperfuncs.basePoint.equals(it)) {
|
||||
result.add(it);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX
|
||||
// std::make_heap(result.begin(), result.end(), ITHelperFuncs::sortPointFunc);
|
||||
// std::sort_heap(result.begin(), result.end(), ITHelperFuncs::sortPointFunc);
|
||||
|
||||
points.clear();
|
||||
|
||||
Point current;
|
||||
|
||||
if (result.isEmpty()) {
|
||||
//there is no point left
|
||||
//push the basepoint into result and return
|
||||
result.add(ithelperfuncs.basePoint);
|
||||
return result;
|
||||
}
|
||||
|
||||
PriorityQueue<Point> queue = new PriorityQueue<>(result.size(), new Comparator<Point>() {
|
||||
@Override
|
||||
public int compare(Point o1, Point o2) {
|
||||
if (ithelperfuncs.sortPointFunc(o1, o2)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
for (Point p : result) {
|
||||
queue.add(p);
|
||||
}
|
||||
result.clear();
|
||||
for (Point p : queue) {
|
||||
result.add(p);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
current = result.get(index);
|
||||
points.add(current);
|
||||
|
||||
do {
|
||||
if (!ithelperfuncs.areEqual(current, result.get(index))) {
|
||||
current = result.get(index);
|
||||
points.add(current);
|
||||
}
|
||||
++index;
|
||||
} while (index != result.size());
|
||||
|
||||
index = 0;
|
||||
|
||||
result.clear();
|
||||
|
||||
result.add(ithelperfuncs.basePoint);
|
||||
|
||||
result.add(points.get(index));
|
||||
++index;
|
||||
// result.add(new Point(points.get(index)));
|
||||
|
||||
while (index != points.size()) {
|
||||
if (info(result.get(result.size() - 2),
|
||||
result.get(result.size() - 1), points.get(index)) > 0) {
|
||||
// the new point should be included into the hull
|
||||
result.add(points.get(index));
|
||||
index++;
|
||||
} else {
|
||||
// pop a point from the stack
|
||||
result.remove(result.size() - 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
interface JoiningCriterionT {
|
||||
|
||||
public boolean joinCritFunc(Region r1, Region r2);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.stormy.ocrlib.svm.svm;
|
||||
import com.stormy.ocrlib.svm.svm_node;
|
||||
|
||||
final class Letter extends Region {
|
||||
|
||||
private Letter(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
Letter(SimpleImage letter) {
|
||||
super(letter);
|
||||
}
|
||||
|
||||
static List<Letter> splitLetters(SimpleImage image) {
|
||||
final ArrayList<Letter> list = new ArrayList<Letter>();
|
||||
final int h = image.Height();
|
||||
int start = -1;
|
||||
for (int x = 0; x < image.Width(); ++x) {
|
||||
if (rowContainsColour(image, x)) {
|
||||
if (start == -1) {
|
||||
start = x;
|
||||
}
|
||||
} else {
|
||||
if (start == -1) {
|
||||
continue;
|
||||
}
|
||||
final int w = x - start;
|
||||
if (w > 5) {
|
||||
final Letter letter = new Letter(w, h);
|
||||
letter.copy(image, x, 0, w, h, 0, 0);
|
||||
list.add(letter);
|
||||
start = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static boolean rowContainsColour(SimpleImage image, int x) {
|
||||
for (int y = 0; y < image.Height(); ++y) {
|
||||
if (image.getPixel(x, y) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void guess(OCR ocr, int idxInStr) {
|
||||
final svm_node svmNode[] = toSvmNode();
|
||||
|
||||
final int labels[] = ocr.labels;
|
||||
|
||||
final double charProb[] = ocr.charProb;
|
||||
|
||||
svm.svm_get_labels(ocr.model, labels);
|
||||
svm.svm_predict_probability(ocr.model, svmNode, charProb);
|
||||
|
||||
final double probs[] = ocr.strProb[idxInStr];
|
||||
|
||||
for (int i = 0; i < probs.length; i++) {
|
||||
probs[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < charProb.length; i++) {
|
||||
probs[/* 'a' + */labels[i]] = charProb[i];
|
||||
}
|
||||
}
|
||||
|
||||
char getBestGuess(OCR ocr, int idxInStr) {
|
||||
guess(ocr, idxInStr);
|
||||
final double charProb[] = ocr.charProb;
|
||||
int index = 0;
|
||||
for (int i = 0; i < charProb.length; i++) {
|
||||
if (charProb[i] > charProb[index]) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return (char) (ocr.labels[index] + 'a');
|
||||
}
|
||||
|
||||
private svm_node[] toSvmNode() {
|
||||
int pixelCount = 0;
|
||||
final int width = Width();
|
||||
final int height = Height();
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
if (getPixel(x, y) != 0) {
|
||||
pixelCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
final svm_node output[] = new svm_node[pixelCount + 1];
|
||||
for (int i = 0; i < output.length; ++i) {
|
||||
output[i] = new svm_node();
|
||||
}
|
||||
int pos = 0;
|
||||
double max = -1.;
|
||||
double min = 256.;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
if (getPixel(x, y) != 0) {
|
||||
output[pos].index = y * width + x + 1;
|
||||
output[pos].value = getPixel(x, y) / 255.f;
|
||||
if (max < output[pos].value) {
|
||||
max = output[pos].value;
|
||||
}
|
||||
if (min > output[pos].value) {
|
||||
min = output[pos].value;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
output[pos].index = -1;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public final class LetterComparator implements Comparator<Region> {
|
||||
|
||||
@Override
|
||||
public int compare(Region r1, Region r2) {
|
||||
if (r1.OffsetX() < r2.OffsetX()) {
|
||||
return -1;
|
||||
} else if (r1.OffsetX() > r2.OffsetX()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof LetterComparator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
final class Line {
|
||||
|
||||
// the equation is ax + by + c = 0
|
||||
private int a, b, c;
|
||||
|
||||
// creates the line that passes between those two points
|
||||
boolean init(Point p1, Point p2) {
|
||||
if (p1 == p2) {
|
||||
a = 1;
|
||||
b = 0;
|
||||
c = -p1.x;
|
||||
return true;
|
||||
|
||||
}
|
||||
a = p1.y - p2.y;
|
||||
b = p2.x - p1.x;
|
||||
c = p1.x * p2.y - p1.y * p2.x;
|
||||
|
||||
if ((a == 0) && (b == 0) && (c == 0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if "p" is contained by the line
|
||||
boolean isOnLine(Point p) {
|
||||
int res = a * p.x + b * p.y + c;
|
||||
|
||||
return (res == 0);
|
||||
}
|
||||
|
||||
// returns a line parallel to this line and passes through the point "p"
|
||||
Line getParallel(Point p) {
|
||||
Line tmp = new Line();
|
||||
|
||||
tmp.a = a;
|
||||
tmp.b = b;
|
||||
tmp.c = -tmp.a * p.x - tmp.b * p.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// returns a line that is perpendicular to this line and passes through "p"
|
||||
Line getPerpendicular(Point p) {
|
||||
Line tmp = new Line();
|
||||
|
||||
tmp.a = -b;
|
||||
tmp.b = a;
|
||||
tmp.c = -tmp.a * p.x - tmp.b * p.y;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// returns 0 if p is on the line, +1 if p is in one semiplane and -1 if it
|
||||
// is in the other
|
||||
int getSign(Point p) {
|
||||
int tmp = a * p.x + b * p.y + c;
|
||||
|
||||
if (tmp < 0)
|
||||
return -1;
|
||||
if (tmp > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void translate(int deltaX, int deltaY) {
|
||||
c -= deltaX * a + deltaY * b;
|
||||
}
|
||||
|
||||
// gets the distance between those two lines (they have to be parallel)
|
||||
double getDistance(Line l) {
|
||||
double x, y;
|
||||
|
||||
// choose a point on the line
|
||||
if (b != 0) {
|
||||
x = 0.f;
|
||||
y = (double) (-c) / (double) b;
|
||||
} else {
|
||||
y = 0.f;
|
||||
x = (double) (-c) / (double) a;
|
||||
}
|
||||
|
||||
return Math.abs((double) a * (double) x + (double) b * (double) y
|
||||
+ (double) c)
|
||||
/ Math.sqrt((double) a * (double) a + (double) b * (double) b);
|
||||
}
|
||||
|
||||
double getSignedDistance(Point p) {
|
||||
return ((double) a * (double) p.x + (double) b * (double) p.y + (double) c)
|
||||
/ Math.sqrt((double) a * (double) a + (double) b * (double) b);
|
||||
}
|
||||
|
||||
double getDistance(Point p) {
|
||||
return Math.abs(getSignedDistance(p));
|
||||
}
|
||||
|
||||
Point intersect(Line l) {
|
||||
double x, y;
|
||||
x = ((double) c * (double) l.b - (double) l.c * (double) b)
|
||||
/ ((double) l.a * (double) b - (double) a * (double) l.b);
|
||||
y = ((double) c * (double) l.a - (double) l.c * (double) a)
|
||||
/ ((double) a * (double) l.b - (double) l.a * (double) b);
|
||||
|
||||
return new Point((int) x, (int) y);
|
||||
}
|
||||
|
||||
double angle() {
|
||||
|
||||
if (b == 0)
|
||||
return 0.0;
|
||||
|
||||
if (a == 0) {
|
||||
if (b > 0)
|
||||
return Math.acos(0.0);
|
||||
return -Math.acos(0.0);
|
||||
}
|
||||
|
||||
return Math.atan(-(double) b / (double) a);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.stormy.ocrlib.svm.svm;
|
||||
import com.stormy.ocrlib.svm.svm_model;
|
||||
|
||||
public final class OCR {
|
||||
|
||||
private static final int MAX_WORD_LEN = 30;
|
||||
private static final Segmentor s = new Segmentor();
|
||||
private final DictSearch dictSearch;
|
||||
svm_model model;
|
||||
double strProb[][];
|
||||
double charProb[];
|
||||
int labels[];
|
||||
|
||||
public OCR(DictSearch dictSearch, BufferedReader modelReader)
|
||||
throws OCRException, IOException {
|
||||
this.dictSearch = dictSearch;
|
||||
model = svm.svm_load_model(modelReader);
|
||||
if (model == null) {
|
||||
throw new OCRException();
|
||||
}
|
||||
final int n = model.nr_class;
|
||||
strProb = new double[MAX_WORD_LEN][n];
|
||||
labels = new int[n];
|
||||
charProb = new double[n];
|
||||
}
|
||||
|
||||
public String guess(SimpleImage image, boolean dict) {
|
||||
return guess_old(image, dict);
|
||||
}
|
||||
|
||||
public String guess_old(SimpleImage image, boolean dict) {
|
||||
final List<Letter> split = Letter.splitLetters(image);
|
||||
final int len = split.size();
|
||||
if (dict) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
final Letter letter = split.get(i);
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
letter.guess(this, i);
|
||||
}
|
||||
return dictSearch.getMatch(len, strProb);
|
||||
} else {
|
||||
char[] ch = new char[len];
|
||||
for (int i = 0; i < len; ++i) {
|
||||
final Letter letter = split.get(i);
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
ch[i] = letter.getBestGuess(this, i);
|
||||
}
|
||||
return new String(ch);
|
||||
}
|
||||
}
|
||||
|
||||
public String guess_new(SimpleImage image, boolean dict) {
|
||||
s.process(image);
|
||||
final List<Letter> split = Letter.splitLetters(image);
|
||||
final int len = split.size();
|
||||
if (dict) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
final Letter letter = new Letter(s.getLetter(i, true));
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
letter.guess(this, i);
|
||||
}
|
||||
return dictSearch.getMatch(len, strProb);
|
||||
} else {
|
||||
char[] ch = new char[len];
|
||||
for (int i = 0; i < len; ++i) {
|
||||
final Letter letter = new Letter(s.getLetter(i, true));
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
ch[i] = letter.getBestGuess(this, i);
|
||||
}
|
||||
return new String(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
public class OCRException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -3043287754156453842L;
|
||||
|
||||
public OCRException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OCRException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OCRException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public OCRException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
final class Point {
|
||||
|
||||
final int x, y;
|
||||
|
||||
Point() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
Point(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (!(object instanceof Point)) return false;
|
||||
Point p = (Point) object;
|
||||
if (p == this) return true;
|
||||
return p.x == x && p.y == y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Point [x=%s, y=%s]", x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
final class Rectangle {
|
||||
|
||||
Line l1, l2, p1, p2;
|
||||
double area;
|
||||
|
||||
Rectangle(Rectangle r) {
|
||||
l1 = r.l1;
|
||||
l2 = r.l2;
|
||||
p1 = r.p1;
|
||||
p2 = r.p2;
|
||||
area = r.area;
|
||||
}
|
||||
|
||||
Rectangle() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
class Region extends SimpleImage {
|
||||
|
||||
private final int offset_x;
|
||||
private final int offset_y;
|
||||
|
||||
Region(int width, int height) {
|
||||
super(width, height);
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
}
|
||||
|
||||
Region(int w, int h, int ox, int oy) {
|
||||
super(w, h);
|
||||
offset_x = ox;
|
||||
offset_y = oy;
|
||||
}
|
||||
|
||||
Region(SimpleImage image) {
|
||||
super(image);
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
}
|
||||
|
||||
int OffsetX() {
|
||||
return offset_x;
|
||||
}
|
||||
|
||||
int OffsetY() {
|
||||
return offset_y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Region [offset_x=%s, offset_y=%s]", offset_x,
|
||||
offset_y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
final class RegionOverlapCriterion implements JoiningCriterionT {
|
||||
|
||||
private static double overlap(Region r1, Region r2) {
|
||||
int oX;
|
||||
|
||||
int r1minX = r1.OffsetX();
|
||||
int r1maxX = r1.OffsetX() + r1.Width();
|
||||
|
||||
int r2minX = r2.OffsetX();
|
||||
int r2maxX = r2.OffsetX() + r2.Width();
|
||||
|
||||
if (r1maxX < r2minX)
|
||||
return 0;
|
||||
if (r1minX > r2maxX)
|
||||
return 0;
|
||||
|
||||
if (r1minX >= r2minX) {
|
||||
if (r1maxX <= r2maxX) {
|
||||
oX = r1maxX - r1minX + 1;
|
||||
} else {
|
||||
oX = r2maxX - r1minX + 1;
|
||||
}
|
||||
} else {
|
||||
if (r1maxX <= r2maxX) {
|
||||
oX = r1maxX - r2minX + 1;
|
||||
} else {
|
||||
oX = r2maxX - r2minX + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (double) oX / (r2maxX - r2minX + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean joinCritFunc(Region r1, Region r2) {
|
||||
double overlapFactor = 0.3;
|
||||
return ((overlap(r1, r2) >= overlapFactor) || (overlap(r2, r1) >= overlapFactor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof RegionOverlapCriterion;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
final class Segmentor {
|
||||
|
||||
private ArrayList<Region> letters = new ArrayList<>();
|
||||
private final ArrayList<Rectangle> rectangles = new ArrayList<>();
|
||||
private ImageTransform imt = new ImageTransform();
|
||||
private static final JoiningCriterionT smallRegionsCrowdingCriterion = new SmallRegionsCrowdingCriterion();
|
||||
private static final JoiningCriterionT regionOverlapCriterion = new RegionOverlapCriterion();
|
||||
private static final LetterComparator letterComparator = new LetterComparator();
|
||||
|
||||
Rectangle getRectangle(int imageNo) {
|
||||
Rectangle tmp = new Rectangle();
|
||||
tmp.area = -1.f;
|
||||
|
||||
if (imageNo < 0)
|
||||
return tmp;
|
||||
if (imageNo >= letters.size())
|
||||
return tmp;
|
||||
|
||||
Rectangle r = new Rectangle(rectangles.get(imageNo));
|
||||
if (r.area < 0)
|
||||
return r;
|
||||
int deltaX, deltaY;
|
||||
deltaX = letters.get(imageNo).OffsetX();
|
||||
deltaY = letters.get(imageNo).OffsetY();
|
||||
r.l1.translate(deltaX, deltaY);
|
||||
r.l2.translate(deltaX, deltaY);
|
||||
r.p1.translate(deltaX, deltaY);
|
||||
r.p2.translate(deltaX, deltaY);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void process(SimpleImage im) {
|
||||
letters.clear();
|
||||
rectangles.clear();
|
||||
|
||||
SimpleImage tmpIm = new SimpleImage(im);
|
||||
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < im.Height(); i++) {
|
||||
for (j = 0; j < im.Width(); j++) {
|
||||
if (tmpIm.getPixel(j, i) == 255) {
|
||||
// find the region
|
||||
Region r = tmpIm.extract(j, i, true);
|
||||
|
||||
// remove it from the image
|
||||
tmpIm.remove(r);
|
||||
|
||||
// push the region on the vector
|
||||
letters.add(r);
|
||||
|
||||
// now find the rectangle
|
||||
rectangles.add(getRegionRectangle(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
joinRegions(smallRegionsCrowdingCriterion);
|
||||
joinRegions(regionOverlapCriterion);
|
||||
|
||||
Collections.sort(letters, letterComparator);
|
||||
System.out.println(letters.size());
|
||||
|
||||
buildRectangles();
|
||||
}
|
||||
|
||||
void joinRegions(JoiningCriterionT joinCritFunc) {
|
||||
ArrayList<Integer> rids = new ArrayList<>(letters.size());
|
||||
|
||||
int i;
|
||||
for (i = 0; i < letters.size(); i++) {
|
||||
rids.add(i);
|
||||
}
|
||||
|
||||
int j;
|
||||
for (i = 0; i < letters.size(); i++) {
|
||||
for (j = i + 1; j < letters.size(); j++) {
|
||||
if (joinCritFunc.joinCritFunc(letters.get(i), letters.get(j))) {
|
||||
rids.set(j, rids.get(j) < rids.get(i) ?
|
||||
rids.get(j) : rids.get(i));
|
||||
rids.set(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_ids(rids);
|
||||
}
|
||||
|
||||
void collapse_ids(ArrayList<Integer> regionId) {
|
||||
if (regionId.size() != letters.size())
|
||||
return;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayList<Region>[] regList = new ArrayList[letters.size()];
|
||||
for (int i = 0; i < regList.length; ++i) {
|
||||
regList[i] = new ArrayList<>();
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < letters.size(); i++) {
|
||||
regList[i].clear();
|
||||
}
|
||||
|
||||
// now fill regList
|
||||
|
||||
for (i = 0; i < regionId.size(); i++) {
|
||||
regList[regionId.get(i)].add(letters.get(i));
|
||||
}
|
||||
|
||||
// now collapse the regions
|
||||
ArrayList<Region> tmpLetters = new ArrayList<Region>();
|
||||
|
||||
for (i = 0; i < regionId.size(); i++) {
|
||||
if (regList[i].size() > 0) {
|
||||
tmpLetters.add(collapse_regions(regList[i]));
|
||||
}
|
||||
}
|
||||
|
||||
letters = tmpLetters;
|
||||
}
|
||||
|
||||
Rectangle getRegionRectangle(Region r) {
|
||||
ArrayList<Point> input = new ArrayList<>();
|
||||
|
||||
int i, j;
|
||||
for (i = 0; i < r.Height(); i++) {
|
||||
for (j = 0; j < r.Width(); j++) {
|
||||
if (r.getPixel(j, i) == 255) {
|
||||
input.add(new Point(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return imt.getMinAreaRectangle(input);
|
||||
}
|
||||
|
||||
void buildRectangles() {
|
||||
rectangles.clear();
|
||||
int i;
|
||||
for (i = 0; i < letters.size(); i++) {
|
||||
rectangles.add(getRegionRectangle(letters.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
Region collapse_regions(ArrayList<Region> regs) {
|
||||
if (regs.size() == 0)
|
||||
return null;
|
||||
// adds more regions together
|
||||
int minX, maxX, minY, maxY;
|
||||
|
||||
minX = regs.get(0).OffsetX();
|
||||
minY = regs.get(0).OffsetY();
|
||||
|
||||
maxX = minX + regs.get(0).Width();
|
||||
maxY = minY + regs.get(0).Height();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < regs.size(); i++) {
|
||||
if (regs.get(i).OffsetX() < minX)
|
||||
minX = regs.get(i).OffsetX();
|
||||
if (regs.get(i).OffsetY() < minY)
|
||||
minY = regs.get(i).OffsetY();
|
||||
|
||||
if (regs.get(i).OffsetX() + regs.get(i).Width() > maxX)
|
||||
maxX = regs.get(i).OffsetX() + regs.get(i).Width();
|
||||
if (regs.get(i).OffsetY() + regs.get(i).Height() > maxY)
|
||||
maxY = regs.get(i).OffsetY() + regs.get(i).Height();
|
||||
}
|
||||
|
||||
// now minX, maxX, minY, maxY define a rectangle that includes all the
|
||||
// regions
|
||||
|
||||
// add all the regions to the new region
|
||||
Region tmpReg = new Region(maxX - minX + 1, maxY - minY + 1, minX, minY);
|
||||
|
||||
int j, k;
|
||||
|
||||
for (k = 0; k < regs.size(); k++) {
|
||||
for (i = 0; i < regs.get(k).Height(); i++) {
|
||||
for (j = 0; j < regs.get(k).Width(); j++) {
|
||||
if (regs.get(k).getPixel(j, i) != 0) {
|
||||
tmpReg.setPixel(j + regs.get(k).OffsetX() - minX, i
|
||||
+ regs.get(k).OffsetY() - minY, regs.get(k)
|
||||
.getPixel(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmpReg;
|
||||
}
|
||||
|
||||
SimpleImage getLetter(int imageNo, boolean rotated) {
|
||||
rotated = true;
|
||||
|
||||
SimpleImage tmp = new SimpleImage(1, 1);
|
||||
|
||||
if (imageNo < 0)
|
||||
return tmp;
|
||||
if (imageNo >= letters.size())
|
||||
return tmp;
|
||||
|
||||
tmp = letters.get(imageNo);
|
||||
|
||||
// now rotate the image if necessary
|
||||
if (rotated) {
|
||||
Rectangle r = getRectangle(imageNo);
|
||||
|
||||
if (r.area > 0) {
|
||||
double angle;
|
||||
|
||||
if (Math.abs(r.l1.angle()) < Math.abs(r.p1.angle())) {
|
||||
angle = r.l1.angle();
|
||||
} else {
|
||||
angle = r.p1.angle();
|
||||
}
|
||||
|
||||
// tmp.scale(tmp.Width() * 2, tmp.Height() * 2);
|
||||
tmp.rotate(-angle);
|
||||
// tmp.scale(tmp.Width() / 2, tmp.Height() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// tmp.center(1.f);
|
||||
|
||||
// tmp.scale(10, 10);
|
||||
|
||||
return tmp;
|
||||
|
||||
}
|
||||
|
||||
int getNrOfLetters() {
|
||||
return letters.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,433 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
public class SimpleImage {
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private byte[] data;
|
||||
|
||||
public SimpleImage(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
data = new byte[width * height];
|
||||
}
|
||||
|
||||
public SimpleImage(SimpleImage image) {
|
||||
copy(image);
|
||||
}
|
||||
|
||||
public int Width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int Height() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int value) {
|
||||
data[y * width + x] = (byte) value;
|
||||
}
|
||||
|
||||
public int getPixel(int x, int y) {
|
||||
return data[y * width + x] & 0xff;
|
||||
}
|
||||
|
||||
void copy(SimpleImage srcImage) {
|
||||
final int area = srcImage.width * srcImage.height;
|
||||
if ((width != srcImage.width) || (height != srcImage.height)) {
|
||||
width = srcImage.width;
|
||||
height = srcImage.height;
|
||||
data = new byte[area];
|
||||
}
|
||||
System.arraycopy(srcImage.data, 0, data, 0, area);
|
||||
}
|
||||
|
||||
void copy(SimpleImage srcImage, int srcX, int srcY, int srcW, int srcH,
|
||||
int destX, int destY) {
|
||||
for (int x = 0; x < srcW; ++x) {
|
||||
for (int y = 0; y < srcH; ++y) {
|
||||
setPixel(destX + x, destY + y, srcImage.getPixel((srcX + x) - srcW, srcY + y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rotate(double angle) {
|
||||
|
||||
// This is the worst method I could implement to rotate an image, but it
|
||||
// works well enough. I wanted to implement a better method but it looks
|
||||
// like I don't have to.
|
||||
// Angle is given in radians.
|
||||
|
||||
// these are the limits of the rotated image
|
||||
double minX, maxX, minY, maxY;
|
||||
|
||||
double x, y;
|
||||
|
||||
double sina, cosa;
|
||||
|
||||
sina = Math.sin(angle);
|
||||
cosa = Math.cos(angle);
|
||||
|
||||
// this is the first point (0,0)
|
||||
minX = 0.f;
|
||||
maxX = 0.f;
|
||||
minY = 0.f;
|
||||
maxY = 0.f;
|
||||
|
||||
// check where the second point will go (0,height)
|
||||
x = sina * height;
|
||||
y = cosa * height;
|
||||
|
||||
if (minX > x) {
|
||||
minX = x;
|
||||
}
|
||||
if (maxX < x) {
|
||||
maxX = x;
|
||||
}
|
||||
if (minY > y) {
|
||||
minY = y;
|
||||
}
|
||||
if (maxY < y) {
|
||||
maxY = y;
|
||||
}
|
||||
|
||||
// check where the third point will go (width, height)
|
||||
|
||||
x = cosa * width + sina * height;
|
||||
y = -sina * width + cosa * height;
|
||||
|
||||
if (minX > x) {
|
||||
minX = x;
|
||||
}
|
||||
if (maxX < x) {
|
||||
maxX = x;
|
||||
}
|
||||
if (minY > y) {
|
||||
minY = y;
|
||||
}
|
||||
if (maxY < y) {
|
||||
maxY = y;
|
||||
}
|
||||
|
||||
// check where the fourth point will go (width, 0)
|
||||
|
||||
x = cosa * width;
|
||||
y = -sina * width;
|
||||
|
||||
if (minX > x) {
|
||||
minX = x;
|
||||
}
|
||||
if (maxX < x) {
|
||||
maxX = x;
|
||||
}
|
||||
if (minY > y) {
|
||||
minY = y;
|
||||
}
|
||||
if (maxY < y) {
|
||||
maxY = y;
|
||||
}
|
||||
|
||||
// round minimums towards -\infty and maximums towards +\infty
|
||||
|
||||
minX = Math.floor(minX);
|
||||
minY = Math.floor(minY);
|
||||
maxX = Math.ceil(maxX);
|
||||
maxY = Math.ceil(maxY);
|
||||
|
||||
final SimpleImage tmpIm = new SimpleImage((int) (maxX - minX), (int) (maxY - minY));
|
||||
|
||||
for (double i = 0; i < maxY - minY; i++) {
|
||||
for (double j = 0; j < maxX - minX; j++) {
|
||||
x = cosa * (j + minX) - sina * (i + minY);
|
||||
y = sina * (j + minX) + cosa * (i + minY);
|
||||
|
||||
// see if x and y are within the image
|
||||
final int xx = (int) x;
|
||||
final int yy = (int) y;
|
||||
|
||||
if ((xx < 0) || (yy < 0) || (xx >= width) || (yy >= height)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we got here then xx and yy are valid
|
||||
tmpIm.setPixel((int) j, (int) i, getPixel(xx, yy));
|
||||
}
|
||||
}
|
||||
copy(tmpIm);
|
||||
}
|
||||
|
||||
void scale(int sizeX, int sizeY) {
|
||||
final SimpleImage tmpImage = new SimpleImage(sizeX, sizeY);
|
||||
|
||||
int ip, jp, m, n;
|
||||
double x, y, dx, dy;
|
||||
int i, j;
|
||||
|
||||
for (ip = 0; ip < sizeY; ip++) {
|
||||
for (jp = 0; jp < sizeX; jp++) {
|
||||
|
||||
x = jp * width / sizeX;
|
||||
dx = x - Math.floor(x);
|
||||
j = (int) Math.floor(x);
|
||||
|
||||
y = ip * height / sizeY;
|
||||
dy = y - Math.floor(y);
|
||||
i = (int) Math.floor(y);
|
||||
|
||||
double res = 0;
|
||||
|
||||
for (m = -1; m <= 2; m++) {
|
||||
for (n = -1; n <= 2; n++) {
|
||||
|
||||
int yy = i + m;
|
||||
int xx = j + n;
|
||||
|
||||
// xx = xx < 0 ? 0 : xx;
|
||||
if (xx < 0) {
|
||||
xx = 0;
|
||||
}
|
||||
xx = xx >= width ? width - 1 : xx;
|
||||
|
||||
yy = yy < 0 ? 0 : yy;
|
||||
yy = yy >= height ? height - 1 : yy;
|
||||
|
||||
res += getPixel(xx, yy) * R(n - dx) * R(m - dy);
|
||||
}
|
||||
}
|
||||
tmpImage.setPixel(jp, ip, (int) res);
|
||||
}
|
||||
}
|
||||
copy(tmpImage);
|
||||
}
|
||||
|
||||
void center(double x_y_ratio) {
|
||||
// The output will be an image with width/heigh = x_y_ratio. At first
|
||||
// all
|
||||
// the black pixels will be removed from the image, leaving the minimum
|
||||
// image that includes the white pixels. This image will be centered
|
||||
// into a
|
||||
// minimum rectangle whose width/height ratio is x_y_ratio and includes
|
||||
// it.
|
||||
|
||||
// Seems to be perf.
|
||||
|
||||
// First remove the black borders
|
||||
cropBorders();
|
||||
|
||||
// Then find the enclosing rectangle
|
||||
double w1, h1;
|
||||
|
||||
w1 = width;
|
||||
h1 = height;
|
||||
if (width < height * x_y_ratio) {
|
||||
w1 = height * x_y_ratio;
|
||||
} else {
|
||||
h1 = width / x_y_ratio;
|
||||
}
|
||||
|
||||
// Now w1 and h1 are the dimensions of the new image
|
||||
w1 = Math.ceil(w1);
|
||||
h1 = Math.ceil(h1);
|
||||
|
||||
final SimpleImage tmpIm = new SimpleImage((int) w1, (int) h1);
|
||||
|
||||
// Now find the x and y offsets of the original image in the new image
|
||||
double offsetX, offsetY;
|
||||
|
||||
offsetX = (w1 - width) / 2.f;
|
||||
offsetY = (h1 - height) / 2.f;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
tmpIm.setPixel((int) (x + offsetX), (int) (y + offsetY), getPixel(x, y));
|
||||
}
|
||||
}
|
||||
copy(tmpIm);
|
||||
}
|
||||
|
||||
void cropBorders() {
|
||||
int minX = width, minY = height, maxX = -1, maxY = -1;
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
if (getPixel(j, i) != 0) {
|
||||
if (j < minX) {
|
||||
minX = j;
|
||||
}
|
||||
if (j > maxX) {
|
||||
maxX = j;
|
||||
}
|
||||
if (i < minY) {
|
||||
minY = i;
|
||||
}
|
||||
if (i > maxY) {
|
||||
maxY = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then we have at least a point that is not black
|
||||
if (minX < width) {
|
||||
final SimpleImage tmpIm = new SimpleImage(maxX - minX + 1, maxY - minY + 1);
|
||||
|
||||
// Now copy the part of the image to tmpIm;
|
||||
for (int i = 0; i < maxY - minY + 1; i++) {
|
||||
for (int j = 0; j < maxX - minX + 1; j++) {
|
||||
tmpIm.setPixel(j, i, getPixel(j + minX, i + minY));
|
||||
}
|
||||
}
|
||||
copy(tmpIm);
|
||||
} else {
|
||||
// The image is all black.
|
||||
final SimpleImage tmpIm = new SimpleImage(1, 1);
|
||||
copy(tmpIm);
|
||||
}
|
||||
}
|
||||
|
||||
private static double R(double x) {
|
||||
// Auxiliary function for scaling
|
||||
|
||||
double a, b, c, d;
|
||||
|
||||
// Implement Eq 4.3-5 in four parts
|
||||
|
||||
if ((x + 2.0F) <= 0.0F) {
|
||||
a = 0.0F;
|
||||
} else {
|
||||
a = Math.pow((x + 2.0F), 3.0F);
|
||||
}
|
||||
|
||||
if ((x + 1.0F) <= 0.0F) {
|
||||
b = 0.0F;
|
||||
} else {
|
||||
b = Math.pow((x + 1.0F), 3.0F);
|
||||
}
|
||||
|
||||
if (x <= 0) {
|
||||
c = 0.0F;
|
||||
} else {
|
||||
c = Math.pow(x, 3.0F);
|
||||
}
|
||||
|
||||
if ((x - 1.0F) <= 0.0F) {
|
||||
d = 0.0F;
|
||||
} else {
|
||||
d = Math.pow((x - 1.0F), 3.0F);
|
||||
}
|
||||
|
||||
return (1.f / 6.f * (a - (4.0F * b) + (6.0F * c) - (4.0F * d)));
|
||||
}
|
||||
|
||||
Region extract(int x, int y, boolean eightWay) {
|
||||
SimpleImage tmpImage = new SimpleImage(width, height);
|
||||
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (getPixel(x, y) != 255) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// if the pixel at (x, y) is white, then we can do a flood fill
|
||||
|
||||
int minX, maxX, minY, maxY;
|
||||
|
||||
ArrayDeque<Point> floodStack = new ArrayDeque<>();
|
||||
|
||||
Point p = new Point(x, y);
|
||||
|
||||
minX = p.x;
|
||||
maxX = p.x;
|
||||
minY = p.y;
|
||||
maxY = p.y;
|
||||
|
||||
tmpImage.setPixel(p.x, p.y, 255);
|
||||
|
||||
floodStack.push(p);
|
||||
|
||||
do {
|
||||
p = floodStack.getLast();
|
||||
floodStack.pop();
|
||||
|
||||
// now push all unvisited neighbours on stack
|
||||
int i, j;
|
||||
for (i = -1; i <= 1; i++) {
|
||||
for (j = -1; j <= 1; j++) {
|
||||
if (((p.x + i) < 0) || ((p.y + j) < 0)
|
||||
|| ((p.x + i) >= width) || ((p.y + j) >= height)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!eightWay) {
|
||||
if ((i != 0) && (j != 0)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// now add that point
|
||||
if ((tmpImage.getPixel(p.x + i, p.y + j) != 255)
|
||||
&& (getPixel(p.x + i, p.y + j) == 255)) {
|
||||
// mark it as visited
|
||||
tmpImage.setPixel(p.x + i, p.y + j, 255);
|
||||
|
||||
// and add it
|
||||
floodStack.push(new Point(p.x + i, p.y + j));
|
||||
|
||||
// now update the min and max
|
||||
|
||||
if (p.x + i < minX)
|
||||
minX = p.x + i;
|
||||
if (p.x + i > maxX)
|
||||
maxX = p.x + i;
|
||||
|
||||
if (p.y + j < minY)
|
||||
minY = p.y + j;
|
||||
if (p.y + j > maxY)
|
||||
maxY = p.y + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (!floodStack.isEmpty());
|
||||
|
||||
// now we know the flood fill is included in the rectable delimited by
|
||||
// minX, maxX, minY, maxY
|
||||
|
||||
// This will be the region that we'll return
|
||||
Region r = new Region(maxX - minX + 1, maxY - minY + 1, minX, minY);
|
||||
|
||||
int i, j;
|
||||
for (j = minY; j <= maxY; j++) {
|
||||
for (i = minX; i <= maxX; i++) {
|
||||
r.setPixel(i - minX, j - minY, tmpImage.getPixel(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
void remove(Region reg) {
|
||||
int minX, minY, maxX, maxY;
|
||||
|
||||
minX = reg.OffsetX();
|
||||
minY = reg.OffsetY();
|
||||
|
||||
maxX = width < minX + reg.Width() ? width : minX + reg.Width();
|
||||
maxY = height < minY + reg.Height() ? height : minY + reg.Height();
|
||||
|
||||
int i, j;
|
||||
|
||||
for (j = minY; j < maxY; j++) {
|
||||
for (i = minX; i < maxX; i++) {
|
||||
if (reg.getPixel(i - minX, j - minY) == 255) {
|
||||
setPixel(i, j, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class SimpleImageIO {
|
||||
|
||||
private SimpleImageIO() {
|
||||
}
|
||||
|
||||
public static SimpleImage readBMP(byte data[]) throws IOException {
|
||||
|
||||
final int type = get2l(data, 0);
|
||||
if (type != 19778) {
|
||||
throw new IOException("Data not valid bitmap: no magic header");
|
||||
}
|
||||
|
||||
final int width = get4l(data, 18);
|
||||
final int height = get4l(data, 22);
|
||||
|
||||
final int bpp = get2l(data, 26);
|
||||
if (bpp != 1) {
|
||||
throw new IOException("Expected 1 bpp, got " + bpp);
|
||||
}
|
||||
|
||||
// Calculate the size of the image data with padding
|
||||
|
||||
// First calculate the size of one row
|
||||
int rowSize = width / 8;
|
||||
if ((width % 8) != 0) {
|
||||
rowSize++;
|
||||
}
|
||||
|
||||
// Adjust the row size to the next multiple of 4 bytes
|
||||
if ((rowSize % 4) != 0) {
|
||||
rowSize += 4 - (rowSize % 4);
|
||||
}
|
||||
|
||||
final int dataSize = height * rowSize;
|
||||
final byte tmpData[] = new byte[dataSize];
|
||||
|
||||
int offset = 30;
|
||||
|
||||
for (int i = 0; i < dataSize; ++i) {
|
||||
tmpData[i] = data[offset++];
|
||||
}
|
||||
|
||||
final SimpleImage image = new SimpleImage(width, height);
|
||||
|
||||
for (int y = 1; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
final int tmp = ((tmpData[y * rowSize + (x / 8)] & 0xff) >> (7 - x % 8)) & 1;
|
||||
if (tmp != 0) {
|
||||
image.setPixel(x, y, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static int get2l(byte b[], int offset) {
|
||||
return ((b[offset + 1] & 0xff) << 8) |
|
||||
(b[offset] & 0xff);
|
||||
}
|
||||
|
||||
private static int get4l(byte b[], int offset) {
|
||||
return ((b[offset + 3] & 0xff) << 24) |
|
||||
((b[offset + 2] & 0xff) << 16) |
|
||||
((b[offset + 1] & 0xff) << 8) |
|
||||
(b[offset] & 0xff);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
final class SmallRegionsCrowdingCriterion implements JoiningCriterionT {
|
||||
|
||||
@Override
|
||||
public boolean joinCritFunc(Region r1, Region r2) {
|
||||
if ((r1.Width() >= 8) || (r1.Height() >= 8) || (r2.Width() >= 8)
|
||||
|| (r2.Height() >= 8)) {
|
||||
// they are not small regions
|
||||
return false;
|
||||
}
|
||||
|
||||
int x1, x2, y1, y2;
|
||||
|
||||
x1 = r1.OffsetX() + r1.Width() / 2;
|
||||
x2 = r2.OffsetX() + r2.Width() / 2;
|
||||
|
||||
y1 = r1.OffsetY() + r1.Height() / 2;
|
||||
y2 = r2.OffsetY() + r2.Height() / 2;
|
||||
|
||||
if (Math.abs(x2 - x1) + Math.abs(y1 - y2) < 15) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof SmallRegionsCrowdingCriterion;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.stormy.ocrlib;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
public final class Test {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
BufferedReader br1 = null;
|
||||
BufferedReader br2 = null;
|
||||
try {
|
||||
/*br1 = new BufferedReader(new FileReader("./lib/Model.txt"));
|
||||
br2 = new BufferedReader(new FileReader("./lib/Dictionary.txt"));
|
||||
DictSearch ds = new DictSearch(br2);
|
||||
OCR ocr = new OCR(ds, br1);*/
|
||||
SimpleImage image = SimpleImageIO.readBMP(Files.readAllBytes(Paths.get("./HC.BMP")));
|
||||
//System.out.println(ocr.guess(image, true));
|
||||
display(splitToBuffered(image, true));
|
||||
} finally {
|
||||
if (br1 != null)
|
||||
br1.close();
|
||||
if (br2 != null)
|
||||
br2.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static BufferedImage toBufferedImage(SimpleImage src) {
|
||||
int width = src.Width();
|
||||
int height = src.Height();
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int p = src.getPixel(x, height - y - 1);
|
||||
image.setRGB(x, y,
|
||||
((p & 0xFF) << 16) |
|
||||
((p & 0xFF) << 8) |
|
||||
((p & 0xFF) << 0));
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
private static BufferedImage[] splitToBuffered(SimpleImage src, boolean use_new) {
|
||||
BufferedImage[] ai;
|
||||
if (use_new) {
|
||||
Segmentor s = new Segmentor();
|
||||
s.process(src);
|
||||
int count = s.getNrOfLetters();
|
||||
ai = new BufferedImage[count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SimpleImage letter = s.getLetter(i, true);
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
ai[i] = toBufferedImage(letter);
|
||||
}
|
||||
} else {
|
||||
List<Letter> split = Letter.splitLetters(src);
|
||||
int count = split.size();
|
||||
ai = new BufferedImage[count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final Letter letter = split.get(i);
|
||||
letter.center(1);
|
||||
letter.scale(15, 15);
|
||||
ai[i] = toBufferedImage(letter);
|
||||
}
|
||||
}
|
||||
return ai;
|
||||
}
|
||||
|
||||
private static void display(final BufferedImage[] ai) {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
for (BufferedImage image : ai) {
|
||||
int ih = image.getHeight() * 3;
|
||||
if (ih > height) {
|
||||
height = ih;
|
||||
}
|
||||
width += (image.getWidth() * 3);
|
||||
}
|
||||
final int fh = height;
|
||||
Component p = new Component() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for (BufferedImage image : ai) {
|
||||
int w = image.getWidth() * 3;
|
||||
g.drawImage(image, x, y, w, image.getHeight() * 3, null);
|
||||
x += w;
|
||||
}
|
||||
y += (fh + 15);
|
||||
x = 0;
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString("Number of letters: " + ai.length, x, y);
|
||||
}
|
||||
};
|
||||
p.setPreferredSize(new Dimension(width, height + 30));
|
||||
Frame f = new Frame("Output");
|
||||
f.add(p);
|
||||
f.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
f.setResizable(false);
|
||||
f.pack();
|
||||
f.setLocationRelativeTo(null);
|
||||
f.setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// svm_model
|
||||
//
|
||||
package com.stormy.ocrlib.svm;
|
||||
|
||||
public class svm_model
|
||||
implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6790261614477255960L;
|
||||
svm_parameter param; // parameter
|
||||
public int nr_class; // number of classes, = 2 in regression/one class svm
|
||||
int l; // total #SV
|
||||
svm_node[][] SV; // SVs (SV[l])
|
||||
double[][] sv_coef; // coefficients for SVs in decision functions
|
||||
// (sv_coef[k-1][l])
|
||||
double[] rho; // constants in decision functions (rho[k*(k-1)/2])
|
||||
double[] probA; // pariwise probability information
|
||||
double[] probB;
|
||||
int[] sv_indices; // sv_indices[0,...,nSV-1] are values in
|
||||
// [1,...,num_traning_data] to indicate SVs in the
|
||||
// training set
|
||||
|
||||
// for classification only
|
||||
|
||||
int[] label; // label of each class (label[k])
|
||||
int[] nSV; // number of SVs for each class (nSV[k])
|
||||
// nSV[0] + nSV[1] + ... + nSV[k-1] = l
|
||||
};
|
||||