diff --git a/.deepsource.toml b/.deepsource.toml
new file mode 100644
index 000000000..aa313b066
--- /dev/null
+++ b/.deepsource.toml
@@ -0,0 +1,14 @@
+version = 1
+
+[[analyzers]]
+name = "php"
+
+[[analyzers]]
+name = "javascript"
+
+[[analyzers]]
+name = "sql"
+
+exclude_files = [
+ "lib/phpmailer/**",
+]
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000..b862461eb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,49 @@
+name: Bug Report
+description: Create an Issue that details broken or unexpected behaviour
+labels: [Bug Report]
+body:
+- type: textarea
+ attributes:
+ label: Environment
+ description: |
+ examples:
+ - **PHP**: 8.1
+ - **MySQL**: MariaDB 10
+ value: |
+ - PHP:
+ - MySQL:
+ render: Markdown
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Current Behavior
+ description: A concise description of what you're experiencing.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Expected Behavior
+ description: A concise description of what you expected to happen.
+ validations:
+ required: false
+- type: textarea
+ attributes:
+ label: Steps To Reproduce
+ description: Steps to reproduce the behavior.
+ placeholder: |
+ 1. In this environment...
+ 2. With this config...
+ 3. Open page '...'
+ 4. See error...
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Anything else?
+ description: |
+ Links? References? Anything that will give us more context about the issue you are encountering!
+
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..e42d93361
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Forum Support
+ url: https://rathena.org/board/forum/21-web-support/
+ about: You can obtain support for FluxCP on our forum.
+ - name: Discord Support
+ url: https://discord.gg/kMeMXWEvSV
+ about: Chat with others in our fluxcp-support channel.
diff --git a/.github/ISSUE_TEMPLATE/enhancement_request.yml b/.github/ISSUE_TEMPLATE/enhancement_request.yml
new file mode 100644
index 000000000..852eb266a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement_request.yml
@@ -0,0 +1,11 @@
+name: Enhancement Request
+description: Submit your request for changes to existing code to provide more functionality or QoL changes.
+title: "Enhancement Request"
+labels: [Enhancement Request]
+body:
+- type: textarea
+ attributes:
+ label: Provide Details
+ description: Give as much information as possible in order to get the discussion going.
+ validations:
+ required: true
diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
new file mode 100644
index 000000000..752919ceb
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
@@ -0,0 +1,6 @@
+Fixes # .
+
+Changes proposed in this Pull Request:
+ * ?
+ * ?
+ * ?
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..752919ceb
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,6 @@
+Fixes # .
+
+Changes proposed in this Pull Request:
+ * ?
+ * ?
+ * ?
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 000000000..1c5b7d7d1
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,41 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+ schedule:
+ - cron: "36 3 * * 3"
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ javascript ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ queries: +security-and-quality
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{ matrix.language }}"
diff --git a/.gitignore b/.gitignore
index c8ecfd748..d917b432c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,13 @@
# Caches
/data/tmp/*.php
/data/tmp/*.cache
+/data/tmp/emblems
+
+# Non-Default Themes
+/themes/*
+!/themes/default
+!/themes/bootstrap
+!/themes/installer
+
+# Import Configs
+/config/import
diff --git a/README.md b/README.md
index 67c132b3e..2afb68682 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
FluxCP
======
-[![Total alerts](https://img.shields.io/lgtm/alerts/g/rathena/FluxCP.svg?logo=lgtm&logoWidth=18&color=orange)](https://lgtm.com/projects/g/rathena/FluxCP/alerts/)
+[![DeepSource](https://app.deepsource.com/gh/rathena/FluxCP.svg/?label=active+issues&show_trend=true&token=nhkIfid6qRIZxl2INWaaV4Qb)](https://app.deepsource.com/gh/rathena/FluxCP/?ref=repository-badge)
[![Open Issues](https://img.shields.io/github/issues/rathena/FluxCP.svg?logo=github&logoWidth=18&color=yellow)](https://lgtm.com/projects/g/rathena/FluxCP/alerts/)
[![Open PRs](https://img.shields.io/github/issues-pr/rathena/FluxCP.svg?logo=github&logoWidth=18&color=blue)](https://lgtm.com/projects/g/rathena/FluxCP/alerts/)
-[![Codacy Badge](https://api.codacy.com/project/badge/Grade/d842cd47636244668f3093151b288eff)](https://www.codacy.com/app/rathena/FluxCP?utm_source=github.com&utm_medium=referral&utm_content=rathena/FluxCP&utm_campaign=Badge_Grade)
+[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4d1c0a43c0864764b3d3dc5ed2d93192)](https://www.codacy.com/gh/rathena/FluxCP/dashboard?utm_source=github.com&utm_medium=referral&utm_content=rathena/FluxCP&utm_campaign=Badge_Grade)
Flux Control Panel (FluxCP) for rAthena servers.
@@ -24,7 +24,7 @@ What's New?
* Pre-integrated themes:
- default
- Bootstrap
-
+
* Built-In:
- News and Pages CMS with integrated TinyMCE
- Service Desk (ITIL Incident Management style support ticket system)
@@ -55,7 +55,7 @@ Join the Discussion
---------
We have a discord server separate from rAthena just for FluxCP stuff!
The channels there can be used to obtain help, discuss testing, view anonymous feedback log, Github commits, etc.
-https://discord.gg/0XP9qqhUV9GLSfCh
+https://discord.gg/kMeMXWEvSV
Extra Credits
diff --git a/config/access.php b/config/access.php
index 5d8fa23d6..54598d711 100644
--- a/config/access.php
+++ b/config/access.php
@@ -98,9 +98,6 @@
'item' => array(
'index' => AccountLevel::ANYONE,
'view' => AccountLevel::ANYONE,
- 'add' => AccountLevel::ADMIN,
- 'edit' => AccountLevel::ADMIN,
- 'copy' => AccountLevel::ADMIN,
'iteminfo' => AccountLevel::ADMIN
),
'monster' => array(
diff --git a/config/application.php b/config/application.php
index 3c8a59f06..8a66c5af2 100644
--- a/config/application.php
+++ b/config/application.php
@@ -18,8 +18,10 @@
'ItemImageNameFormat' => '%d.png', // The filename format for item images (defaults to {itemid}.png).
'MonsterImageNameFormat' => '%d.gif', // The filename format for monster images (defaults to {monsterid}.gif).
'JobImageNameFormat' => '%d.gif', // The filename format for job images (defaults to {jobid}.gif).
+ 'DivinePrideIntegration' => true, // Dowload monsters and items images from https://www.divine-pride.net if it's not exist.
'ForceEmptyEmblem' => false, // Forcefully display empty guild emblems, helpful when you don't have GD2 installed.
'EmblemCacheInterval' => 12, // Hourly interval to re-cache guild emblems (set to 0 to disable emblem cache).
+ 'EmblemUseWebservice' => true, // Load emblems from WebService?
'SessionCookieExpire' => 48, // Duration in hours.
'AdminMenuGroupLevel' => AccountLevel::LOWGM, // The starting group ID for which module actions are moved into the admin menu for display.
'DateDefaultTimezone' => 'UTC', // The default timezone, consult the PHP manual for valid timezones: http://php.net/timezones (null for defaut system TZ)
@@ -56,7 +58,7 @@
'RequireChangeConfirm' => false, // Require confirmation when changing e-mail addresses.
'EmailConfirmExpire' => 48, // E-mail confirmations expire hours. Unconfirmed accounts will expire after this period of time.
'PendingRegistration' => false, // Requires 'RequireEmailConfirm' to be true. Prevents new registration if ip address has a pending registration on selected mail.
- 'PincodeEnabled' => true, // Whether or not the pincode system is enabled in your server. (Check your char_athena.conf file. Enabled by default.)
+ 'PincodeEnabled' => true, // Whether or not the pincode system is enabled in your server. (Check your char_athena.conf file. Enabled by default.)
'MailerFromAddress' => 'noreply@localhost', // The e-mail address displayed in the From field.
'MailerFromName' => 'MailerName', // The name displayed with the From e-mail address.
'MailerUseSMTP' => false, // Whether or not to use a separate SMTP server for sending mail.
@@ -78,7 +80,7 @@
'ShowRenderDetails' => true, // Shows the "page rendered in X seconds" and "number of queries executed: X" in the default theme.
'UseCleanUrls' => false, // Set to true if you're running Apache and it supports mod_rewrite and .htaccess files.
'DebugMode' => false, // Set to false to minimize technical details from being output by Flux. WARNING: DO NOT USE THIS OPTION ON A PUBLICALLY-ACCESSIBLE CP.
- 'UseCaptcha' => true, // Use CAPTCHA image for account registration to prevent automated account creations. (Requires GD2/FreeType2)
+ 'UseCaptcha' => false, // Use CAPTCHA image for account registration to prevent automated account creations. (Requires GD2/FreeType2)
'UseLoginCaptcha' => false, // Use CAPTCHA image for account logins. (Requires GD2/FreeType2)
'EnableReCaptcha' => false, // Enables the use of reCAPTCHA instead of Flux's native GD2 library (http://www.google.com/recaptcha)
'ReCaptchaPublicKey' => '...', // This is your reCAPTCHA public key [REQUIRED FOR RECAPTCHA] (sign up at http://www.google.com/recaptcha)
@@ -86,7 +88,7 @@
'ReCaptchaTheme' => 'light', // ReCaptcha theme to use (Value: dark or light) (see: https://developers.google.com/recaptcha/docs/display#render_param)
'DisplaySinglePages' => true, // Whether or not to display paging for single page results.
'ForwardYears' => 15, // (Visual) The number of years to display ahead of the current year in date inputs.
- 'BackwardYears' => 30, // (Visual) The number of years to display behind the current year in date inputs.
+ 'BackwardYears' => 60, // (Visual) The number of years to display behind the current year in date inputs.
'ColumnSortAscending' => ' ▲', // (Visual) Text displayed for ascending sorted column names.
'ColumnSortDescending' => ' ▼', // (Visual) Text displayed for descending sorted column names.
'CreditExchangeRate' => 1.0, // The rate at which credits are exchanged for dollars.
@@ -96,13 +98,28 @@
'MoneyThousandsSymbol' => ',', // (Visual) Thousandths place separator (a period in European currencies).
'MoneyDecimalSymbol' => '.', // (Visual) Decimal separator (a comma in European currencies).
'AcceptDonations' => true, // Whether or not to accept donations.
- 'PayPalIpnUrl' => 'www.sandbox.paypal.com',// The URL for PayPal's IPN responses (www.paypal.com for live and www.sandbox.paypal.com for testing)
+ 'PayPalIpnUrl' => 'www.paypal.com', // The ipnpb.paypal.com and ipnpb.sandbox.paypal.com endpoints only accept HTTPS connections. If you currently use www.paypal.com, you should move to ipnpb.paypal.com when you update your code to use HTTPS.
'PayPalBusinessEmail' => 'admin@localhost', // Enter the e-mail under which you have registered your business account.
'PayPalReceiverEmails' => array( // These are the receiver e-mail addresses who are allowed to receive payment.
//'admin2@localhost', // -- This array may be empty if you only use one e-mail
//'admin3@localhost' // -- because your Business Email is also checked.
),
'PaypalHackNotify' => true, // Send email notification if hack attempt detected (Notification will be send for each address in list PayPalBusinessEmail and PayPalReceiverEmails)
+ 'PayPalAllowedHosts' => array( // PayPal IP list https://www.paypal.com/fm/smarthelp/article/what-are-the-ip-addresses-for-live-paypal-servers-ts1056
+ 'ipn.sandbox.paypal.com',
+ 'notify.paypal.com',
+ '66.211.170.66',
+ '173.0.81.1',
+ '173.0.81.0/24',
+ '173.0.81.33',
+ '173.0.81.65',
+ '173.0.81.140',
+ '64.4.240.0/21',
+ '64.4.248.0/22',
+ '6.211.168.0/22',
+ '173.0.80.0/20',
+ '91.243.72.0/23'
+ ),
'GStorageLeaderOnly' => false, // Only allow guild leader to view guild storage rather than all members?
'DivorceKeepChild' => false, // Keep child after divorce?
'DivorceKeepRings' => false, // Keep wedding rings after divorce?
@@ -156,7 +173,7 @@
'BlacksmithRankingLimit' => 20, //
'HomunRankingLimit' => 20, //
'MVPRankingLimit' => 20, //
-
+
'RankingHideGroupLevel' => AccountLevel::LOWGM, //
'InfoHideZenyGroupLevel' => AccountLevel::LOWGM, // Minimum group level of account to hide zeny from in server information page.
@@ -197,8 +214,8 @@
'AdminMenuNewStyle' => true, // Use new-style admin menu; Applies to 'default' theme.
'EnablePeakDisplay' => true, // Display Peak User count on Server Status page.
-
-
+
+
// News Options
'CMSNewsOnHomepage' => true, // Display News on Home Page instead of "You've Just Installed FluxCP" message?
'CMSNewsType' => 1, // Type = source of news feed:
@@ -220,10 +237,12 @@
// Discord Webhooks
'DiscordUseWebhook' => false,
'DiscordWebhookURL' => 'enter_webhook_url_from_discord_here',
- 'DiscordSendOnRegister' => true,
- 'DiscordSendOnNewTicket' => true,
- 'DiscordSendOnWebCommand' => true,
- 'DiscordSendOnMarketing' => true,
+ 'DiscordSendOnRegister' => true, // Sends a channel message when someone registers
+ 'DiscordSendOnNewTicket' => true, // Sends a channel message when someone submits a new ticket to the Service Desk
+ 'DiscordSendOnWebCommand' => true, // Sends a channel message when someone uses the Web Command feature in FluxCP
+ 'DiscordSendOnMarketing' => true, // Sends a channel message when someone uses the Send Email feature in FluxCP
+
+ 'TinyMCEKey' => 'no-key', // Register for a key at https://www.tiny.cloud/my-account/dashboard/
// These are the main menu items that should be displayed by themes.
// They route to modules and actions. Whether they are displayed or
@@ -236,8 +255,8 @@
//'ForumLabel' => array('module' => 'forums'), // Built-in forum link
'NewsLabel' => array('module' => 'news'),
// Sample items for pages function.
- 'DownloadsLabel' => array('module' => 'pages','action'=>'content&path=downloads'),
- 'RulesLabel' => array('module' => 'pages','action'=>'content&path=rules'),
+ 'DownloadsLabel' => array('module' => 'pages','action'=>'content','param'=>array('path'=>'downloads')),
+ 'RulesLabel' => array('module' => 'pages','action'=>'content','param'=>array('path'=>'rules')),
// End sample items for pages function.
),
'AccountLabel' => array(
@@ -291,7 +310,7 @@
//'Economy' => array('module' => 'economy')
)
),
-
+
// Sub-menu items that are displayed for any action belonging to a
// particular module. The format it simple.
'SubMenuItems' => array(
@@ -376,7 +395,6 @@
),
'item' => array(
'index' => 'List Items',
- 'add' => 'Add Item',
'iteminfo' => 'Add Item Info',
),
'pages' => array(
@@ -401,7 +419,7 @@
'index' => 'Buyers',
),
),
-
+
'AllowMD5PasswordSearch' => false,
'ReallyAllowMD5PasswordSearch' => false, // Are you POSITIVELY sure?
@@ -437,9 +455,9 @@
// Shouldn't touch this either.
'ItemTypes' => include('itemtypes.php'),
- // Special Item Types with their corresponding names (For Weapons & Ammo by default).
+ // Item SubTypes with their corresponding names.
// Shouldn't touch this either.
- 'ItemTypes2' => include('itemtypes2.php'),
+ 'ItemSubTypes' => include('itemsubtypes.php'),
// Common Equip Location Combinations with their corresponding names.
// Shouldn't touch this unless you've added custom combinations.
@@ -472,6 +490,7 @@
// rA monster modes mapping.
'MonsterModes' => include('monstermode.php'),
+ 'MonsterAI' => include('monster_ai.php'),
// Item shop categories.
'ShopCategories' => include('shopcategories.php'),
@@ -488,6 +507,15 @@
// Castle names.
'CastleNames' => include('castlenames.php'),
+ // Trade restrictions.
+ 'TradeRestriction' => include('trade_restrictions.php'),
+
+ // Item flags.
+ 'ItemFlags' => include('itemsflags.php'),
+
+ // Item random options.
+ 'RandomOptions' => include('item_randoptions.php'),
+
// DON'T TOUCH. THIS IS FOR DEVELOPERS.
'FluxTables' => array(
'CreditsTable' => 'cp_credits',
diff --git a/config/castlenames.php b/config/castlenames.php
index af00e1136..296c7d120 100644
--- a/config/castlenames.php
+++ b/config/castlenames.php
@@ -36,7 +36,17 @@
30 => 'Cyr',
31 => 'Horn',
32 => 'Gefn',
- 33 => 'Bandis'
+ 33 => 'Bandis',
+ 34 => 'Leilah',
+ 35 => 'Pavianne',
+ 36 => 'Jasmine',
+ 37 => 'Roxie',
+ 38 => 'Curly Sue',
+ 39 => 'Gaebolg',
+ 40 => 'Richard',
+ 41 => 'Wigner',
+ 42 => 'Heine',
+ 43 => 'Nerious'
// kRO Names
/**
* 0 => 'Noisyubantian',
@@ -72,7 +82,17 @@
*30 => 'Cyr',
*31 => 'Horn',
*32 => 'Gefn',
- *33 => 'Bandis'
+ *33 => 'Bandis',
+ *34 => 'Kafragarten 1',
+ *35 => 'Kafragarten 2',
+ *36 => 'Kafragarten 3',
+ *37 => 'Kafragarten 4',
+ *38 => 'Kafragarten 5',
+ *39 => 'Gloria 1',
+ *40 => 'Gloria 2',
+ *41 => 'Gloria 3',
+ *42 => 'Gloria 4',
+ *43 => 'Gloria 5'
*/
)
?>
diff --git a/config/elements.php b/config/elements.php
index c7b08ac61..5965a2bdb 100644
--- a/config/elements.php
+++ b/config/elements.php
@@ -1,15 +1,15 @@
'Neutral',
- 1 => 'Water',
- 2 => 'Earth',
- 3 => 'Fire',
- 4 => 'Wind',
- 5 => 'Poison',
- 6 => 'Holy',
- 7 => 'Dark',
- 8 => 'Ghost',
- 9 => 'Undead'
+ 'Neutral' => 'Neutral',
+ 'Water' => 'Water',
+ 'Earth' => 'Earth',
+ 'Fire' => 'Fire',
+ 'Wind' => 'Wind',
+ 'Poison' => 'Poison',
+ 'Holy' => 'Holy',
+ 'Dark' => 'Dark',
+ 'Ghost' => 'Ghost',
+ 'Undead' => 'Undead'
);
?>
diff --git a/config/equip_jobs.php b/config/equip_jobs.php
index 1f34bd15d..d6dec9ae2 100644
--- a/config/equip_jobs.php
+++ b/config/equip_jobs.php
@@ -1,36 +1,38 @@
'Novice',
- pow(2, 1) => 'Swordman',
- pow(2, 2) => 'Mage',
- pow(2, 3) => 'Archer',
- pow(2, 4) => 'Acolyte',
- pow(2, 5) => 'Merchant',
- pow(2, 6) => 'Thief',
- pow(2, 7) => 'Knight',
- pow(2, 8) => 'Priest',
- pow(2, 9) => 'Wizard',
- pow(2, 10) => 'Blacksmith',
- pow(2, 11) => 'Hunter',
- pow(2, 12) => 'Assassin',
- pow(2, 13) => 'Unused',
- pow(2, 14) => 'Crusader',
- pow(2, 15) => 'Monk',
- pow(2, 16) => 'Sage',
- pow(2, 17) => 'Rogue',
- pow(2, 18) => 'Alchemist',
- pow(2, 19) => 'Bard/Dancer',
- pow(2, 20) => 'Unused',
- pow(2, 21) => 'Taekwon',
- pow(2, 22) => 'Star Gladiator',
- pow(2, 23) => 'Soul Linker',
- pow(2, 24) => 'Gunslinger',
- pow(2, 25) => 'Ninja',
- pow(2, 26) => 'Gangsi',
- pow(2, 27) => 'Death Knight',
- pow(2, 28) => 'Dark Collector',
- pow(2, 29) => 'Kagerou/Oboro',
- pow(2, 30) => 'Rebellion',
- pow(2, 31) => 'Summoner',
+ 0 => // Default job list
+ array(
+ 'job_all' => 'All jobs',
+ 'job_novice' => 'Novice',
+ 'job_supernovice' => 'Super novice',
+ 'job_swordman' => 'Swordman',
+ 'job_mage' => 'Mage',
+ 'job_archer' => 'Archer',
+ 'job_merchant' => 'Merchant',
+ 'job_thief' => 'Thief',
+ 'job_knight' => 'Knight',
+ 'job_priest' => 'Priest',
+ 'job_wizard' => 'Wizard',
+ 'job_blacksmith' => 'Blacksmith',
+ 'job_hunter' => 'Hunter',
+ 'job_assassin' => 'Assassin',
+ 'job_crusader' => 'Crusader',
+ 'job_monk' => 'Monk',
+ 'job_sage' => 'Sage',
+ 'job_rogue' => 'Rogue',
+ 'job_alchemist' => 'Alchemist',
+ 'job_barddancer' => 'Bard / Dancer',
+ 'job_taekwon' => 'Taekwon',
+ 'job_stargladiator' => 'Star Gladiator',
+ 'job_soullinker' => 'Soul Linker',
+ 'job_gunslinger' => 'Gunslinger',
+ 'job_ninja' => 'Ninja',
+ ),
+ 1 => // Renewal job list
+ array(
+ 'job_kagerouoboro' => 'Kagerou / Oboro',
+ 'job_rebellion' => 'Rebellion',
+ 'job_summoner' => 'Summoner'
+ )
)
?>
diff --git a/config/equip_location_combinations.php b/config/equip_location_combinations.php
index 5269132ef..3fa378aec 100644
--- a/config/equip_location_combinations.php
+++ b/config/equip_location_combinations.php
@@ -1,33 +1,16 @@
'None',
- 65536 => 'Shadow Armor',
- 131072 => 'Shadow Weapon',
- 262144 => 'Shadow Shield',
- 524288 => 'Shadow Shoes',
- 1048576 => 'Shadow Accessory Right (Earring)',
- 2097152 => 'Shadow Accessory Left (Pendant)',
- 4096 => 'Costume Low Headgear',
- 2048 => 'Costume Mid Headgear',
- 1024 => 'Costume Top Headgear',
- 7168 => 'Costume Low/Mid/Top Headgear',
- 3072 => 'Costume Mid/Top Headgear',
- 6144 => 'Costume Low/Mid Headgear',
- 256 => 'Upper Headgear',
- 512 => 'Middle Headgear',
- 1 => 'Lower Headgear',
- 769 => 'Upper/Mid/Lower Headgear',
- 768 => 'Upper/Mid Headgear',
- //257 => 'Upper/Lower Headgear',
- 513 => 'Mid/Lower Headgear',
- 16 => 'Armor',
- 2 => 'Weapon',
- 32 => 'Shield',
- 34 => 'Two-Handed',
- 50 => 'Armor/Hands',
- 4 => 'Garment',
- 64 => 'Footgear',
- 136 => 'Accessories',
- 32768 => 'Arrow/Ammo'
+ 'location_left_hand/location_right_hand' => 'Two-Handed',
+ 'location_head_low/location_head_mid/location_head_top' => 'Upper/Mid/Lower Headgear',
+ 'location_head_mid/location_head_top' => 'Upper/Mid Headgear',
+ 'location_head_top/location_head_low' => 'Upper/Lower Headgear',
+ 'location_head_low/location_head_mid' => 'Mid/Lower Headgear',
+ 'location_head_low/location_head_top' => 'Upper/Lower Headgear',
+ 'location_costume_head_mid/location_costume_head_top' => 'Costume Upper/Mid Headgear',
+ 'location_costume_head_low/location_costume_head_top' => 'Costume Upper/Lower Headgear',
+ 'location_costume_head_low/location_costume_head_mid' => 'Costume Mid/Lower Headgear',
+ 'location_costume_head_low/location_costume_head_mid/location_costume_head_top' => 'Costume Upper/Mid/Lower Headgear',
+ 'location_left_accessory/location_right_accessory' => 'Accessory Left/Right',
+ 'location_armor/location_garment/location_head_low/location_head_mid/location_head_top/location_left_accessory/location_left_hand/location_right_accessory/location_right_hand/location_shoes' => 'All equip',
)
?>
diff --git a/config/equip_locations.php b/config/equip_locations.php
index d31e57552..5a40b3cc4 100644
--- a/config/equip_locations.php
+++ b/config/equip_locations.php
@@ -1,25 +1,25 @@
'Lower Headgear',
- 2 => 'Main Hand',
- 4 => 'Garment',
- 8 => 'Accessory Right',
- 16 => 'Armor',
- 32 => 'Off Hand',
- 64 => 'Footgear',
- 128 => 'Accessory Left',
- 256 => 'Upper Headgear',
- 512 => 'Middle Headgear',
- 1024 => 'Costume Top Headgear',
- 2048 => 'Costume Mid Headgear',
- 4096 => 'Costume Low Headgear',
- 8192 => 'Costume Garment',
- 32768 => 'Ammo',
- 65536 => 'Shadow Armor',
- 131072 => 'Shadow Weapon',
- 262144 => 'Shadow Shield',
- 524288 => 'Shadow Shoes',
- 1048576 => 'Shadow Accessory Right (Earring)',
- 2097152 => 'Shadow Accessory Left (Pendant)',
+ 'location_head_low' => 'Lower Headgear',
+ 'location_right_hand' => 'Main Hand',
+ 'location_garment' => 'Garment',
+ 'location_right_accessory' => 'Accessory Right',
+ 'location_armor' => 'Armor',
+ 'location_left_hand' => 'Off Hand',
+ 'location_shoes' => 'Footgear',
+ 'location_left_accessory' => 'Accessory Left',
+ 'location_head_top' => 'Upper Headgear',
+ 'location_head_mid' => 'Middle Headgear',
+ 'location_costume_head_top' => 'Costume Top Headgear',
+ 'location_costume_head_mid' => 'Costume Mid Headgear',
+ 'location_costume_head_low' => 'Costume Low Headgear',
+ 'location_costume_garment' => 'Costume Garment',
+ 'location_ammo' => 'Ammo',
+ 'location_shadow_armor' => 'Shadow Armor',
+ 'location_shadow_weapon' => 'Shadow Weapon',
+ 'location_shadow_shield' => 'Shadow Shield',
+ 'location_shadow_shoes' => 'Shadow Shoes',
+ 'location_shadow_right_accessory' => 'Shadow Accessory Right (Earring)',
+ 'location_shadow_left_accessory' => 'Shadow Accessory Left (Pendant)',
)
?>
diff --git a/config/equip_upper.php b/config/equip_upper.php
index 6795ee203..e6ce9b461 100644
--- a/config/equip_upper.php
+++ b/config/equip_upper.php
@@ -1,10 +1,17 @@
'Normal',
- 2 => 'Upper',
- 4 => 'Baby',
- 8 => 'Third',
- 16 => 'Third Upper',
- 32 => 'Third Baby'
+ 0 => // Default class list
+ array(
+ 'class_all' => 'All classes',
+ 'class_normal' => 'Normal',
+ 'class_upper' => 'Upper',
+ 'class_baby' => 'Baby'
+ ),
+ 1 => // Renewal class list
+ array(
+ 'class_third' => 'Third',
+ 'class_third_upper' => 'Third Upper',
+ 'class_third_baby' => 'Third Baby'
+ )
)
?>
diff --git a/config/item_randoptions.php b/config/item_randoptions.php
new file mode 100644
index 000000000..882b0c037
--- /dev/null
+++ b/config/item_randoptions.php
@@ -0,0 +1,224 @@
+ 'MaxHP +%s',
+ 2 => 'MaxSP +%s',
+ 3 => 'STR +%s',
+ 4 => 'AGI +%s',
+ 5 => 'VIT +%s',
+ 6 => 'INT +%s',
+ 7 => 'DEX +%s',
+ 8 => 'LUK +%s',
+ 9 => 'MaxHP +%s%%',
+ 10 => 'MaxSP +%s%%',
+ 11 => 'HP regen +%s%%',
+ 12 => 'SP regen +%s%%',
+ 13 => 'ATK +%s%%',
+ 14 => 'MATK +%s%%',
+ 15 => 'ASPD +%s',
+ 16 => 'Delay after attack -%s%%',
+ 17 => 'ATK +%s',
+ 18 => 'HIT +%s',
+ 19 => 'MATK +%s',
+ 20 => 'DEF +%s',
+ 21 => 'MDEF +%s',
+ 22 => 'FLEE +%s',
+ 23 => 'Perfect dodge +%s',
+ 24 => 'CRIT +%s',
+ 25 => 'Neutral elemental resistance +%s%%',
+ 26 => 'Water elemental resistance +%s%%',
+ 27 => 'Earth elemental resistance +%s%%',
+ 28 => 'Fire elemental resistance +%s%%',
+ 29 => 'Wind elemental resistance +%s%%',
+ 30 => 'Poison elemental resistance +%s%%',
+ 31 => 'Holy elemental resistance +%s%%',
+ 32 => 'Shadow elemental resistance +%s%%',
+ 33 => 'Ghost elemental resistance +%s%%',
+ 34 => 'Undead elemental resistance +%s%%',
+ 35 => 'All elementals resistance +%s%%',
+ 36 => 'Neutral monster resistance +%s%%',
+ 37 => 'ATK +%s%% against Neutral monster',
+ 38 => 'Water monster resistance +%s%%',
+ 39 => 'ATK +%s%% against Water monster',
+ 40 => 'Earth monster resistance +%s%%',
+ 41 => 'ATK +%s%% against Earth monster',
+ 42 => 'Fire monster resistance +%s%%',
+ 43 => 'ATK +%s%% against Fire monster',
+ 44 => 'Wind monster resistance +%s%%',
+ 45 => 'ATK +%s%% against Wind monster',
+ 46 => 'Poison monster resistance +%s%%',
+ 47 => 'ATK +%s%% against Poison monster',
+ 48 => 'Holy monster resistance +%s%%',
+ 49 => 'ATK +%s%% against Holy monster',
+ 50 => 'Shadow monster resistance +%s%%',
+ 51 => 'ATK +%s%% against Shadow monster',
+ 52 => 'Ghost monster resistance +%s%%',
+ 53 => 'ATK +%s%% against Ghost monster',
+ 54 => 'Undead monster resistance +%s%%',
+ 55 => 'ATK +%s%% against Undead monster',
+ 56 => 'Neutral monster magic resistance +%s%%',
+ 57 => 'MATK +%s%% against Neutral monster',
+ 58 => 'Water monster magic resistance +%s%%',
+ 59 => 'MATK +%s%% against Water monster',
+ 60 => 'Earth monster magic resistance +%s%%',
+ 61 => 'MATK +%s%% against Earth monster',
+ 62 => 'Fire monster magic resistance +%s%%',
+ 63 => 'MATK +%s%% against Fire monster',
+ 64 => 'Wind monster magic resistance +%s%%',
+ 65 => 'MATK +%s%% against Wind monster',
+ 66 => 'Poison monster magic resistance +%s%%',
+ 67 => 'MATK +%s%% against Poison monster',
+ 68 => 'Holy monster magic resistance +%s%%',
+ 69 => 'MATK +%s%% against Holy monster',
+ 70 => 'Shadow monster magic resistance +%s%%',
+ 71 => 'MATK +%s%% against Shadow monster',
+ 72 => 'Ghost monster magic resistance +%s%%',
+ 73 => 'MATK +%s%% against Ghost monster',
+ 74 => 'Undead monster magic resistance +%s%%',
+ 75 => 'MATK +%s%% against Undead monster',
+ 76 => 'Armor element: Neutral',
+ 77 => 'Armor element: Water',
+ 78 => 'Armor element: Earth',
+ 79 => 'Armor element: Fire',
+ 80 => 'Armor element: Wind',
+ 81 => 'Armor element: Poison',
+ 82 => 'Armor element: Holy',
+ 83 => 'Armor element: Shadow',
+ 84 => 'Armor element: Ghost',
+ 85 => 'Armor element: Undead',
+ //86 => '',
+ 87 => 'Formless monster resistance +%s%%',
+ 88 => 'Undead monster resistance +%s%%',
+ 89 => 'Brute monster resistance +%s%%',
+ 90 => 'Plant monster resistance +%s%%',
+ 91 => 'Insect monster resistance +%s%%',
+ 92 => 'Fish monster resistance +%s%%',
+ 93 => 'Demon monster resistance +%s%%',
+ 94 => 'Demihuman monster resistance +%s%%',
+ 95 => 'Angel monster resistance +%s%%',
+ 96 => 'Dragon monster resistance +%s%%',
+ 97 => 'ATK +%s%% against Formless monster',
+ 98 => 'ATK +%s%% against Undead monster',
+ 99 => 'ATK +%s%% against Brute monster',
+ 100 => 'ATK +%s%% against Plant monster',
+ 101 => 'ATK +%s%% against Insect monster',
+ 102 => 'ATK +%s%% against Fish monster',
+ 103 => 'ATK +%s%% against Demon monster',
+ 104 => 'ATK +%s%% against Demihuman monster',
+ 105 => 'ATK +%s%% against Angel monster',
+ 106 => 'ATK +%s%% against Dragon monster',
+ 107 => 'MATK +%s%% against Formless monster',
+ 108 => 'MATK +%s%% against Undead monster',
+ 109 => 'MATK +%s%% against Brute monster',
+ 110 => 'MATK +%s%% against Plant monster',
+ 111 => 'MATK +%s%% against Insect monster',
+ 112 => 'MATK +%s%% against Fish monster',
+ 113 => 'MATK +%s%% against Devil monster',
+ 114 => 'MATK +%s%% against Demihuman monster',
+ 115 => 'MATK +%s%% against Angel monster',
+ 116 => 'MATK +%s%% against Dragon monster',
+ 117 => 'CRIT +%s against Formless monster',
+ 118 => 'CRIT +%s against Undead monster',
+ 119 => 'CRIT +%s against Brute monster',
+ 120 => 'CRIT +%s against Plant monster',
+ 121 => 'CRIT +%s against Insect monster',
+ 122 => 'CRIT +%s against Fish monster',
+ 123 => 'CRIT +%s against Demon monster',
+ 124 => 'CRIT +%s against Demihuman monster',
+ 125 => 'CRIT +%s against Angel monster',
+ 126 => 'CRIT +%s against Dragon monster',
+ 127 => 'Pierces %s%% DEF of Formless monster',
+ 128 => 'Pierces %s%% DEF of Undead monster',
+ 129 => 'Pierces %s%% DEF of Brute monster',
+ 130 => 'Pierces %s%% DEF of Plant monster',
+ 131 => 'Pierces %s%% DEF of Insect monster',
+ 132 => 'Pierces %s%% DEF of Fish monster',
+ 133 => 'Pierces %s%% DEF of Demon monster',
+ 134 => 'Pierces %s%% DEF of Demihuman monster',
+ 135 => 'Pierces %s%% DEF of Angel monster',
+ 136 => 'Pierces %s%% DEF of Dragon monster',
+ 137 => 'Pierces %s%% MDEF of Formless monster',
+ 138 => 'Pierces %s%% MDEF of Undead monster',
+ 139 => 'Pierces %s%% MDEF of Brute monster',
+ 140 => 'Pierces %s%% MDEF of Plant monster',
+ 141 => 'Pierces %s%% MDEF of Insect monster',
+ 142 => 'Pierces %s%% MDEF of Fish monster',
+ 143 => 'Pierces %s%% MDEF of Demon monster',
+ 144 => 'Pierces %s%% MDEF of Demihuman monster',
+ 145 => 'Pierces %s%% MDEF of Angel monster',
+ 146 => 'Pierces %s%% MDEF of Dragon monster',
+ 147 => 'ATK +%s%% against Normal monster',
+ 148 => 'ATK +%s%% against Boss monster',
+ 149 => 'Normal monster resistance +%s%%',
+ 150 => 'Boss monster resistance +%s%%',
+ 151 => 'MATK +%s%% against Normal monster',
+ 152 => 'MATK +%s%% against Boss monster',
+ 153 => 'Pierces %s%% DEF of Normal monster',
+ 154 => 'Pierces %s%% DEF of Boss monster',
+ 155 => 'Pierces %s%% MDEF of Normal monster',
+ 156 => 'Pierces %s%% MDEF of Boss monster',
+ 157 => 'ATK +%s%% against Small size monster',
+ 158 => 'ATK +%s%% against Medium size monster',
+ 159 => 'ATK +%s%% against Large size monster',
+ 160 => 'Small monster resistance +%s%%',
+ 161 => 'Medium monster resistance +%s%%',
+ 162 => 'Large monster resistance +%s%%',
+ 163 => 'Nullify weapon\'s damage size penalty',
+ 164 => 'Critical attack +%s%%',
+ 165 => 'Critical damage -%s%%',
+ 166 => 'Long range physical attack +%s%%',
+ 167 => 'Long range physical damage -%s%%',
+ 168 => 'Healing skills +%s%%',
+ 169 => 'Restoration gained from Healing skills +%s%%',
+ 170 => 'Variable cast time -%s%%',
+ 171 => 'After cast delay -%s%%',
+ 172 => 'Reduces SP cost by %s%%',
+ //173 => '',
+ //174 => '',
+ 175 => 'Weapon element: Neutral',
+ 176 => 'Weapon element: Water',
+ 177 => 'Weapon element: Earth',
+ 178 => 'Weapon element: Fire',
+ 179 => 'Weapon element: Wind',
+ 180 => 'Weapon element: Poison',
+ 181 => 'Weapon element: Holy',
+ 182 => 'Weapon element: Shadow',
+ 183 => 'Weapon element: Ghost',
+ 184 => 'Weapon element: Undead',
+ 185 => 'Indestructible in battle',
+ 186 => 'Indestructible in battle',
+ 187 => 'MATK against Small size monster +%s%%',
+ 188 => 'MATK against Medium size monster +%s%%',
+ 189 => 'MATK against Large size monster +%s%%',
+ 190 => 'Small monster magic resistance +%s%%',
+ 191 => 'Medium monster magic resistance +%s%%',
+ 192 => 'Large monster magic resistance +%s%%',
+ 193 => 'Elemental attacks resistance +%s%%',
+ 194 => 'Formless monster resistance +%s%%',
+ 195 => 'Undead monster resistance +%s%%',
+ 196 => 'Brute monster resistance +%s%%',
+ 197 => 'Plant monster resistance +%s%%',
+ 198 => 'Insect monster resistance +%s%%',
+ 199 => 'Fish monster resistance +%s%%',
+ 200 => 'Demon monster resistance +%s%%',
+ 201 => 'Demihuman monster resistance +%s%%',
+ 202 => 'Angel monster resistance +%s%%',
+ 203 => 'Dragon monster resistance +%s%%',
+ 204 => 'Long range physical attack +%s%%',
+ 205 => 'Long range physical damage -%s%%',
+ 206 => 'Demi-Human players resistance + %s%%',
+ 207 => 'Doram players resistance +%s%%',
+ 208 => 'ATK against Demi-Human players +%s%%',
+ 209 => 'ATK against Doram players +%s%%',
+ 210 => 'MATK against Demi-Human players +%s%%',
+ 211 => 'MATK against Doram players +%s%%',
+ 212 => 'Critical +%s for Demi-Human players',
+ 213 => 'Critical +%s for Doram players',
+ 214 => 'Pierces %s%% DEF of Demi-Human players',
+ 215 => 'Pierces %s%% DEF of Doram players',
+ 216 => 'Pierces %s%% MDEF of Demi-Human players',
+ 217 => 'Pierces %s%% MDEF of Doram players',
+ 218 => 'Recieved reflected damage -%s%%',
+ 219 => 'Melee physical damage +%s%%',
+ 220 => 'Melee physical damage -%s%%',
+ )
+?>
diff --git a/config/itemsflags.php b/config/itemsflags.php
new file mode 100644
index 000000000..ab509dfd9
--- /dev/null
+++ b/config/itemsflags.php
@@ -0,0 +1,11 @@
+ 'Item is available to Buying Stores',
+ 'flag_deadbranch' => 'Item is a Dead Branch type',
+ 'flag_container' => 'Item is part of a Container',
+ 'flag_uniqueid' => 'Item is a unique stack',
+ 'flag_bindonequip' => 'Item is bound to the character upon equipping',
+ 'flag_dropannounce' => 'Item has a special announcement to self on drop',
+ 'flag_noconsume' => 'Item is consumed on use',
+)
+?>
diff --git a/config/itemsubtypes.php b/config/itemsubtypes.php
new file mode 100644
index 000000000..f3e2502cd
--- /dev/null
+++ b/config/itemsubtypes.php
@@ -0,0 +1,43 @@
+ array(
+ '1haxe' => 'One-Handed Axe',
+ '1hspear' => 'One-Handed Spear',
+ '1hsword' => 'One-Handed Sword',
+ '2haxe' => 'Two-Handed Axe',
+ '2hspear' => 'Two-Handed Spear',
+ '2hstaff' => 'Two-Handed Staff',
+ '2hsword' => 'Two-Handed Sword',
+ 'book' => 'Book',
+ 'bow' => 'Bow',
+ 'dagger' => 'Dagger',
+ 'gatling' => 'Gatling Gun',
+ 'grenade' => 'Grenade Launcher',
+ 'huuma' => 'Fuuma Shuriken',
+ 'katar' => 'Katar',
+ 'knuckle' => 'Knuckle',
+ 'mace' => 'Mace',
+ 'musical' => 'Musical Instrument',
+ 'revolver' => 'Revolver',
+ 'rifle' => 'Rifle',
+ 'shotgun' => 'Shotgun',
+ 'staff' => 'Staff',
+ 'whip' => 'Whip'
+ ),
+ 'ammo' => array(
+ 'arrow' => 'Arrow',
+ 'bullet' => 'Bullet',
+ 'dagger' => 'Throwing Dagger',
+ 'cannonball' => 'Cannonball',
+ 'grenade' => 'Grenade',
+ 'kunai' => 'Kunai',
+ 'shell' => 'Shell',
+ 'shuriken' => 'Shuriken',
+ 'throwweapon' => 'Throwable Item (Sling Item)'
+ ),
+ 'card' => array(
+ 'normal' => 'Card',
+ 'enchant' => 'Enchant'
+ )
+)
+?>
\ No newline at end of file
diff --git a/config/itemtypes.php b/config/itemtypes.php
index a84a8e927..43a301350 100644
--- a/config/itemtypes.php
+++ b/config/itemtypes.php
@@ -1,18 +1,16 @@
'Healing',
- //1 => 'Unknown',
- 2 => 'Usable',
- 3 => 'Etc',
- 4 => 'Armor',
- 5 => 'Weapon',
- 6 => 'Card',
- 7 => 'Pet Egg',
- 8 => 'Pet Armor',
- //9 => 'Unknown2',
- 10 => 'Ammo',
- 11 => 'Delay Consume',
- 12 => 'Shadow Equipment',
- 18 => 'Cash Shop Reward'
+ 'ammo' => 'Ammo',
+ 'armor' => 'Armor',
+ 'card' => 'Card',
+ 'cash' => 'Cash Shop Reward',
+ 'delayconsume' => 'Delay Consume',
+ 'etc' => 'Etc',
+ 'healing' => 'Healing',
+ 'petarmor' => 'Pet Armor',
+ 'petegg' => 'Pet Egg',
+ 'shadowgear' => 'Shadow Equipment',
+ 'usable' => 'Usable',
+ 'weapon' => 'Weapon'
)
?>
diff --git a/config/itemtypes2.php b/config/itemtypes2.php
deleted file mode 100644
index 3e77770d6..000000000
--- a/config/itemtypes2.php
+++ /dev/null
@@ -1,48 +0,0 @@
- array( // Weapons
- 0 => 'Bare Fist',
- 1 => 'Dagger',
- 2 => 'One-Handed Sword',
- 3 => 'Two-Handed Sword',
- 4 => 'One-Handed Spear',
- 5 => 'Two-Handed Spear',
- 6 => 'One-Handed Axe',
- 7 => 'Two-Handed Axe',
- 8 => 'Mace',
- //9 => 'Unused',
- 10 => 'Staff',
- 11 => 'Bow',
- 12 => 'Knuckle',
- 13 => 'Musical Instrument',
- 14 => 'Whip',
- 15 => 'Book',
- 16 => 'Katar',
- 17 => 'Revolver',
- 18 => 'Rifle',
- 19 => 'Gatling Gun',
- 20 => 'Shotgun',
- 21 => 'Grenade Launcher',
- 22 => 'Fuuma Shuriken',
- 23 => 'Two-handed staves',
- //24 => '',
- 25 => 'Dual-wield Daggers',
- 26 => 'Dual-wield Swords',
- 27 => 'Dual-wield Axes',
- 28 => 'Dagger + Sword',
- 29 => 'Dagger + Axe',
- 30 => 'Sword + Axe'
- ),
- 10 => array( // Ammo
- 1 => 'Arrow',
- 2 => 'Throwing Dagger',
- 3 => 'Bullet',
- 4 => 'Shell',
- 5 => 'Grenade',
- 6 => 'Shuriken',
- 7 => 'Kunai',
- 8 => 'Cannonballs',
- 9 => 'Throwable Item (Sling Item)'
- )
-)
-?>
diff --git a/config/jobs.php b/config/jobs.php
index ff92604a9..07aa4cb3d 100644
--- a/config/jobs.php
+++ b/config/jobs.php
@@ -161,5 +161,25 @@
4228 => 'Baby Gunslinger',
4229 => 'Baby Rebellion',
//4238 => 'Baby Star Gladiator (Union)',
+
+ //4238 => 'Baby Star Glad (Union)',
+ 4239 => 'Star Emperor',
+ 4240 => 'Soul Reaper',
+ 4241 => 'Baby Star Emperor',
+ 4242 => 'Baby Soul Reaper',
+
+ 4252 => 'Dragon Knight',
+ 4253 => 'Meister',
+ 4254 => 'Shadow Cross',
+ 4255 => 'Arch Mage',
+ 4256 => 'Cardinal',
+ 4257 => 'WindHawk',
+ 4258 => 'Imperial Guard',
+ 4259 => 'Biolo',
+ 4260 => 'Abyss Chaser',
+ 4261 => 'Elemental Master',
+ 4262 => 'Inquisitor',
+ 4263 => 'Troubadour',
+ 4264 => 'Trouvere',
)
?>
diff --git a/config/jobs_alchemist.php b/config/jobs_alchemist.php
index fd82db4ee..2f573e0e4 100644
--- a/config/jobs_alchemist.php
+++ b/config/jobs_alchemist.php
@@ -5,6 +5,7 @@
4041 => 'Baby Alchemist',
4071 => 'Genetic',
4078 => 'Genetic+',
- 4107 => 'Baby Genetic'
+ 4107 => 'Baby Genetic',
+ 4259 => 'Biolo'
)
?>
diff --git a/config/jobs_blacksmith.php b/config/jobs_blacksmith.php
index 524a5c0d7..aef1f2e4d 100644
--- a/config/jobs_blacksmith.php
+++ b/config/jobs_blacksmith.php
@@ -5,6 +5,7 @@
4033 => 'Baby Blacksmith',
4058 => 'Mechanic',
4064 => 'Mechanic+',
- 4100 => 'Baby Mechanic'
+ 4100 => 'Baby Mechanic',
+ 4253 => 'Meister'
)
?>
diff --git a/config/jobs_gender_linked.php b/config/jobs_gender_linked.php
index d7c968c89..ed7c66f88 100644
--- a/config/jobs_gender_linked.php
+++ b/config/jobs_gender_linked.php
@@ -11,6 +11,12 @@
4075 => 'Minstrel+',
4076 => 'Wanderer+',
4104 => 'Baby Minstrel',
- 4105 => 'Baby Wanderer'
+ 4105 => 'Baby Wanderer',
+ 4211 => 'Kagerou',
+ 4212 => 'Oboro',
+ 4223 => 'Baby Kagerou',
+ 4224 => 'Baby Oboro',
+ 4263 => 'Troubadour',
+ 4264 => 'Trouvere'
)
?>
diff --git a/config/monster_ai.php b/config/monster_ai.php
new file mode 100644
index 000000000..a2b240099
--- /dev/null
+++ b/config/monster_ai.php
@@ -0,0 +1,31 @@
+ array('mode_canattack', 'mode_canmove'),
+ '02' => array('mode_canattack', 'mode_looter', 'mode_canmove'),
+ '03' => array('mode_changetargetmelee', 'mode_canattack', 'mode_assist', 'mode_canmove'),
+ '04' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_angry', 'mode_canattack', 'mode_aggressive', 'mode_canmove'),
+ '05' => array('mode_changetargetchase', 'mode_canattack', 'mode_aggressive', 'mode_canmove'),
+ '06' => array(),
+ '07' => array('mode_changetargetmelee', 'mode_canattack', 'mode_assist', 'mode_looter', 'mode_canmove'),
+ '08' => array('mode_targetweak', 'mode_changetargetchase', 'mode_changetargetmelee', 'mode_canattack', 'mode_aggressive', 'mode_canmove'),
+ '09' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_canattack', 'mode_castsensoridle', 'mode_aggressive', 'mode_canmove'),
+ '10' => array('mode_canattack', 'mode_aggressive'),
+ '11' => array('mode_canattack', 'mode_aggressive'),
+ '12' => array('mode_changetargetchase', 'mode_canattack', 'mode_aggressive', 'mode_canmove'),
+ '13' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_canattack', 'mode_assist', 'mode_aggressive', 'mode_canmove'),
+ //14 => array(),
+ //15 => array(),
+ //16 => array(),
+ '17' => array('mode_canattack', 'mode_castsensoridle', 'mode_canmove'),
+ //18 => array(),
+ '19' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_canattack', 'mode_castsensoridle', 'mode_aggressive', 'mode_canmove'),
+ '20' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_castsensorchase', 'mode_canattack', 'mode_castsensoridle', 'mode_aggressive', 'mode_canmove'),
+ '21' => array('mode_changetargetchase', 'mode_changetargetmelee', 'mode_changechase', 'mode_castsensorchase', 'mode_canattack', 'mode_castsensoridle', 'mode_aggressive', 'mode_canmove'),
+ //22 => array(),
+ //23 => array(),
+ '24' => array('mode_canattack', 'mode_norandomwalk', 'mode_canmove'),
+ '25' => array('mode_canmove'),
+ '26' => array('mode_randomtarget', 'mode_changetargetchase', 'mode_changetargetmelee', 'mode_changechase', 'mode_castsensorchase', 'mode_canattack', 'mode_castsensoridle', 'mode_aggressive', 'mode_canmove'),
+ '27' => array('mode_randomtarget', 'mode_canattack', 'mode_aggressive'),
+)
+?>
diff --git a/config/monstermode.php b/config/monstermode.php
index 0c2126b35..27ecd749f 100644
--- a/config/monstermode.php
+++ b/config/monstermode.php
@@ -1,32 +1,29 @@
'Can Move',
- 2 => 'Looter',
- 4 => 'Aggressive',
- 8 => 'Assist',
- 16 => 'Cast Sensor Idle',
- 32 => 'Boss',
- 64 => 'Plant',
- 128 => 'Can Attack',
- 256 => 'Detector',
- 512 => 'Cast Sensor Chase',
- 1024 => 'Change Chase',
- 2048 => 'Angry',
- 4096 => 'Change Target Melee',
- 8192 => 'Change Target Chase',
- 16384 => 'Target Weak',
- 32768 => 'Random Target',
- 65536 => 'Ignore Melee',
- 131072 => 'Ignore Magic',
- 262144 => 'Ignore Ranged',
- 524288 => 'MVP',
- 1048576 => 'Ignore Misc',
- 2097152 => 'Knockback Immune',
- 4194304 => 'Teleport Block',
- 8388608 => 'Unknown',
- 16777216 => 'Fixed Item Drop',
- 33554432 => 'Detector',
- 67108864 => 'Status Immune',
- 134217728 => 'Skill Immune',
+ 'mode_aggressive' => 'Aggressive',
+ 'mode_angry' => 'Angry',
+ 'mode_assist' => 'Assist',
+ 'mode_canattack' => 'Can Attack',
+ 'mode_canmove' => 'Can Move',
+ 'mode_castsensorchase' => 'Cast Sensor Chase',
+ 'mode_castsensoridle' => 'Cast Sensor Idle',
+ 'mode_changechase' => 'Change Chase',
+ 'mode_changetargetchase' => 'Change Target Chase',
+ 'mode_changetargetmelee' => 'Change Target Melee',
+ 'mode_detector' => 'Detector',
+ 'mode_fixeditemdrop' => 'Fixed Item Drop',
+ 'mode_ignoremagic' => 'Ignore Magic',
+ 'mode_ignoremelee' => 'Ignore Melee',
+ 'mode_ignoremisc' => 'Ignore Misc',
+ 'mode_ignoreranged' => 'Ignore Ranged',
+ 'mode_knockbackimmune' => 'Knockback Immune',
+ 'mode_looter' => 'Looter',
+ 'mode_mvp' => 'MVP',
+ 'mode_norandomwalk' => 'Plant',
+ 'mode_randomtarget' => 'Random Target',
+ 'mode_skillimmune' => 'Skill Immune',
+ 'mode_statusimmune' => 'Status Immune',
+ 'mode_targetweak' => 'Target Weak',
+ 'mode_teleportblock' => 'Teleport Block',
)
?>
diff --git a/config/races.php b/config/races.php
index 59fdbf4f7..488216b7f 100644
--- a/config/races.php
+++ b/config/races.php
@@ -1,16 +1,15 @@
'Formless',
- 1 => 'Undead',
- 2 => 'Brute',
- 3 => 'Plant',
- 4 => 'Insect',
- 5 => 'Fish',
- 6 => 'Demon',
- 7 => 'Demi-Human',
- 8 => 'Angel',
- 9 => 'Dragon',
- 10 => 'Human'
+ 'Formless' => 'Formless',
+ 'Undead' => 'Undead',
+ 'Brute' => 'Brute',
+ 'Plant' => 'Plant',
+ 'Insect' => 'Insect',
+ 'Fish' => 'Fish',
+ 'Demon' => 'Demon',
+ 'Demihuman' => 'Demi-Human',
+ 'Angel' => 'Angel',
+ 'Dragon' => 'Dragon'
)
?>
diff --git a/config/servers.php b/config/servers.php
index 47aa0640d..8ea3e7518 100644
--- a/config/servers.php
+++ b/config/servers.php
@@ -41,6 +41,14 @@
'Persistent' => true,
'Timezone' => null // Possible values is as described in the comment in DbConfig.
),
+ // Web server configuration.
+ 'WebDbConfig' => array(
+ 'Hostname' => '127.0.0.1',
+ 'Username' => 'ragnarok',
+ 'Password' => 'ragnarok',
+ 'Database' => 'ragnarok',
+ 'Persistent' => true
+ ),
// Login server configuration.
'LoginServer' => array(
'Address' => '127.0.0.1',
@@ -64,23 +72,44 @@
'Mvp' => 100 // MVP bonus exp rate
),
'DropRates' => array(
+ // If drop rate was below this amount and bonus is applied to it, the bonus can't make it exceed this amount.
+ 'DropRateCap' => 9000,
// The rate the common items (in the ETC tab, besides card) are dropped
'Common' => 100,
'CommonBoss' => 100,
+ 'CommonMVP' => 100,
+ 'CommonMin' => 1,
+ 'CommonMax' => 10000,
// The rate healing items (that restore HP or SP) are dropped
'Heal' => 100,
'HealBoss' => 100,
+ 'HealMVP' => 100,
+ 'HealMin' => 1,
+ 'HealMax' => 10000,
// The rate usable items (in the item tab other then healing items) are dropped
'Useable' => 100,
'UseableBoss' => 100,
+ 'UseableMVP' => 100,
+ 'UseableMin' => 1,
+ 'UseableMax' => 10000,
// The rate at which equipment is dropped
'Equip' => 100,
'EquipBoss' => 100,
+ 'EquipMVP' => 100,
+ 'EquipMin' => 1,
+ 'EquipMax' => 10000,
// The rate at which cards are dropped
'Card' => 100,
'CardBoss' => 100,
+ 'CardMVP' => 100,
+ 'CardMin' => 1,
+ 'CardMax' => 10000,
// The rate adjustment for the MVP items that the MVP gets directly in their inventory
- 'MvpItem' => 100
+ 'MvpItem' => 100,
+ 'MvpItemMin' => 1,
+ 'MvpItemMax' => 10000,
+ // 0 - official order (Show message "Note: Only one MVP drop will be rewarded.") , 2 - all items
+ 'MvpItemMode' => 0,
),
'CharServer' => array(
'Address' => '127.0.0.1',
diff --git a/config/sizes.php b/config/sizes.php
index 96de6938e..80604a9f7 100644
--- a/config/sizes.php
+++ b/config/sizes.php
@@ -1,8 +1,8 @@
'Small',
- 1 => 'Medium',
- 2 => 'Large'
+ 'Small' => 'Small',
+ 'Medium' => 'Medium',
+ 'Large' => 'Large'
)
?>
diff --git a/config/trade_restrictions.php b/config/trade_restrictions.php
new file mode 100644
index 000000000..f5f6c6f39
--- /dev/null
+++ b/config/trade_restrictions.php
@@ -0,0 +1,13 @@
+ 'Can\'t be dropped',
+ 'trade_notrade' => 'Can\'t be traded with player',
+ 'trade_tradepartner' => 'Can\'t be traded with partner',
+ 'trade_nosell' => 'Can\'t be sold to NPC',
+ 'trade_nocart' => 'Can\'t be put in Cart',
+ 'trade_nostorage' => 'Can\'t be put in Storage',
+ 'trade_noguildstorage' => 'Can\'t be put in Guild Storage',
+ 'trade_nomail' => 'Can\'t be attached in Mail',
+ 'trade_noauction' => 'Can\'t be auctioned'
+)
+?>
diff --git a/data/npc/web_commands.txt b/data/npc/web_commands.txt
index 990b0d3fc..9493394ce 100644
--- a/data/npc/web_commands.txt
+++ b/data/npc/web_commands.txt
@@ -8,24 +8,26 @@
//= commands every 2 seconds.
//===== Additional Comments: =================================
//= 1.0 First Version.
+//= 1.1 Fixed code to prevent single-run senarios.
//============================================================
- script Commands -1,{
OnInit:
start:
-initnpctimer;
-end;
+ initnpctimer;
+ end;
+
OnTimer2000:
-set $@nb2,query_sql("SELECT COUNT(*) FROM cp_commands WHERE done=0",$@count);
-if($@count != 0) {
- set $@nb,query_sql("SELECT command,id,account_id FROM cp_commands WHERE done=0",$@command$,$@id,$@account_id);
- if(compare($@command$,"@")) {
- attachrid($@account_id[0]);
- atcommand $@command$[0];
- } else charcommand $@command$[0];
- query_sql("UPDATE cp_commands SET done='1' WHERE command='"+$@command$[0]+"' AND id='"+$@id[0]+"'");
-} else
-finish:
-stopnpctimer;
-goto start;
-}
\ No newline at end of file
+ .@nb2 = query_sql("SELECT COUNT(*) FROM cp_commands WHERE done=0",.@count);
+ if(.@count != 0) {
+ .@nb = query_sql("SELECT command,id,account_id FROM cp_commands WHERE done=0 ORDER BY id LIMIT 1",.@command$,.@id,.@account_id);
+ if(compare(.@command$,"@")) {
+ attachrid(.@account_id[0]);
+ atcommand .@command$[0];
+ } else charcommand .@command$[0];
+ query_sql("UPDATE cp_commands SET done='1' WHERE command='"+.@command$[0]+"' AND id='"+.@id[0]+"'");
+ .@nb = 0; .@nb2 = 0; .@count = 0; .@command$ = 0; .@id = 0; .@account_id = 0;
+ }
+ stopnpctimer;
+ goto start;
+}
diff --git a/index.php b/index.php
index b7235f2ff..55c7f2c15 100644
--- a/index.php
+++ b/index.php
@@ -1,21 +1,8 @@
Error';
- echo '
PHP 5.2.1 or higher is required to use Flux Control Panel.
';
- echo 'You are running '.PHP_VERSION.'
';
- exit;
-}
-
-// Disable Zend Engine 1 compatibility mode.
-// See: http://www.php.net/manual/en/ini.core.php#ini.zend.ze1-compatibility-mode
-ini_set('zend.ze1_compatibility_mode', 0);
// Time started.
define('__START__', microtime(true));
-error_reporting(E_ALL);
-ini_set('display_errors', 1);
-
define('FLUX_ROOT', str_replace('\\', '/', dirname(__FILE__)));
define('FLUX_DATA_DIR', 'data');
define('FLUX_CONFIG_DIR', 'config');
@@ -54,17 +41,12 @@
// Vendor libraries.
try {
- if (!extension_loaded('pdo')) {
- throw new Flux_Error('The PDO extension is required to use Flux, please make sure it is installed along with the PDO_MYSQL driver.');
- }
- elseif (!extension_loaded('pdo_mysql')) {
- throw new Flux_Error('The PDO_MYSQL driver for the PDO extension must be installed to use Flux. Please consult the PHP manual for installation instructions.');
- }
-
// Initialize Flux.
Flux::initialize(array(
- 'appConfigFile' => FLUX_CONFIG_DIR.'/application.php',
- 'serversConfigFile' => FLUX_CONFIG_DIR.'/servers.php',
+ 'appConfigFile' => FLUX_CONFIG_DIR.'/application.php',
+ 'serversConfigFile' => FLUX_CONFIG_DIR.'/servers.php',
+ 'appConfigFileImport' => FLUX_CONFIG_DIR.'/import/application.php',
+ 'serversConfigFileImport' => FLUX_CONFIG_DIR.'/import/servers.php',
));
// Set time limit.
@@ -107,24 +89,26 @@
mkdir($directory, 0777);
}
}
-
+
if (Flux::config('RequireOwnership') && function_exists('posix_getuid'))
$uid = posix_getuid();
-
+
$directories = array(
FLUX_DATA_DIR.'/logs' => 'log storage',
FLUX_DATA_DIR.'/itemshop' => 'item shop image',
FLUX_DATA_DIR.'/tmp' => 'temporary'
);
-
+
foreach ($directories as $directory => $directoryFunction) {
$directory = realpath($directory);
- if (!is_writable($directory))
+ if (!is_dir($directory))
+ mkdir($directory, 0600);
+ if (!is_writable($directory) && is_dir($directory))
throw new Flux_PermissionError("The $directoryFunction directory '$directory' is not writable. Remedy with `chmod 0600 $directory`");
if (Flux::config('RequireOwnership') && function_exists('posix_getuid') && fileowner($directory) != $uid)
throw new Flux_PermissionError("The $directoryFunction directory '$directory' is not owned by the executing user. Remedy with `chown -R ".posix_geteuid().":".posix_geteuid()." $directory`");
}
-
+
if (ini_get('session.use_trans_sid'))
throw new Flux_Error("The 'session.use_trans_sid' php.ini configuration must be turned off for Flux to work.");
@@ -158,8 +142,9 @@
$accessConfig->set('unauthorized.index', AccountLevel::ANYONE);
$authComponent = Flux_Authorization::getInstance($accessConfig, Flux::$sessionData);
- if (!Flux::config('DebugMode')) {
- ini_set('display_errors', 0);
+ if (Flux::config('DebugMode')) {
+ error_reporting(E_ALL);
+ ini_set('display_errors', 1);
}
// Dispatch requests->modules->actions->views.
diff --git a/lang/en_us.php b/lang/en_us.php
index f9a33c9df..177488ae2 100755
--- a/lang/en_us.php
+++ b/lang/en_us.php
@@ -1,5 +1,5 @@
'English',
'YesLabel' => 'Yes',
@@ -51,11 +51,12 @@
'ItemIdentifyLabel' => 'Identified',
'ItemRefineLabel' => 'Refine',
'ItemBrokenLabel' => 'Broken',
- 'ItemCard0Label' => 'Card 0',
- 'ItemCard1Label' => 'Card 1',
- 'ItemCard2Label' => 'Card 2',
- 'ItemCard3Label' => 'Card 3',
-
+ 'ItemCard0Label' => 'Slot 1',
+ 'ItemCard1Label' => 'Slot 2',
+ 'ItemCard2Label' => 'Slot 3',
+ 'ItemCard3Label' => 'Slot 4',
+ 'ItemRandOptionsLabel' => 'Random options',
+
//SIDEBAR
//FluxCP Menu Items
//Categories
@@ -83,25 +84,24 @@
'DownloadsLabel' => 'Downloads',
'RulesLabel' => 'Rules',
'ContactUsLabel' => 'Contact Us',
- 'MyAccountLabel' => 'My Account',
+ 'MyAccountLabel' => 'My Account',
'HistoryLabel' => 'History',
- 'ServiceDeskLabel' => 'Service Desk',
- 'PurchaseLabel' => 'Purchase',
- 'DonateLabel' => 'Donate',
- 'ServerInfoLabel' => 'Server Info',
- 'ServerStatusLabel' => 'Server Status',
- 'WoeHoursLabel' => 'WOE Hours',
+ 'PurchaseLabel' => 'Purchase',
+ 'DonateLabel' => 'Donate',
+ 'ServerInfoLabel' => 'Server Info',
+ 'ServerStatusLabel' => 'Server Status',
+ 'WoeHoursLabel' => 'WOE Hours',
'CastlesLabel' => 'Castles',
- 'WhosOnlineLabel' => "Who's Online",
- 'MapStaticsLabel' => 'Map Statics',
- 'RankingInfoLabel' => 'Ranking Info',
- 'VendingInfoLabel' => 'Vending Info',
- 'BuyingstoreInfoLabel' => 'Buyingstore Info',
- 'ItemDatabaseLabel' => 'Item Database',
- 'MobDatabaseLabel' => 'Mob Database',
- 'JoinUsInFacebookLabel' => 'Join us on Facebook!',
- 'RateUsOnRMSLabel' => 'Rate us on RMS!',
-
+ 'WhosOnlineLabel' => "Who's Online",
+ 'MapStaticsLabel' => 'Map Statics',
+ 'RankingInfoLabel' => 'Ranking Info',
+ 'VendingInfoLabel' => 'Vending Info',
+ 'BuyingstoreInfoLabel' => 'Buyingstore Info',
+ 'ItemDatabaseLabel' => 'Item Database',
+ 'MobDatabaseLabel' => 'Mob Database',
+ 'JoinUsInFacebookLabel' => 'Join us on Facebook!',
+ 'RateUsOnRMSLabel' => 'Rate us on RMS!',
+
// Module: account
// - account/changemail
'EmailChangeTitle' => 'Change E-mail',
@@ -180,12 +180,13 @@
'AccountPasswordLabel' => 'Your Password',
'AccountPassConfirmLabel' => 'Confirm Password',
'AccountEmailLabel' => 'E-mail Address',
- 'AccountEmailLabel2' => 'Confirm E-mail Address',
+ 'AccountEmailLabel2' => 'Confirm E-mail Address',
'AccountGenderLabel' => 'Gender',
'AccountBirthdateLabel' => 'Birthdate',
'AccountSecurityLabel' => 'Security Code',
'AccountCreateButton' => 'Create My Account',
'AccountInvalidChars' => "A username can only contain these characters: '%s'",
+ 'AccountRecaptchaKey' => 'You need Recaptcha keys, see more in config/applications.php (ReCaptchaPublicKey/ReCaptchaPrivateKey)',
'InvalidLoginServer' => 'Invalid login server selected, please try again with a valid server.',
'InvalidLoginCredentials' => 'Invalid login credentials, please verify that you typed the correct info and try again.',
'UnexpectedLoginError' => 'Unexpected error occurred, please try again or report to an admin.',
@@ -270,7 +271,6 @@
'ResetPassDisallowed' => 'Password recovery cannot be used for this account.',
'ResetPassFailed' => 'Failed to send reset password e-mail.',
'ResetPassEmailSent' => 'An e-mail has been sent with details on how to reset your password.',
- 'ResetPassTitle' => 'Reset Password',
'ResetPassInfo' => 'If you lost your password, you can re-set it by entering the e-mail address you used to register your account.',
'ResetPassInfo2' => 'An e-mail will then be sent to the specified address with a link allowing you to reset your password, therefore a valid e-mail address is required.',
'ResetPassServerLabel' => 'Registered Server',
@@ -366,7 +366,7 @@
'XferLogCharNameLabel' => 'To Character',
'XferLogNotReceived' => 'You have not received any credit transfers.',
'XferLogNotSent' => 'You have not sent any credit transfers.',
-
+
// Module: character
// - character/changeslot
// - character/index
@@ -396,20 +396,20 @@
'DivorceText3' => 'Wedding rings will also be deleted.',
'DivorceButton' => 'Yes, do it please.',
'DivorceSuccessful' => '%s has been divorced!',
-
+
// Module: cplog
// - cplog/index.php
// - cplog/login.php
// - cplog/paypal.php
// - cplog/resetpass.php
// - cplog/txnview.php
-
+
// Module: donate
// - donate/complete
// - donate/history
// - donate/index
// - donate/trusted
-
+
// Module: errors
// - errors/missing_action
'MissingActionTitle' => 'Missing Action',
@@ -425,12 +425,12 @@
'MissingViewActLabel' => 'Action:',
'MissingViewReqLabel' => 'Request URI:',
'MissingViewLocLabel' => 'File system location:',
-
+
// Module: guild
// - guild/export
// - guild/index
// - guild/view
-
+
// Module: history
// - history/cplogin
'HistoryCpLoginTitle' => 'Control Panel Logins',
@@ -474,7 +474,7 @@
'HistoryPassResetResetDate' => 'Reset Date',
'HistoryPassResetResetIp' => 'Reset IP',
'HistoryNoPassResets' => 'No password reset attempts found.',
-
+
// Module: ipban
// - ipban/add
'IpbanAddTitle' => 'Add IP Ban',
@@ -525,20 +525,20 @@
'IpbanEnterUnbanReason' => 'Please enter a reason for lifting the IP ban(s).',
'IpbanUnbanned' => 'Lifted selected IP ban(s)!',
'IpbanUnbanFailed' => 'Failed to lift %d of the specified IP unban(s)!',
-
+
// Module: item
// - item/add
// - item/copy
// - item/edit
// - item/index
// - item/view
-
+
// Module: itemshop
// - itemshop/add
// - itemshop/delete
// - itemshop/edit
// - itemshop/imagedel
-
+
// Module: logdata
// - logdata/chat
// - logdata/cashpoints
@@ -573,10 +573,10 @@
'PickLogItemLabel' => 'Item Name',
'PickLogAmountLabel' => 'Amount',
'PickLogRefineLabel' => 'Refine',
- 'PickLogCard0Label' => 'Card 0',
- 'PickLogCard1Label' => 'Card 1',
- 'PickLogCard2Label' => 'Card 2',
- 'PickLogCard3Label' => 'Card 3',
+ 'PickLogCard0Label' => 'Slot 1',
+ 'PickLogCard1Label' => 'Slot 2',
+ 'PickLogCard2Label' => 'Slot 3',
+ 'PickLogCard3Label' => 'Slot 4',
'PickLogMapLabel' => 'Map',
// - logdata/branch
'BranchLogTitle' => 'List Branch Log',
@@ -637,7 +637,7 @@
'ZenyLogMapLabel' => 'Map',
// - logdata/feeding
'FeedingLogTitle' => 'Feeding Log',
-
+
// Module: mail
// - mail/index
'MailerTitle' => 'Form Mailer',
@@ -653,7 +653,7 @@
'MailerSubjectLabel' => 'Subject',
'MailerBodyLabel' => 'Body',
'MailerSelectTemplateLabel' => 'Select Template',
-
+
// Module: main
// - main/index
'MainPageHeading' => 'Flux Control Panel',
@@ -669,11 +669,11 @@
'PageNotFoundInfo' => 'The page you have requested was not found on our server. Please check the address and make sure it is correct, and try again.',
// - main/preprocess
'DisallowedDuringWoE' => 'The page you have requested is not accessible during WoE.',
-
+
// Module: monster
// - monster/index
// - monster/view
-
+
// Module: purchase
// - purchase/add
// - purchase/cart
@@ -682,12 +682,12 @@
// - purchase/index
// - purchase/pending
// - purchase/remove
-
+
// Module: ranking
// - ranking/character
// - ranking/guild
// - ranking/zeny
-
+
// Module: server
// - server/info
'ServerInfoTitle' => 'Server Information',
@@ -710,20 +710,20 @@
'ServerStatusMapLabel' => 'Map Server',
'ServerStatusOnlineLabel' => 'Players Online',
'ServerStatusPeakLabel' => 'Player Peak',
-
+
// Module: service
// - service/tos
'TermsTitle' => 'Terms of Service',
'TermsHeading' => 'Terms of Service',
'TermsInfo' => 'Please read before creating an account!',
'TermsInfo2' => "FOR CONTROL PANEL ADMINISTRATOR: You may add your server's ToS in this view file directly. The location of the view file is: %s",
-
+
// Module: unauthorized
// - unauthorized/index
'UnauthorizedTitle' => 'Unauthorized',
'UnauthorizedHeading' => 'Unauthorized',
'UnauthorizedInfo' => 'You are unauthorized to view this page. Redirecting…',
-
+
// Module: woe
// - woe/index
'WoeTitle' => 'WoE Hours',
@@ -733,10 +733,10 @@
'WoeServerLabel' => 'Servers',
'WoeTimesLabel' => 'War of Emperium Times',
'WoeNotScheduledInfo' => 'There are no scheduled WoE hours.',
-
+
// Module: contactform
'CFTitleSubmit' => 'Contact Us',
-
+
// Module: News and Pages
'CMSNewsHeader' => 'Announcements',
'CMSPageHeader' => 'Content Management System',
@@ -749,7 +749,7 @@
'CMSNewsAdded' => 'News added to system',
'CMSPagesAdded' => 'Your new page has been added',
'CMSNewsUpdated' => 'News updated',
- 'CMSPageUpdated' => 'Your page has been updated',
+ 'CMSPageUpdated' => 'Your page has been updated',
'CMSNewsAddTitle' => 'Add a news item',
'CMSPageAddTitle' => 'Add a new page',
'CMSNewsEditTitle' => 'Edit news',
@@ -779,17 +779,17 @@
'CMSOptionalLabel' => '(Optional)',
'CMSRequiredLabel' => '(Required)',
'CMSCreateLabel' => 'Add News',
-
+
// Module: vending
'TLHeaderTasks' => 'Tasks',
- 'TLHeaderOwner' => 'Owner',
- 'TLHeaderPriority' => 'Priority',
- 'TLHeaderStatus' => 'Status',
+ 'TLHeaderOwner' => 'Owner',
+ 'TLHeaderPriority' => 'Priority',
+ 'TLHeaderStatus' => 'Status',
'TLHeaderCreated' => 'Created',
'TLHeaderModified' => 'Modified',
'TLHeaderResources' => 'Additional Resources',
'TLHeaderBody' => 'Body',
-
+
// Module: servicedesk
'SDHeader' => 'Service Desk',
'SDCreateNew' => 'Create a new ticket',
@@ -801,18 +801,18 @@
'SDNoInactiveTickets' => 'You have no in-active tickets at the moment.',
'SDNoClosedTickets' => 'There are no Closed tickets in the database.',
'SDNoCats' => 'There are no categories within the database.',
- 'SDHuh' => 'You should not be here o.O',
+ 'SDHuh' => 'You should not be here o.O',
'SDPointerChatLog' => 'We recommend pasting to pastebin.com then putting the link in here.',
'SDPointerScreenShot' => 'Provide image links as evidence',
'SDPointerVideoLink' => 'We recommend uploading to youtube then putting the link in here.',
- 'SDHeaderID' => 'Ticket #',
- 'SDHeaderSubject' => 'Subject',
+ 'SDHeaderID' => 'Ticket #',
+ 'SDHeaderSubject' => 'Subject',
'SDHeaderCategory' => 'Category',
- 'SDHeaderStatus' => 'Current Status',
+ 'SDHeaderStatus' => 'Current Status',
'SDHeaderLastAuthor' => 'Last Author',
- 'SDHeaderTimestamp' => 'Created',
- 'SDHeaderAccount' => 'Account',
- 'SDHeaderTeam' => 'Team',
+ 'SDHeaderTimestamp' => 'Created',
+ 'SDHeaderAccount' => 'Account',
+ 'SDHeaderTeam' => 'Team',
'SDH3ActiveTickets' => 'Active Tickets',
'SDH3InActiveTickets' => 'In-Active Tickets',
'SDH3ClosedTickets' => 'Closed Tickets',
diff --git a/lang/es_es.php b/lang/es_es.php
index f219dd887..7a1c8e315 100755
--- a/lang/es_es.php
+++ b/lang/es_es.php
@@ -2,19 +2,19 @@
// Translation by: jaBote
// Revised by: -
// Translator Notes:
-// This is a Spanish/Spain translation. However, my efforts were towards the most neutral
+// This is a Spanish/Spain translation. However, my efforts were towards the most neutral
// translation I've been able to achieve.
-// In case of dispute or suggestions about this translation, please contact me (jaBote in Hercules
+// In case of dispute or suggestions about this translation, please contact me (jaBote in Hercules
// forums), you can use Spanish if you want.
-// Also, please avoid disrespectful destructive criticism towards this translation. I've used a
-// translation criteria that should fit most Spanish-speaking servers. Expect translations of some
-// RO slang to Spanish when possible but don't expect any forced overzealous mindless translations
+// Also, please avoid disrespectful destructive criticism towards this translation. I've used a
+// translation criteria that should fit most Spanish-speaking servers. Expect translations of some
+// RO slang to Spanish when possible but don't expect any forced overzealous mindless translations
// where it simply won't fit. Arbitrary? Maybe. Results? Better than mindlessly translating everything.
// Example: storage -> almacén ? No! That'd require scripts to be translated for that!
// Example: ban -> expulsión -> bloqueo ? Yes! No scripts to be translated and it's widely understood!
// ip ban -> IP con acceso prohibido ?
-
-return array(
+
+return array(
// Generic/Misc.
'Language' => 'Spanish',
'YesLabel' => 'Sí',
@@ -66,11 +66,11 @@
'ItemIdentifyLabel' => 'Identificado',
'ItemRefineLabel' => 'Refinado',
'ItemBrokenLabel' => 'Roto',
- 'ItemCard0Label' => 'Carta 0',
- 'ItemCard1Label' => 'Carta 1',
- 'ItemCard2Label' => 'Carta 2',
- 'ItemCard3Label' => 'Carta 3',
-
+ 'ItemCard0Label' => 'Carta 1',
+ 'ItemCard1Label' => 'Carta 2',
+ 'ItemCard2Label' => 'Carta 3',
+ 'ItemCard3Label' => 'Carta 4',
+
//SIDEBAR
//FluxCP Menu Items
//Categories
@@ -206,6 +206,7 @@
'AccountSecurityLabel' => 'Código de Seguridad',
'AccountCreateButton' => 'Crear Cuenta',
'AccountInvalidChars' => "El nombre de usuario solo puede contener los siguientes caracteres: '%s'",
+ 'AccountRecaptchaKey' => 'Necesitas claves de Recaptcha, ver más en config/applications.php (ReCaptchaPublicKey/ReCaptchaPrivateKey)',
'InvalidLoginServer' => 'Has seleccionado un login server no válido. Inténtalo de nuevo seleccionando un servidor válido.',
'InvalidLoginCredentials' => 'Las credenciales introducidas no son válidas. Asegúrate de haber escrito la información correcta e inténtalo de nuevo.',
'UnexpectedLoginError' => 'Ha ocurrido un fallo inesperado. Inténtalo de nuevo o contacta con un administrador.',
@@ -382,7 +383,7 @@
'XferLogCharNameLabel' => 'Para el Personaje',
'XferLogNotReceived' => 'No has recibido ninguna transferencia de crédito.',
'XferLogNotSent' => 'No has hecho ninguna transferencia de crédito.',
-
+
// Module: character
// - character/changeslot
// - character/index
@@ -412,23 +413,23 @@
'DivorceText3' => 'Además, sus Anillos de matrimonio serán eliminados.',
'DivorceButton' => 'Sí, hazlo por favor.',
'DivorceSuccessful' => '¡Se ha divorciado a %s!',
-
+
// Module: cplog
// - cplog/index.php
// - cplog/login.php
// - cplog/paypal.php
// - cplog/resetpass.php
// - cplog/txnview.php
-
+
// Module: donate
// - donate/complete
// - donate/history
// - donate/index
// - donate/trusted
-
+
// Module: errors
// - errors/missing_action
- 'MissingActionTitle' => 'Acción Faltante', // Nociones de Programación Orientada a Objetos: Acción = "Página"
+ 'MissingActionTitle' => 'Acción Faltante', // Nociones de Programación Orientada a Objetos: Acción = "Página"
'MissingActionHeading' => 'Acción Faltante!', // Una acción es un conjunto de Vistas, cada elemento de la acción
'MissingActionModLabel' => 'Módulo:',
'MissingActionActLabel' => 'Acción:',
@@ -441,12 +442,12 @@
'MissingViewActLabel' => 'Acción:',
'MissingViewReqLabel' => 'URI de petición:',
'MissingViewLocLabel' => 'Localización en el sistema de archivos:',
-
+
// Module: guild
// - guild/export
// - guild/index
// - guild/view
-
+
// Module: history
// - history/cplogin
'HistoryCpLoginTitle' => 'Accesos al Panel de Control',
@@ -490,7 +491,7 @@
'HistoryPassResetResetDate' => 'Fecha de la Recuperación',
'HistoryPassResetResetIp' => 'IP de la Recuperación',
'HistoryNoPassResets' => 'No se ha encontrado ningún intento de recuperar la contraseña.',
-
+
// Module: ipban
// - ipban/add
'IpbanAddTitle' => 'Añadir Bloqueos de IP',
@@ -541,20 +542,20 @@
'IpbanEnterUnbanReason' => 'Introduce un motivo para desbloquear esta(s) IP.',
'IpbanUnbanned' => '¡Se ha(n) desbloqueado la(s) IP seleccionada(s)!',
'IpbanUnbanFailed' => '¡No se pudo/pudieron desbloquear %d IP especificada(s)!',
-
+
// Module: item
// - item/add
// - item/copy
// - item/edit
// - item/index
// - item/view
-
+
// Module: itemshop
// - itemshop/add
// - itemshop/delete
// - itemshop/edit
// - itemshop/imagedel
-
+
// Module: logdata
// - logdata/chat
// - logdata/command
@@ -579,10 +580,10 @@
'PickLogItemLabel' => 'Nombre de Objeto',
'PickLogAmountLabel' => 'Cantidad',
'PickLogRefineLabel' => 'Refinado',
- 'PickLogCard0Label' => 'Carta 0',
- 'PickLogCard1Label' => 'Carta 1',
- 'PickLogCard2Label' => 'Carta 2',
- 'PickLogCard3Label' => 'Carta 3',
+ 'PickLogCard0Label' => 'Carta 1',
+ 'PickLogCard1Label' => 'Carta 2',
+ 'PickLogCard2Label' => 'Carta 3',
+ 'PickLogCard3Label' => 'Carta 4',
'PickLogMapLabel' => 'Mapa',
// - logdata/zeny
'ZenyLogTitle' => 'Lista de Transacciones de Zeny',
@@ -594,7 +595,7 @@
'ZenyLogTypeLabel' => 'Tipo',
'ZenyLogAmountLabel' => 'Cantidad',
'ZenyLogMapLabel' => 'Mapa',
-
+
// Module: mail
// - mail/index
'MailerTitle' => 'Enviar Correo Electrónico',
@@ -609,7 +610,7 @@
'MailerToLabel' => 'Para',
'MailerSubjectLabel' => 'Asunto',
'MailerBodyLabel' => 'Cuerpo del mensaje',
-
+
// Module: main
// - main/index
'MainPageHeading' => 'Panel de Control Flux',
@@ -624,11 +625,11 @@
'PageNotFoundInfo' => 'No se ha encontrado la página que buscas en nuestro servidor. Verifica que la dirección es correcta e inténtalo de nuevo.',
// - main/preprocess
'DisallowedDuringWoE' => 'No se puede acceder a la página que buscas en horario de WoE.',
-
+
// Module: monster
// - monster/index
// - monster/view
-
+
// Module: purchase
// - purchase/add
// - purchase/cart
@@ -637,12 +638,12 @@
// - purchase/index
// - purchase/pending
// - purchase/remove
-
+
// Module: ranking
// - ranking/character
// - ranking/guild
// - ranking/zeny
-
+
// Module: server
// - server/info
'ServerInfoTitle' => 'Información del Servidor',
@@ -664,20 +665,20 @@
'ServerStatusCharLabel' => 'Character Server',
'ServerStatusMapLabel' => 'Map Server',
'ServerStatusOnlineLabel' => 'Jugadores Conectados',
-
+
// Module: service
// - service/tos
'TermsTitle' => 'Términos del Servicio',
'TermsHeading' => 'Términos del Servicio',
'TermsInfo' => '¡Por favor, léelos atentamente antes de crearte una cuenta!',
'TermsInfo2' => "PARA EL ADMINISTRADOR DEL PANEL DE CONTROL: Puedes añadir los Términos del Servicio de tu servidor directamente en este archivo. Su localización es: %s",
-
+
// Module: unauthorized
// - unauthorized/index
'UnauthorizedTitle' => 'No estás autorizado',
'UnauthorizedHeading' => 'No estás autorizado',
'UnauthorizedInfo' => 'No estás autorizado para ver esta página. Redireccionando…',
-
+
// Module: woe
// - woe/index
'WoeTitle' => 'Horario de WoE',
diff --git a/lang/id_id.php b/lang/id_id.php
index 95b2966c0..e0d2a57d4 100644
--- a/lang/id_id.php
+++ b/lang/id_id.php
@@ -58,10 +58,10 @@
'ItemIdentifyLabel' => 'Teridentifikasi',
'ItemRefineLabel' => 'Tempa',
'ItemBrokenLabel' => 'Rusak',
- 'ItemCard0Label' => 'Kartu 0',
- 'ItemCard1Label' => 'Kartu 1',
- 'ItemCard2Label' => 'Kartu 2',
- 'ItemCard3Label' => 'Kartu 3',
+ 'ItemCard0Label' => 'Kartu 1',
+ 'ItemCard1Label' => 'Kartu 2',
+ 'ItemCard2Label' => 'Kartu 3',
+ 'ItemCard3Label' => 'Kartu 4',
//SIDEBAR
//FluxCP Menu Items
@@ -275,7 +275,6 @@
'ResetPassDisallowed' => 'Pemulihan kata sandi tidak dapat digunakan untuk akun ini.',
'ResetPassFailed' => 'Gagal untuk mengirim e-mail pemulihan akun.',
'ResetPassEmailSent' => 'E-mail berisi detail untuk menyetel ulang kata sandi sudah dikiriman.',
- 'ResetPassTitle' => 'Reset Kata Sandi',
'ResetPassInfo' => 'Jika Anda lupa kata sandi, Anda dapat menyetel ulang dengan cara memasukkan alamat e-mail yang digunakan ketika mendaftarkan akun.',
'ResetPassInfo2' => 'Alamat e-mail harus benar untuk melakukan pengiriman sebuah e-mail ke alamat yang dicantumkan yang berisi tautan untuk menyetel ulang kata sandi akun Anda.',
'ResetPassServerLabel' => 'Server Terdaftar',
@@ -578,10 +577,10 @@
'PickLogItemLabel' => 'Nama Barang',
'PickLogAmountLabel' => 'Jumlah',
'PickLogRefineLabel' => 'Tempa',
- 'PickLogCard0Label' => 'Kartu 0',
- 'PickLogCard1Label' => 'Kartu 1',
- 'PickLogCard2Label' => 'Kartu 2',
- 'PickLogCard3Label' => 'Kartu 3',
+ 'PickLogCard0Label' => 'Kartu 1',
+ 'PickLogCard1Label' => 'Kartu 2',
+ 'PickLogCard2Label' => 'Kartu 3',
+ 'PickLogCard3Label' => 'Kartu 4',
'PickLogMapLabel' => 'Map',
// - logdata/branch
'BranchLogTitle' => 'Daftar Branch',
@@ -739,7 +738,7 @@
// Module: contactform
'CFTitleSubmit' => 'Hubungi Kami',
-
+
// Module: News and Pages
'CMSNewsHeader' => 'Pengumuman',
'CMSPageHeader' => 'Content Management System',
diff --git a/lang/pt_br.php b/lang/pt_br.php
index fea759b7a..903cfcb72 100644
--- a/lang/pt_br.php
+++ b/lang/pt_br.php
@@ -1,5 +1,5 @@
'Portuguese',
'YesLabel' => 'Sim',
@@ -51,16 +51,16 @@
'ItemIdentifyLabel' => 'Identificado',
'ItemRefineLabel' => 'Refinado',
'ItemBrokenLabel' => 'Quebrado',
- 'ItemCard0Label' => 'Carta 0',
- 'ItemCard1Label' => 'Carta 1',
- 'ItemCard2Label' => 'Carta 2',
- 'ItemCard3Label' => 'Carta 3',
-
+ 'ItemCard0Label' => 'Carta 1',
+ 'ItemCard1Label' => 'Carta 2',
+ 'ItemCard2Label' => 'Carta 3',
+ 'ItemCard3Label' => 'Carta 4',
+
// Security
'SecuritySessionInvalid' => 'Desculpe, a sessão expirou, tente novamente.',
'SecurityNeedSession' => 'Desculpe, nenhuma sessão foi encontrada (tentativa de hack?)',
'SecurityNeedToken' => 'Desculpe, nenhum sinal encontrado para identificar esta forma (tentativa de hack?)',
-
+
// Module: account
// - account/changemail
'EmailChangeTitle' => 'Alterar E-mail',
@@ -144,6 +144,7 @@
'AccountSecurityLabel' => 'Código de Segurança',
'AccountCreateButton' => 'Criar Minha Conta',
'AccountInvalidChars' => "Um nome de usuário pode conter somente estes caracteres: ' %s'",
+ 'AccountRecaptchaKey' => 'Você precisa das chaves de Recaptcha, veja mais em config/applications.php (ReCaptchaPublicKey/ReCaptchaPrivateKey)',
'InvalidLoginServer' => 'Login inválido para servidor selecionado, por favor, tente novamente com um servidor válido.',
'InvalidLoginCredentials' => 'Login inválido credenciais, verifique se você digitou as informações corretas e tente novamente.',
'UnexpectedLoginError' => 'Ocorreu um erro inesperado, tente novamente ou reporte ao administrador.',
@@ -224,7 +225,6 @@
'ResetPassDisallowed' => 'Recuperação de senha não pode ser usada para esta conta.',
'ResetPassFailed' => 'Falha ao enviar o email de redefinição de senha.',
'ResetPassEmailSent' => 'Um e-mail foi enviado para você com os detalhes de como proceder para redefinir sua senha.',
- 'ResetPassTitle' => 'Redefinir Senha',
'ResetPassInfo' => 'Se você perder a sua senha, você pode redefiní-la digitando apenas o email que você cadastrou na sua conta.',
'ResetPassInfo2' => 'Uma mensagem será enviada ao email digitado contendo um link para você poder redefinir a sua senha, por isso é necessário que você possua um e-mail válido.',
'ResetPassServerLabel' => 'Servidor Registrado',
@@ -319,7 +319,7 @@
'XferLogCharNameLabel' => 'Para o Personagem',
'XferLogNotReceived' => 'Você não recebeu nenhuma transferência de crédito.',
'XferLogNotSent' => 'Você não fez nenhuma transferência de crédito.',
-
+
// Module: character
// - character/changeslot
// - character/index
@@ -349,20 +349,20 @@
'DivorceText3' => 'Anéis de casamento também serão excluídos.',
'DivorceButton' => 'Sim, fazê-lo por favor.',
'DivorceSuccessful' => '%s já se divorciou!',
-
+
// Module: cplog
// - cplog/index.php
// - cplog/login.php
// - cplog/paypal.php
// - cplog/resetpass.php
// - cplog/txnview.php
-
+
// Module: donate
// - donate/complete
// - donate/history
// - donate/index
// - donate/trusted
-
+
// Module: errors
// - errors/missing_action
'MissingActionTitle' => 'Ação Inexistente',
@@ -378,12 +378,12 @@
'MissingViewActLabel' => 'Ação:',
'MissingViewReqLabel' => 'URL requerida:',
'MissingViewLocLabel' => 'Localização do arquivo de sistema:',
-
+
// Module: guild
// - guild/export
// - guild/index
// - guild/view
-
+
// Module: history
// - history/cplogin
'HistoryCpLoginTitle' => 'Logins no Painel de Controle',
@@ -427,58 +427,7 @@
'HistoryPassResetResetDate' => 'Redefinir a data',
'HistoryPassResetResetIp' => 'Redefinir o IP',
'HistoryNoPassResets' => 'Nenhuma senha Redefinida encontradas.',
-
- // Module: ipban
- // - ipban/add
- 'IpbanAddTitle' => 'Add IP Ban',
- 'IpbanEnterIpPattern' => 'Please input an IP address or pattern.',
- 'IpbanInvalidPattern' => 'Invalid IP address or pattern.',
- 'IpbanWhitelistedPattern' => 'This pattern is whitelisted and cannot be blocked.',
- 'IpbanEnterReason' => 'Please enter a reason for the IP ban.',
- 'IpbanSelectUnbanDate' => 'Unban date is required.',
- 'IpbanFutureDate' => 'Unban date must be specified to a future date.',
- 'IpbanAlreadyBanned' => 'A matching IP (%s) has already been banned.',
- 'IpbanPatternBanned' => "The IP address/pattern '%s' has been banned.",
- 'IpbanAddFailed' => 'Failed to add IP ban.',
- 'IpbanAddHeading' => 'Add IP Ban',
- 'IpbanIpAddressLabel' => 'IP Address',
- 'IpbanReasonLabel' => 'Ban Reason',
- 'IpbanUnbanDateLabel' => 'Unban Date',
- 'IpbanIpAddressInfo' => 'You may specify a pattern such as 218.139.*.*',
- 'IpbanAddButton' => 'Add IP Ban',
- // - ipban/edit
- 'IpbanEditTitle' => 'Modify IP Ban',
- 'IpbanEnterEditReason' => 'Please enter a reason for the IP ban modification.',
- 'IpbanEditFailed' => 'Failed to modify IP ban.',
- 'IpbanEditHeading' => 'Modify IP Ban',
- 'IpbanEditReasonLabel' => 'Edit Reason',
- 'IpbanEditButton' => 'Modify IP Ban',
- // - ipban/index
- 'IpbanListTitle' => 'IP Ban List',
- 'IpbanListHeading' => 'IP Ban List',
- 'IpbanBannedIpLabel' => 'Banned IP',
- 'IpbanBanDateLabel' => 'Ban Date',
- 'IpbanBanReasonLabel' => 'Ban Reason',
- 'IpbanBanExpireLabel' => 'Ban Expiration Date',
- 'IpbanModifyLink' => 'Modify',
- 'IpbanRemoveLink' => 'Remove',
- 'IpbanUnbanButton' => 'Unban Selected',
- 'IpbanListNoBans' => 'There are currently no IP bans.',
- // - ipban/remove
- 'IpbanRemoveTitle' => 'Remove IP Ban',
- 'IpbanEnterRemoveReason' => 'Please enter a reason for the IP ban removal.',
- 'IpbanNotBanned' => 'No matching IP (%s) is currently banned.',
- 'IpbanPatternUnbanned' => "The IP address/pattern '%s' has been unbanned.",
- 'IpbanRemoveFailed' => 'Failed to remove IP ban.',
- 'IpbanRemoveHeading' => 'Remove IP Ban',
- 'IpbanRemoveReasonLabel' => 'Unban Reason',
- 'IpbanRemoveButton' => 'Remove IP Ban',
- // - ipban/unban
- 'IpbanNothingToUnban' => 'Nothing to unban.',
- 'IpbanEnterUnbanReason' => 'Please enter a reason for lifting the IP ban(s).',
- 'IpbanUnbanned' => 'Lifted selected IP ban(s)!',
- 'IpbanUnbanFailed' => 'Failed to lift %d of the specified IP unban(s)!',
-
+
// Module: ipban
// - ipban/add
'IpbanAddTitle' => 'Banir IP',
@@ -529,20 +478,20 @@
'IpbanEnterUnbanReason' => 'Por favor, digite uma razão para desbanir o(s) IP(s).',
'IpbanUnbanned' => 'IP(s) selecionado(s) desbanido(s)!',
'IpbanUnbanFailed' => 'Falha ao desbanir %d IP(s) especificado(s)!',
-
+
// Module: item
// - item/add
// - item/copy
// - item/edit
// - item/index
// - item/view
-
+
// Module: itemshop
// - itemshop/add
// - itemshop/delete
// - itemshop/edit
// - itemshop/imagedel
-
+
// Module: logdata
// - logdata/chat
// - logdata/command
@@ -582,7 +531,7 @@
'ZenyLogTypeLabel' => 'Tipo',
'ZenyLogAmountLabel' => 'Valor',
'ZenyLogMapLabel' => 'Mapa',
-
+
// Module: mail
// - mail/index
'MailerTitle' => 'Formulário de Email',
@@ -597,7 +546,7 @@
'MailerToLabel' => 'Para',
'MailerSubjectLabel' => 'Assunto',
'MailerBodyLabel' => 'Corpo da Mensagem',
-
+
// Module: main
// - main/index
'MainPageHeading' => 'Flux Control Panel',
@@ -612,11 +561,11 @@
'PageNotFoundInfo' => 'A página que você solicitou não foi encontrada. Por favor, verifique se o endereço está correto e tente novamente.',
// - main/preprocess
'DisallowedDuringWoE' => 'A página que você solicitou não está disponível durante a GdE.',
-
+
// Module: monster
// - monster/index
// - monster/view
-
+
// Module: purchase
// - purchase/add
// - purchase/cart
@@ -625,12 +574,12 @@
// - purchase/index
// - purchase/pending
// - purchase/remove
-
+
// Module: ranking
// - ranking/character
// - ranking/guild
// - ranking/zeny
-
+
// Module: server
// - server/info
'ServerInfoTitle' => 'Informação do Servidor',
@@ -653,20 +602,20 @@
'ServerStatusMapLabel' => 'Map Server',
'ServerStatusOnlineLabel' => 'Jogadores Online',
'ServerStatusPeakLabel' => 'Pico de jogador',
-
+
// Module: service
// - service/tos
'TermsTitle' => 'Termos de Serviço',
'TermsHeading' => 'Termos de Serviço',
'TermsInfo' => 'Por favor, leia tudo antes de criar a sua conta!',
'TermsInfo2' => "PARA O ADMINISTRADOR DO PAINEL DE CONTROLE: Você pode adicionar os Termos de Serviço diretamente neste arquivo. A localização do arquivo é: %s",
-
+
// Module: unauthorized
// - unauthorized/index
'UnauthorizedTitle' => 'Não Autorizado',
'UnauthorizedHeading' => 'Não Autorizado',
'UnauthorizedInfo' => 'Você não está autrizado a ver essa página. Redirecionando…',
-
+
// Module: woe
// - woe/index
'WoeTitle' => 'Horários da Guerra do Emperium',
@@ -676,7 +625,7 @@
'WoeServerLabel' => 'Servidores',
'WoeTimesLabel' => 'Horários da Guerra do Emperium',
'WoeNotScheduledInfo' => 'Não há nenhuma Guerra do Emperium agendada.',
-
+
// Module: tasks
'TaskListHeader' => 'Lista de tarefas',
'TaskListHeaderCompleted' => 'Tarefas concluídas',
@@ -688,9 +637,9 @@
'TLNoMine' => 'Você não tem tarefas atribuídas a você.',
'TLNoCompleted' => 'Não há tarefas concluídas ainda.',
'TLHeaderTasks' => 'Tarefas',
- 'TLHeaderOwner' => 'Atribuido à',
- 'TLHeaderPriority' => 'Prioridade',
- 'TLHeaderStatus' => 'Estado',
+ 'TLHeaderOwner' => 'Atribuido à',
+ 'TLHeaderPriority' => 'Prioridade',
+ 'TLHeaderStatus' => 'Estado',
'TLHeaderCreated' => 'Criado',
'TLHeaderModified' => 'Modificado',
'TLHeaderResources' => 'Informações',
@@ -703,7 +652,7 @@
'TLStatus2' => 'Aguardando Implementação',
'TLStatus5' => 'completo',
'TLHuh' => 'Você não deve ser capaz de ver isso!',
-
+
// Module: contactform
'CFTitleSubmit' => 'Contate-nos',
@@ -716,14 +665,7 @@
'HARAccountID' => 'ID da conta',
'HARNoData' => 'Nenhum dado foi encontrado.',
'HARGoback' => 'Voltar',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
- 'HARTitle' => 'Harmony Logs',
-
+
// Module: News and Pages
'XCMSNewsHeader' => 'Announcements',
'XCMSPageHeader' => 'Content Management System',
@@ -736,7 +678,7 @@
'XCMSNewsAdded' => 'News added to system',
'XCMSPagesAdded' => 'Your new page has been added',
'XCMSNewsUpdated' => 'News updated',
- 'XCMSPageUpdated' => 'Your page has been updated',
+ 'XCMSPageUpdated' => 'Your page has been updated',
'XCMSNewsAddTitle' => 'Add a news item',
'XCMSPageAddTitle' => 'Add a new page',
'XCMSNewsEditTitle' => 'Edit news',
@@ -767,19 +709,7 @@
'XCMSPageCreate' => 'Create now?',
'XCMSOptionalLabel' => '(Optional)',
'XCMSRequiredLabel' => '(Required)',
-
-
- // Module: vending
- 'TLHeaderTasks' => 'Tasks',
- 'TLHeaderOwner' => 'Owner',
- 'TLHeaderPriority' => 'Priority',
- 'TLHeaderStatus' => 'Status',
- 'TLHeaderCreated' => 'Created',
- 'TLHeaderModified' => 'Modified',
- 'TLHeaderResources' => 'Additional Resources',
- 'TLHeaderBody' => 'Body',
-
// Module: servicedesk
'SDHeader' => 'Serviço de tickets',
'SDCreateNew' => 'Criar um novo ticket',
@@ -791,18 +721,18 @@
'SDNoInactiveTickets' => 'Não existem tickets inativos.',
'SDNoClosedTickets' => 'Não existem tickets fechados.',
'SDNoCats' => 'Não existem categorias.',
- 'SDHuh' => 'Você não deveria estar aqui o.O',
+ 'SDHuh' => 'Você não deveria estar aqui o.O',
'SDPointerChatLog' => 'Nós recomendamos que você cole o log aqui pastebin.com e nos envie o erro.',
'SDPointerScreenShot' => 'Nos envie links de imagens para serem utilizados como provas',
'SDPointerVideoLink' => 'Recomendamos que envie para o youtube e coloque o link aqui',
- 'SDHeaderID' => 'Ticket #',
- 'SDHeaderSubject' => 'Resposta',
+ 'SDHeaderID' => 'Ticket #',
+ 'SDHeaderSubject' => 'Resposta',
'SDHeaderCategory' => 'Categoria',
- 'SDHeaderStatus' => 'Status atual',
+ 'SDHeaderStatus' => 'Status atual',
'SDHeaderLastAuthor' => 'Última resposta',
- 'SDHeaderTimestamp' => 'Criado',
- 'SDHeaderAccount' => 'Conta',
- 'SDHeaderTeam' => 'Equipe',
+ 'SDHeaderTimestamp' => 'Criado',
+ 'SDHeaderAccount' => 'Conta',
+ 'SDHeaderTeam' => 'Equipe',
'SDH3ActiveTickets' => 'Tickets ativos',
'SDH3InActiveTickets' => 'Tickets inativos',
'SDH3ClosedTickets' => 'Tickets fechados',
@@ -969,6 +899,6 @@
'CMSRequiredLabel' => '(Required)',
'CMSCreateLabel' => 'Add News',
'SDRespTable7' => 'Resolve Ticket and Credit Account',
-
+
);
?>
diff --git a/lib/Flux.php b/lib/Flux.php
index 8d91dcb46..911f94d9e 100644
--- a/lib/Flux.php
+++ b/lib/Flux.php
@@ -24,12 +24,12 @@ class Flux {
* Current version.
*/
const VERSION = '2.0.0';
-
+
/**
* Repository SVN version or GIT hash of the top-level revision.
*/
const REPOSVERSION = FLUX_REPOSVERSION;
-
+
/**
* Application-specific configuration object.
*
@@ -37,7 +37,7 @@ class Flux {
* @var Flux_Config
*/
public static $appConfig;
-
+
/**
* Servers configuration object.
*
@@ -45,7 +45,7 @@ class Flux {
* @var Flux_Config
*/
public static $serversConfig;
-
+
/**
* Messages configuration object.
*
@@ -53,7 +53,7 @@ class Flux {
* @var Flux_Config
*/
public static $messagesConfig;
-
+
/**
* Collection of Flux_Athena objects.
*
@@ -61,7 +61,7 @@ class Flux {
* @var array
*/
public static $servers = array();
-
+
/**
* Registry where Flux_LoginAthenaGroup instances are kept for easy
* searching.
@@ -70,7 +70,7 @@ class Flux {
* @var array
*/
public static $loginAthenaGroupRegistry = array();
-
+
/**
* Registry where Flux_Athena instances are kept for easy searching.
*
@@ -78,7 +78,7 @@ class Flux {
* @var array
*/
public static $athenaServerRegistry = array();
-
+
/**
* Object containing all of Flux's session data.
*
@@ -86,17 +86,17 @@ class Flux {
* @var Flux_SessionData
*/
public static $sessionData;
-
+
/**
*
*/
public static $numberOfQueries = 0;
-
+
/**
*
*/
public static $addons = array();
-
+
/**
* Initialize Flux application. This will handle configuration parsing and
* instanciating of objects crucial to the control panel.
@@ -113,23 +113,34 @@ public static function initialize($options = array())
self::raise("Missing required option `$option' in Flux::initialize()");
}
}
-
+
// Parse application and server configuration files, this will also
// handle configuration file normalization. See the source for the
// below methods for more details on what's being done.
self::$appConfig = self::parseAppConfigFile($options['appConfigFile']);
self::$serversConfig = self::parseServersConfigFile($options['serversConfigFile']);
-
+
+ if (array_key_exists('appConfigFileImport', $options) && file_exists($options['appConfigFileImport'])) {
+ $importAppConfig = self::parseAppConfigFile($options['appConfigFileImport'], true);
+ self::$appConfig->merge($importAppConfig, true, true);
+ }
+
+ // Server configuration files are not merged, instead they replace the original.
+ if (array_key_exists('serversConfigFileImport', $options) && file_exists($options['serversConfigFileImport'])) {
+ $importServersConfig = self::parseServersConfigFile($options['serversConfigFileImport'], true);
+ self::$serversConfig = $importServersConfig;
+ }
+
// Using newer language system.
self::$messagesConfig = self::parseLanguageConfigFile();
-
+
// Initialize server objects.
self::initializeServerObjects();
-
+
// Initialize add-ons.
self::initializeAddons();
}
-
+
/**
* Initialize each Login/Char/Map server object and contain them in their
* own collective Athena object.
@@ -141,30 +152,30 @@ public static function initialize($options = array())
public static function initializeServerObjects()
{
foreach (self::$serversConfig->getChildrenConfigs() as $key => $config) {
- $connection = new Flux_Connection($config->getDbConfig(), $config->getLogsDbConfig());
+ $connection = new Flux_Connection($config->getDbConfig(), $config->getLogsDbConfig(), $config->getWebDbConfig());
$loginServer = new Flux_LoginServer($config->getLoginServer());
-
+
// LoginAthenaGroup maintains the grouping of a central login
// server and its underlying Athena objects.
self::$servers[$key] = new Flux_LoginAthenaGroup($config->getServerName(), $connection, $loginServer);
-
+
// Add into registry.
self::registerServerGroup($config->getServerName(), self::$servers[$key]);
-
+
foreach ($config->getCharMapServers()->getChildrenConfigs() as $charMapServer) {
$charServer = new Flux_CharServer($charMapServer->getCharServer());
$mapServer = new Flux_MapServer($charMapServer->getMapServer());
-
+
// Create the collective server object, Flux_Athena.
$athena = new Flux_Athena($charMapServer, $loginServer, $charServer, $mapServer);
self::$servers[$key]->addAthenaServer($athena);
-
+
// Add into registry.
self::registerAthenaServer($config->getServerName(), $charMapServer->getServerName(), $athena);
}
}
}
-
+
/**
*
*/
@@ -173,26 +184,26 @@ public static function initializeAddons()
if (!is_dir(FLUX_ADDON_DIR)) {
return false;
}
-
+
foreach (glob(FLUX_ADDON_DIR.'/*') as $addonDir) {
if (is_dir($addonDir)) {
$addonName = basename($addonDir);
$addonObject = new Flux_Addon($addonName, $addonDir);
self::$addons[$addonName] = $addonObject;
-
+
// Merge configurations.
self::$appConfig->merge($addonObject->addonConfig);
self::$messagesConfig->merge($addonObject->messagesConfig, false);
}
}
}
-
+
/**
* Wrapper method for setting and getting values from the appConfig.
*
* @param string $key
* @param mixed $value
- * @param arary $options
+ * @param array $options
* @access public
*/
public static function config($key, $value = null, $options = array())
@@ -204,13 +215,13 @@ public static function config($key, $value = null, $options = array())
return self::$appConfig->get($key);
}
}
-
+
/**
* Wrapper method for setting and getting values from the messagesConfig.
*
* @param string $key
* @param mixed $value
- * @param arary $options
+ * @param array $options
* @access public
*/
public static function message($key, $value = null, $options = array())
@@ -218,12 +229,12 @@ public static function message($key, $value = null, $options = array())
if (!is_null($value)) {
return self::$messagesConfig->set($key, $value, $options);
}
- if (!is_null($tmp=self::$messagesConfig->get($key)))
+ if (!is_null($tmp=self::$messagesConfig->get($key)))
return $tmp;
else
return ' '.$key;
}
-
+
/**
* Convenience method for raising Flux_Error exceptions.
*
@@ -246,7 +257,7 @@ public static function parseConfig(array $configArr)
{
return new Flux_Config($configArr);
}
-
+
/**
* Parse a PHP array returned as the result of an included file into a
* Flux_Config configuration object.
@@ -258,16 +269,18 @@ public static function parseConfigFile($filename, $cache=true)
{
$basename = basename(str_replace(' ', '', ucwords(str_replace(array('/', '\\', '_'), ' ', $filename))), '.php').'.cache.php';
$cachefile = FLUX_DATA_DIR."/tmp/$basename";
-
+ $directory = FLUX_DATA_DIR.'/tmp';
+ if (!is_dir($directory))
+ mkdir($directory, 0600);
if ($cache && file_exists($cachefile) && filemtime($cachefile) > filemtime($filename)) {
- return unserialize(file_get_contents($cachefile, null, null, 28));
+ return unserialize(file_get_contents($cachefile, false, null, 28));
}
else {
ob_start();
// Uses require, thus assumes the file returns an array.
$config = require $filename;
ob_end_clean();
-
+
// Cache config file.
$cf = self::parseConfig($config);
@@ -280,101 +293,110 @@ public static function parseConfigFile($filename, $cache=true)
fwrite($fp, $s=serialize($cf), strlen($s));
fclose($fp);
}
-
+
return $cf;
}
}
-
+
/**
* Parse a file in an application-config specific manner.
*
* @param string $filename
+ * @param bool $import Whether this is an import config or not
* @access public
*/
- public static function parseAppConfigFile($filename)
+ public static function parseAppConfigFile($filename, $import = false)
{
$config = self::parseConfigFile($filename, false);
-
- if (!$config->getServerAddress()) {
+
+ if (!$config->getServerAddress() && !$import) {
self::raise("ServerAddress must be specified in your application config.");
}
- if (count($themes = $config->get('ThemeName', false)) < 1) {
+ $themes = $config->get('ThemeName', false);
+ if ((!$themes || count($themes) < 1) && !$import) {
self::raise('ThemeName is required in application configuration.');
}
- else {
+ if ($themes) {
foreach ($themes as $themeName) {
if (!self::themeExists($themeName)) {
self::raise("The selected theme '$themeName' does not exist.");
}
- } }
- if (!($config->getPayPalReceiverEmails() instanceOf Flux_Config)) {
+ }
+ }
+ if (!($config->getPayPalReceiverEmails() instanceof Flux_Config)
+ && !($import && $config->getPayPalReceiverEmails() === null)) {
self::raise("PayPalReceiverEmails must be an array.");
}
-
+
// Sanitize BaseURI. (leading forward slash is mandatory.)
$baseURI = $config->get('BaseURI');
- if (strlen($baseURI) && $baseURI[0] != '/') {
- $config->set('BaseURI', "/$baseURI");
- }
- elseif (trim($baseURI) === '') {
- $config->set('BaseURI', '/');
+ if (!is_null($baseURI)) {
+ if (strlen($baseURI) && $baseURI[0] != '/') {
+ $config->set('BaseURI', "/$baseURI");
+ }
+ elseif (trim($baseURI) === '') {
+ $config->set('BaseURI', '/');
+ }
}
-
+
return $config;
}
-
+
/**
* Parse a file in a servers-config specific manner. This method gets a bit
* nasty so beware of ugly code ;)
*
* @param string $filename
+ * @param bool $import Whether this is an import config or not
* @access public
*/
- public static function parseServersConfigFile($filename)
+ public static function parseServersConfigFile($filename, $import = false)
{
$config = self::parseConfigFile($filename);
$options = array('overwrite' => false, 'force' => true); // Config::set() options.
$serverNames = array();
$athenaServerNames = array();
-
- if (!count($config->toArray())) {
+
+ if (!count($config->toArray()) && !$import) {
self::raise('At least one server configuration must be present.');
}
-
+
foreach ($config->getChildrenConfigs() as $topConfig) {
//
// Top-level normalization.
//
-
+
if (!($serverName = $topConfig->getServerName())) {
self::raise('ServerName is required for each top-level server configuration, check your servers configuration file.');
}
elseif (in_array($serverName, $serverNames)) {
self::raise("The server name '$serverName' has already been configured. Please use another name.");
}
-
+
$serverNames[] = $serverName;
$athenaServerNames[$serverName] = array();
-
+
$topConfig->setDbConfig(array(), $options);
$topConfig->setLogsDbConfig(array(), $options);
+ $topConfig->setWebDbConfig(array(), $options);
$topConfig->setLoginServer(array(), $options);
$topConfig->setCharMapServers(array(), $options);
-
+
$dbConfig = $topConfig->getDbConfig();
$logsDbConfig = $topConfig->getLogsDbConfig();
+ $webDbConfig = $topConfig->getWebDbConfig();
$loginServer = $topConfig->getLoginServer();
-
- foreach (array($dbConfig, $logsDbConfig) as $_dbConfig) {
+
+ foreach (array($dbConfig, $logsDbConfig, $webDbConfig) as $_dbConfig) {
$_dbConfig->setHostname('localhost', $options);
$_dbConfig->setUsername('ragnarok', $options);
$_dbConfig->setPassword('ragnarok', $options);
$_dbConfig->setPersistent(true, $options);
}
-
+
$loginServer->setDatabase($dbConfig->getDatabase(), $options);
$loginServer->setUseMD5(true, $options);
-
+
// Raise error if missing essential configuration directives.
if (!$loginServer->getAddress()) {
self::raise('Address is required for each LoginServer section in your servers configuration.');
@@ -382,11 +404,11 @@ public static function parseServersConfigFile($filename)
elseif (!$loginServer->getPort()) {
self::raise('Port is required for each LoginServer section in your servers configuration.');
}
-
+
if (!$topConfig->getCharMapServers() || !count($topConfig->getCharMapServers()->toArray())) {
self::raise('CharMapServers must be an array and contain at least 1 char/map server entry.');
}
-
+
foreach ($topConfig->getCharMapServers()->getChildrenConfigs() as $charMapServer) {
//
// Char/Map normalization.
@@ -397,42 +419,61 @@ public static function parseServersConfigFile($filename)
'Mvp' => 100
);
$dropRates = array(
+ 'DropRateCap' => 9000,
'Common' => 100,
'CommonBoss' => 100,
+ 'CommonMVP' => 100,
+ 'CommonMin' => 1,
+ 'CommonMax' => 10000,
'Heal' => 100,
'HealBoss' => 100,
+ 'HealMVP' => 100,
+ 'HealMin' => 1,
+ 'HealMax' => 10000,
'Useable' => 100,
'UseableBoss' => 100,
+ 'UseableMVP' => 100,
+ 'UseableMin' => 1,
+ 'UseableMax' => 10000,
'Equip' => 100,
'EquipBoss' => 100,
+ 'EquipMVP' => 100,
+ 'EquipMin' => 1,
+ 'EquipMax' => 10000,
'Card' => 100,
'CardBoss' => 100,
- 'MvpItem' => 100
+ 'CardMVP' => 100,
+ 'CardMin' => 1,
+ 'CardMax' => 10000,
+ 'MvpItem' => 100,
+ 'MvpItemMin' => 1,
+ 'MvpItemMax' => 10000,
+ 'MvpItemMode' => 0
);
$charMapServer->setExpRates($expRates, $options);
$charMapServer->setDropRates($dropRates, $options);
$charMapServer->setRenewal(true, $options);
$charMapServer->setCharServer(array(), $options);
$charMapServer->setMapServer(array(), $options);
- $charMapServer->setDatabase($dbConfig->getDatabase(), $options);
-
+ $charMapServer->setDatabase($dbConfig->getDatabase(), $options);
+
if (!($athenaServerName = $charMapServer->getServerName())) {
self::raise('ServerName is required for each CharMapServers pair in your servers configuration.');
}
elseif (in_array($athenaServerName, $athenaServerNames[$serverName])) {
self::raise("The server name '$athenaServerName' under '$serverName' has already been configured. Please use another name.");
}
-
+
$athenaServerNames[$serverName][] = $athenaServerName;
$charServer = $charMapServer->getCharServer();
-
+
if (!$charServer->getAddress()) {
self::raise('Address is required for each CharServer section in your servers configuration.');
}
elseif (!$charServer->getPort()) {
self::raise('Port is required for each CharServer section in your servers configuration.');
}
-
+
$mapServer = $charMapServer->getMapServer();
if (!$mapServer->getAddress()) {
self::raise('Address is required for each MapServer section in your servers configuration.');
@@ -442,10 +483,10 @@ public static function parseServersConfigFile($filename)
}
}
}
-
+
return $config;
}
-
+
/**
* Parses a messages configuration file. (Deprecated)
*
@@ -458,7 +499,7 @@ public static function parseMessagesConfigFile($filename)
// Nothing yet.
return $config;
}
-
+
/**
* Parses a language configuration file, can also parse a language config
* for any addon.
@@ -470,7 +511,7 @@ public static function parseLanguageConfigFile($addonName=null)
{
$default = $addonName ? FLUX_ADDON_DIR."/$addonName/lang/en_us.php" : FLUX_LANG_DIR.'/en_us.php';
$current = $default;
-
+
if ($lang=self::config('DefaultLanguage')) {
$current = $addonName ? FLUX_ADDON_DIR."/$addonName/lang/$lang.php" : FLUX_LANG_DIR."/$lang.php";
}
@@ -490,15 +531,15 @@ public static function parseLanguageConfigFile($addonName=null)
$tmp = array();
$def = new Flux_Config($tmp);
}
-
+
if ($current != $default && file_exists($current)) {
$cur = self::parseConfigFile($current);
$def->merge($cur, false);
}
-
+
return $def;
}
-
+
/**
* Check whether or not a theme exists.
*
@@ -509,7 +550,7 @@ public static function themeExists($themeName)
{
return is_dir(FLUX_THEME_DIR."/$themeName");
}
-
+
/**
* Register the server group into the registry.
*
@@ -523,7 +564,7 @@ private static function registerServerGroup($serverName, Flux_LoginAthenaGroup $
self::$loginAthenaGroupRegistry[$serverName] = $serverGroup;
return $serverGroup;
}
-
+
/**
* Register the Athena server into the registry.
*
@@ -538,11 +579,11 @@ private static function registerAthenaServer($serverName, $athenaServerName, Flu
if (!array_key_exists($serverName, self::$athenaServerRegistry) || !is_array(self::$athenaServerRegistry[$serverName])) {
self::$athenaServerRegistry[$serverName] = array();
}
-
+
self::$athenaServerRegistry[$serverName][$athenaServerName] = $athenaServer;
return $athenaServer;
}
-
+
/**
* Get Flux_LoginAthenaGroup server object by its ServerName.
*
@@ -553,7 +594,7 @@ private static function registerAthenaServer($serverName, $athenaServerName, Flu
public static function getServerGroupByName($serverName)
{
$registry = &self::$loginAthenaGroupRegistry;
-
+
if (array_key_exists($serverName, $registry) && $registry[$serverName] instanceOf Flux_LoginAthenaGroup) {
return $registry[$serverName];
}
@@ -561,7 +602,7 @@ public static function getServerGroupByName($serverName)
return false;
}
}
-
+
/**
* Get Flux_Athena instance by its group/server names.
*
@@ -575,14 +616,14 @@ public static function getAthenaServerByName($serverName, $athenaServerName)
$registry = &self::$athenaServerRegistry;
if (array_key_exists($serverName, $registry) && array_key_exists($athenaServerName, $registry[$serverName]) &&
$registry[$serverName][$athenaServerName] instanceOf Flux_Athena) {
-
+
return $registry[$serverName][$athenaServerName];
}
else {
return false;
}
}
-
+
/**
* Hashes a password for use in comparison with the login.user_pass column.
*
@@ -595,7 +636,7 @@ public static function hashPassword($password)
// Default hashing schema is MD5.
return md5($password);
}
-
+
/**
* Get the job class name from a job ID.
*
@@ -607,7 +648,7 @@ public static function getJobClass($id)
{
$key = "JobClasses.$id";
$class = self::config($key);
-
+
if ($class) {
return $class;
}
@@ -615,7 +656,7 @@ public static function getJobClass($id)
return false;
}
}
-
+
/**
* Get the job ID from a job class name.
*
@@ -633,7 +674,7 @@ public static function getJobID($class)
return false;
}
}
-
+
/**
* Get the homunculus class name from a homun class ID.
*
@@ -645,7 +686,7 @@ public static function getHomunClass($id)
{
$key = "HomunClasses.$id";
$class = self::config($key);
-
+
if ($class) {
return $class;
}
@@ -657,36 +698,52 @@ public static function getHomunClass($id)
/**
* Get the item type name from an item type.
*
- * @param int $id
- * @param int $id2
- * @return mixed Item Type or false.
+ * @return Item Type or false.
* @access public
*/
- public static function getItemType($id, $id2)
- {
- $key = "ItemTypes.$id";
- $type = self::config($key);
-
- if ($id2) {
- $key = "ItemTypes2.$id.$id2";
- $type2 = self::config($key);
-
- if ($type && $type2) {
- $type .= ' - ' . $type2;
- }
- else if ($type2) {
- $type = $type2;
- }
+ public static function getItemType($id1)
+ {
+ if (is_null($id1))
+ return false;
+
+ $type = self::config("ItemTypes")->toArray();
+
+ if ($type[strtolower($id1)] != NULL) {
+ return $type[strtolower($id1)];
+ }
+ else {
+ return false;
+ }
+ }
+ public static function getItemSubType($id1, $id2)
+ {
+ $subtype = "ItemSubTypes.$id1.$id2";
+ $result = self::config($subtype);
+
+ if ($result) {
+ return $result;
+ }
+ else {
+ return false;
}
-
- if ($type) {
- return $type;
+ }
+
+ /**
+ * return random option description.
+ */
+ public static function getRandOption($id1)
+ {
+ $key = "RandomOptions.$id1";
+ $option = self::config($key);
+
+ if ($option) {
+ return $option;
}
else {
return false;
}
}
-
+
/**
* Get the equip location combination name from an equip location combination type.
*
@@ -694,19 +751,12 @@ public static function getItemType($id, $id2)
* @return mixed Equip Location Combination or false.
* @access public
*/
- public static function getEquipLocationCombination($id)
+ public static function getEquipLocationCombination()
{
- $key = "EquipLocationCombinations.$id";
- $combination = self::config($key);
-
- if ($combination) {
- return $combination;
- }
- else {
- return false;
- }
+ $equiplocations = Flux::config('EquipLocationCombinations')->toArray();
+ return $equiplocations;
}
-
+
/**
* Process donations that have been put on hold.
*/
@@ -716,19 +766,19 @@ public static function processHeldCredits()
$trustTable = self::config('FluxTables.DonationTrustTable');
$loginAthenaGroups = self::$loginAthenaGroupRegistry;
list ($cancel, $accept) = array(array(), array());
-
+
foreach ($loginAthenaGroups as $loginAthenaGroup) {
$sql = "SELECT account_id, payer_email, credits, mc_gross, txn_id, hold_until ";
$sql .= "FROM {$loginAthenaGroup->loginDatabase}.$txnLogTable ";
$sql .= "WHERE account_id > 0 AND hold_until IS NOT NULL AND payment_status = 'Completed'";
$sth = $loginAthenaGroup->connection->getStatement($sql);
-
+
if ($sth->execute() && ($txn=$sth->fetchAll())) {
foreach ($txn as $t) {
$sql = "SELECT id FROM {$loginAthenaGroup->loginDatabase}.$txnLogTable ";
$sql .= "WHERE payment_status IN ('Cancelled_Reversed', 'Reversed', 'Refunded') AND parent_txn_id = ? LIMIT 1";
$sth = $loginAthenaGroup->connection->getStatement($sql);
-
+
if ($sth->execute(array($t->txn_id)) && ($r=$sth->fetch()) && $r->id) {
$cancel[] = $t->txn_id;
}
@@ -737,7 +787,7 @@ public static function processHeldCredits()
}
}
}
-
+
if (!empty($cancel)) {
$ids = implode(', ', array_fill(0, count($cancel), '?'));
$sql = "UPDATE {$loginAthenaGroup->loginDatabase}.$txnLogTable ";
@@ -745,29 +795,29 @@ public static function processHeldCredits()
$sth = $loginAthenaGroup->connection->getStatement($sql);
$sth->execute($cancel);
}
-
+
$sql2 = "INSERT INTO {$loginAthenaGroup->loginDatabase}.$trustTable (account_id, email, create_date)";
$sql2 .= "VALUES (?, ?, NOW())";
$sth2 = $loginAthenaGroup->connection->getStatement($sql2);
-
+
$sql3 = "SELECT id FROM {$loginAthenaGroup->loginDatabase}.$trustTable WHERE ";
$sql3 .= "delete_date IS NULL AND account_id = ? AND email = ? LIMIT 1";
$sth3 = $loginAthenaGroup->connection->getStatement($sql3);
-
+
$idvals = array();
-
+
foreach ($accept as $txn) {
$loginAthenaGroup->loginServer->depositCredits($txn->account_id, $txn->credits, $txn->mc_gross);
$sth3->execute(array($txn->account_id, $txn->payer_email));
$row = $sth3->fetch();
-
+
if (!$row) {
$sth2->execute(array($txn->account_id, $txn->payer_email));
}
-
+
$idvals[] = $txn->txn_id;
}
-
+
if (!empty($idvals)) {
$ids = implode(', ', array_fill(0, count($idvals), '?'));
$sql = "UPDATE {$loginAthenaGroup->loginDatabase}.$txnLogTable ";
@@ -778,25 +828,25 @@ public static function processHeldCredits()
}
}
}
-
+
/**
*
*/
public static function pruneUnconfirmedAccounts()
{
$tbl = Flux::config('FluxTables.AccountCreateTable');
-
+
foreach (self::$loginAthenaGroupRegistry as $loginAthenaGroup) {
$db = $loginAthenaGroup->loginDatabase;
$sql = "DELETE $db.login, $db.$tbl FROM $db.login INNER JOIN $db.$tbl ";
$sql .= "WHERE login.account_id = $tbl.account_id AND $tbl.confirmed = 0 ";
$sql .= "AND $tbl.confirm_code IS NOT NULL AND $tbl.confirm_expire <= NOW()";
$sth = $loginAthenaGroup->connection->getStatement($sql);
-
+
$sth->execute();
}
}
-
+
/**
* Get array of equip_location bits. (bit => loc_name pairs)
* @return array
@@ -806,26 +856,52 @@ public static function getEquipLocationList()
$equiplocations = Flux::config('EquipLocations')->toArray();
return $equiplocations;
}
-
+
/**
* Get array of equip_upper bits. (bit => upper_name pairs)
* @return array
*/
- public static function getEquipUpperList()
+ public static function getEquipUpperList($isRenewal = 1)
{
- $equipupper = Flux::config('EquipUpper')->toArray();
+ $equipupper = Flux::config('EquipUpper.0')->toArray();
+
+ if($isRenewal)
+ $equipupper = array_merge($equipupper, Flux::config('EquipUpper.1')->toArray());
+
return $equipupper;
}
-
+
/**
* Get array of equip_jobs bits. (bit => job_name pairs)
*/
- public static function getEquipJobsList()
+ public static function getEquipJobsList($isRenewal = 1)
{
- $equipjobs = Flux::config('EquipJobs')->toArray();
+ $equipjobs = Flux::config('EquipJobs.0')->toArray();
+
+ if($isRenewal)
+ $equipjobs = array_merge($equipjobs, Flux::config('EquipJobs.1')->toArray());
+
return $equipjobs;
}
-
+
+ /**
+ * Get array of trade restrictions
+ */
+ public static function getTradeRestrictionList()
+ {
+ $restrictions = Flux::config('TradeRestriction')->toArray();
+ return $restrictions;
+ }
+
+ /**
+ * Get array of item flags
+ */
+ public static function getItemFlagList()
+ {
+ $flags = Flux::config('ItemFlags')->toArray();
+ return $flags;
+ }
+
/**
* Check whether a particular item type is stackable.
* @param int $type
@@ -836,47 +912,27 @@ public static function isStackableItemType($type)
$nonstackables = array(1, 4, 5, 7, 8, 9);
return !in_array($type, $nonstackables);
}
-
- /**
- * Perform a bitwise AND from each bit in getEquipLocationList() on $bitmask
- * to determine which bits have been set.
- * @param int $bitmask
- * @return array
- */
- public static function equipLocationsToArray($bitmask)
- {
- $arr = array();
- $bits = self::getEquipLocationList();
-
- foreach ($bits as $bit => $name) {
- if ($bitmask & $bit) {
- $arr[] = $bit;
- }
- }
-
- return $arr;
- }
-
+
/**
* Perform a bitwise AND from each bit in getEquipUpperList() on $bitmask
* to determine which bits have been set.
* @param int $bitmask
* @return array
*/
- public static function equipUpperToArray($bitmask)
+ public static function equipUpperToArray($bitmask, $isRenewal = 1)
{
$arr = array();
- $bits = self::getEquipUpperList();
-
+ $bits = self::getEquipUpperList($isRenewal);
+
foreach ($bits as $bit => $name) {
if ($bitmask & $bit) {
$arr[] = $bit;
}
}
-
+
return $arr;
}
-
+
/**
* Perform a bitwise AND from each bit in getEquipJobsList() on $bitmask
* to determine which bits have been set.
@@ -887,16 +943,16 @@ public static function equipJobsToArray($bitmask)
{
$arr = array();
$bits = self::getEquipJobsList();
-
+
foreach ($bits as $bit => $name) {
if ($bitmask & $bit) {
$arr[] = $bit;
}
}
-
+
return $arr;
}
-
+
/**
*
*/
@@ -904,43 +960,39 @@ public static function monsterModeToArray($bitmask)
{
$arr = array();
$bits = self::config('MonsterModes')->toArray();
-
- foreach ($bits as $bit => $name) {
- if ($bitmask & $bit) {
- $arr[] = $bit;
- }
+
+ foreach ($bits as $name) {
+ $arr[] = $name;
}
-
+
return $arr;
}
-
+
/**
*
*/
public static function elementName($ele)
{
- $neutral = Flux::config('Elements.0');
- $element = Flux::config("Elements.$ele");
-
- return is_null($element) ? $neutral : $element;
+ $element = Flux::config("Elements")->toArray();
+ return is_null($element[$ele]) ? $element['Neutral'] : $element[$ele];
}
-
+
/**
*
*/
public static function monsterRaceName($race)
{
- $race = Flux::config("MonsterRaces.$race");
- return $race;
+ $races = Flux::config("MonsterRaces")->toArray();
+ return is_null($races[$race]) ? $races['Formless'] : $races[$race];
}
-
+
/**
*
*/
public static function monsterSizeName($size)
{
- $size = Flux::config("MonsterSizes.$size");
- return $size;
+ $sizes = Flux::config("MonsterSizes")->toArray();
+ return is_null($sizes[$size]) ? $sizes['Small'] : $sizes[$size];
}
public static function getAvailableLanguages()
diff --git a/lib/Flux/Athena.php b/lib/Flux/Athena.php
index 0819775c8..e45670368 100644
--- a/lib/Flux/Athena.php
+++ b/lib/Flux/Athena.php
@@ -58,6 +58,14 @@ class Flux_Athena {
*/
public $logsDatabase;
+ /**
+ * Web server database. (is not set until setConnection() is called.)
+ *
+ * @access public
+ * @var string
+ */
+ public $webDatabase;
+
/**
* Database used for the char/map (aka everything else) SQL operations.
* This does not include log-related tasks.
@@ -249,6 +257,7 @@ public function setConnection(Flux_Connection $connection)
{
$this->connection = $connection;
$this->logsDatabase = $connection->logsDbConfig->getDatabase();
+ $this->webDatabase = $connection->webDbConfig->getDatabase();
return $connection;
}
@@ -654,7 +663,7 @@ public function resetLook($charID)
$sql = "UPDATE {$this->charMapDatabase}.`char` SET ";
$sql .= "hair = 1, hair_color = 0, clothes_color = 0, weapon = 0, shield = 0, ";
- $sql .= "head_top = 0, head_mid = 0, head_bottom = 0 ";
+ $sql .= "head_top = 0, head_mid = 0, head_bottom = 0, body = 0 ";
$sql .= "WHERE char_id = ?";
$sth = $this->connection->getStatement($sql);
diff --git a/lib/Flux/Captcha.php b/lib/Flux/Captcha.php
index 59d9bf08d..e243f20a1 100644
--- a/lib/Flux/Captcha.php
+++ b/lib/Flux/Captcha.php
@@ -37,7 +37,7 @@ public function __construct($options = array())
'chars' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWWXYZ0123456789',
'length' => 5,
'background' => FLUX_DATA_DIR.'/captcha/background.png',
- 'fontPath' => FLUX_DATA_DIR.'/captcha/fonts',
+ 'fontPath' => realpath(FLUX_DATA_DIR.'/captcha/fonts'),
'fontName' => 'default.ttf',
'fontSize' => 28,
'yPosition' => 40,
diff --git a/lib/Flux/CashShop.php b/lib/Flux/CashShop.php
index 4396adf5b..abfbe842b 100644
--- a/lib/Flux/CashShop.php
+++ b/lib/Flux/CashShop.php
@@ -87,7 +87,7 @@ public function getItem($shopItemID) {
$temp = new Flux_TemporaryTable($this->server->connection, "$db.items", $fromTables);
$shop = 'item_cash_db';
$col = "$shop.item_id AS shop_item_id, $shop.tab AS shop_item_tab, $shop.price AS shop_item_price, ";
- $col .= "items.name_japanese AS shop_item_name";
+ $col .= "items.name_english AS shop_item_name";
$sql = "SELECT $col FROM $db.$shop LEFT OUTER JOIN $db.items ON items.id = $shop.item_id WHERE $shop.item_id = ?";
$sth = $this->server->connection->getStatement($sql);
diff --git a/lib/Flux/Config.php b/lib/Flux/Config.php
index aa12ac7ad..34905c36b 100644
--- a/lib/Flux/Config.php
+++ b/lib/Flux/Config.php
@@ -37,6 +37,22 @@ class Flux_Config {
* @var string
*/
private $exceptionClass = 'Flux_Error';
+
+ /**
+ * The list of configuration keys that are cleared if found in the import config.
+ * These are used for "normal" arrays, not associative arrays. This way is faster than
+ * checking if each array in the config is associative or not.
+ * @access private
+ * @var array
+ */
+ private $clearKeysOnImport = array(
+ 'ThemeName',
+ 'PayPalReceiverEmails',
+ 'PayPalAllowedHosts',
+ 'BanPaymentStatuses',
+ 'ShopImageExtensions',
+ );
+
/**
* Construct a Flux_Config instance which acts as a more convenient
@@ -94,6 +110,9 @@ public function &getChildrenConfigs()
*/
public function get($key, $configObjectIfArray = true)
{
+ if (!is_string($key) || empty($key)) {
+ return null;
+ }
$keys = explode('.', $key);
$base = &$this->configArr;
$size = count($keys) - 1;
@@ -191,7 +210,7 @@ public function raise($message)
* Adds the ability to call set() as native methods.
*
* @param string $method
- * @param arary $args
+ * @param array $args
* @access public
*/
public function __call($method, $args = array())
@@ -216,10 +235,60 @@ public function __call($method, $args = array())
/**
*
*/
- public function merge(Flux_Config $config, $recursive = true)
+ public function merge(Flux_Config $config, $recursive = true, $distinct = false)
{
- $mergeMethod = $recursive ? 'array_merge_recursive' : 'array_merge';
- $this->configArr = $mergeMethod($this->configArr, $config->toArray());
+ if (!$recursive && $distinct) {
+ $this->raise('Cannot merge non-recursively and distinctively at the same time.');
+ }
+ if ($distinct) {
+ $this->configArr = $this->array_merge_recursive_distinct($this->configArr, $config->toArray());
+ } else if ($recursive) {
+ $this->configArr = array_merge_recursive($this->configArr, $config->toArray());
+ } else {
+ $this->configArr = array_merge($this->configArr, $config->toArray());
+ }
+ }
+
+ /**
+ * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
+ * keys to arrays rather than overwriting the value in the first array with the duplicate
+ * value in the second array, as array_merge does. I.e., with array_merge_recursive,
+ * this happens (documented behavior):
+ *
+ * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
+ * => array('key' => array('org value', 'new value'));
+ *
+ * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
+ * Matching keys' values in the second array overwrite those in the first array, as is the
+ * case with array_merge, i.e.:
+ *
+ * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
+ * => array('key' => array('new value'));
+ *
+ * Because arrays are appended, not overwritten, we check each key against $clearKeysOnImport,
+ * and if it matches, we clear the array before importing the new values.
+ *
+ * @param array $array1
+ * @param array $array2
+ * @return array
+ * @author Daniel
+ * @author Gabriel Sobrinho
+ */
+ public function array_merge_recursive_distinct(array $base, array $import) {
+ $merged = $base;
+
+ foreach ($import as $key => &$value) {
+ if (in_array($key, $this->clearKeysOnImport)) {
+ $merged[$key] = array();
+ }
+ if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
+ $merged[$key] = $this->array_merge_recursive_distinct($merged[$key], $value);
+ } else {
+ $merged[$key] = $value;
+ }
+ }
+
+ return $merged;
}
}
?>
diff --git a/lib/Flux/Connection.php b/lib/Flux/Connection.php
index 3e63d928b..6ba181c08 100644
--- a/lib/Flux/Connection.php
+++ b/lib/Flux/Connection.php
@@ -26,6 +26,14 @@ class Flux_Connection {
*/
public $logsDbConfig;
+ /**
+ * Logs database configuration object.
+ *
+ * @access public
+ * @var Flux_Config
+ */
+ public $webDbConfig;
+
/**
* @access private
* @var PDO
@@ -38,15 +46,23 @@ class Flux_Connection {
*/
private $pdoLogs;
+ /**
+ * @access private
+ * @var PDO
+ */
+ private $pdoWeb;
+
/**
* @param Flux_Config $dbConfig
* @param Flux_Config $logsDbConfig
+ * @param Flux_Config $webDbConfig
* @access public
*/
- public function __construct(Flux_Config $dbConfig, Flux_Config $logsDbConfig)
+ public function __construct(Flux_Config $dbConfig, Flux_Config $logsDbConfig, Flux_Config $webDbConfig)
{
$this->dbConfig = $dbConfig;
$this->logsDbConfig = $logsDbConfig;
+ $this->webDbConfig = $webDbConfig;
}
/**
@@ -131,6 +147,31 @@ private function getLogsConnection()
return $this->pdoLogs;
}
+ /**
+ * Get the PDO instance for the web server database server connection.
+ *
+ * @return PDO
+ * @access private
+ */
+ private function getWebConnection()
+ {
+ if (!$this->pdoWeb) {
+ // Establish separate connection just for the web server database.
+ $pdoWeb = $this->connect($this->webDbConfig);
+ $this->pdoWeb = $pdoWeb;
+
+ if ($encoding=$this->webDbConfig->getEncoding()) {
+ $sth = $this->getStatementForWeb("SET NAMES ?");
+ $sth->execute(array($encoding));
+ }
+ if ($timezone=$this->webDbConfig->getTimezone()) {
+ $sth = $this->getStatementForWeb("SET time_zone = ?");
+ $sth->execute(array($timezone));
+ }
+ }
+ return $this->pdoWeb;
+ }
+
/**
* Select database to use.
*
@@ -188,6 +229,26 @@ public function getStatementForLogs($statement, $options = array())
}
}
+ /**
+ * Instanciate a PDOStatement without obtaining a PDO handler before-hand.
+ *
+ * @return PDOStatement
+ * @access public
+ */
+ public function getStatementForWeb($statement, $options = array())
+ {
+ $dbh = $this->getWebConnection();
+ $sth = $dbh->prepare($statement, $options);
+ @$sth->setFetchMode(PDO::FETCH_CLASS, 'Flux_DataObject', array(null, array('dbconfig' => $this->webDbConfig)));
+
+ if ($sth) {
+ return new Flux_Connection_Statement($sth);
+ }
+ else {
+ return false;
+ }
+ }
+
/**
*
*/
diff --git a/lib/Flux/ItemShop.php b/lib/Flux/ItemShop.php
index 422a354e6..d48875553 100644
--- a/lib/Flux/ItemShop.php
+++ b/lib/Flux/ItemShop.php
@@ -146,7 +146,7 @@ public function getItem($shopItemID)
$temp = new Flux_TemporaryTable($this->server->connection, "$db.items", $fromTables);
$shop = Flux::config('FluxTables.ItemShopTable');
$col = "$shop.id AS shop_item_id, $shop.category AS shop_item_category, $shop.cost AS shop_item_cost, $shop.quantity AS shop_item_qty, $shop.use_existing AS shop_item_use_existing, ";
- $col .= "$shop.nameid AS shop_item_nameid, $shop.info AS shop_item_info, items.name_japanese AS shop_item_name";
+ $col .= "$shop.nameid AS shop_item_nameid, $shop.info AS shop_item_info, items.name_english AS shop_item_name";
$sql = "SELECT $col FROM $db.$shop LEFT OUTER JOIN $db.items ON items.id = $shop.nameid WHERE $shop.id = ?";
$sth = $this->server->connection->getStatement($sql);
@@ -176,7 +176,7 @@ public function getItems($paginator, $categoryID = null)
$temp = new Flux_TemporaryTable($this->server->connection, "$db.items", $fromTables);
$shop = Flux::config('FluxTables.ItemShopTable');
$col = "$shop.id AS shop_item_id, $shop.cost AS shop_item_cost, $shop.quantity AS shop_item_qty, $shop.use_existing AS shop_item_use_existing, ";
- $col .= "$shop.nameid AS shop_item_nameid, $shop.info AS shop_item_info, items.name_japanese AS shop_item_name";
+ $col .= "$shop.nameid AS shop_item_nameid, $shop.info AS shop_item_info, items.name_english AS shop_item_name";
if (!is_null($categoryID)) {
$sqlpartial = " WHERE $shop.category = ?";
$bind[] = $categoryID;
diff --git a/lib/Flux/LogFile.php b/lib/Flux/LogFile.php
index 87cf7b030..e5edc5ec4 100644
--- a/lib/Flux/LogFile.php
+++ b/lib/Flux/LogFile.php
@@ -44,7 +44,7 @@ public function __construct($filename, $mode = 'a')
chmod($this->filename, 0600);
}
- $this->fp = fopen($this->filename, 'a');
+ $this->fp = fopen($this->filename, $mode);
if ($isNewFile) {
fputs($this->fp, "\n");
}
diff --git a/lib/Flux/LoginAthenaGroup.php b/lib/Flux/LoginAthenaGroup.php
index 19de6dd52..f7f7fccb1 100644
--- a/lib/Flux/LoginAthenaGroup.php
+++ b/lib/Flux/LoginAthenaGroup.php
@@ -44,6 +44,14 @@ class Flux_LoginAthenaGroup {
*/
public $logsDatabase;
+ /**
+ * Web server database.
+ *
+ * @access public
+ * @var string
+ */
+ public $webDatabase;
+
/**
* Array of Flux_Athena instances.
*
@@ -64,6 +72,7 @@ public function __construct($serverName, Flux_Connection $connection, Flux_Login
$this->loginServer = $loginServer;
$this->loginDatabase = $loginServer->config->getDatabase();
$this->logsDatabase = $connection->logsDbConfig->getDatabase();
+ $this->webDatabase = $connection->webDbConfig->getDatabase();
// Assign connection to LoginServer, used mainly to enable
// authentication feature.
diff --git a/lib/Flux/LoginServer.php b/lib/Flux/LoginServer.php
index 189281337..b8ddf9416 100644
--- a/lib/Flux/LoginServer.php
+++ b/lib/Flux/LoginServer.php
@@ -30,6 +30,14 @@ class Flux_LoginServer extends Flux_BaseServer {
*/
public $logsDatabase;
+ /**
+ * Web server database. (is not set until setConnection() is called.)
+ *
+ * @access public
+ * @var string
+ */
+ public $webDatabase;
+
/**
* Overridden to add custom properties.
*
@@ -52,6 +60,7 @@ public function setConnection(Flux_Connection $connection)
{
$this->connection = $connection;
$this->logsDatabase = $connection->logsDbConfig->getDatabase();
+ $this->webDatabase = $connection->webDbConfig->getDatabase();
return $connection;
}
@@ -110,7 +119,7 @@ public function register($username, $password, $confirmPassword, $email,$email2,
throw new Flux_RegisterError('Username is too long', Flux_RegisterError::USERNAME_TOO_LONG);
}
elseif (!Flux::config('AllowUserInPassword') && stripos($password, $username) !== false) {
- throw new Flux_RegisterError('Password contains username', Flux_RegisterError::USERNAME_IN_PASSWORD);
+ throw new Flux_RegisterError('Password contains username', Flux_RegisterError::PASSWORD_HAS_USERNAME);
}
elseif (!ctype_graph($password)) {
throw new Flux_RegisterError('Invalid character(s) used in password', Flux_RegisterError::INVALID_PASSWORD);
diff --git a/lib/Flux/Mailer.php b/lib/Flux/Mailer.php
index 7aa515a30..fe15700fb 100644
--- a/lib/Flux/Mailer.php
+++ b/lib/Flux/Mailer.php
@@ -81,6 +81,7 @@ public function send($recipient, $subject, $template, array $templateVars = arra
}
}
$this->pm->isHTML(true);
+ $this->pm->CharSet = 'UTF-8';
$this->pm->AddAddress($recipient);
$this->pm->Subject = $subject;
$this->pm->msgHTML($content);
diff --git a/lib/Flux/PaymentNotifyRequest.php b/lib/Flux/PaymentNotifyRequest.php
index 38f26bb7d..0397fbf79 100644
--- a/lib/Flux/PaymentNotifyRequest.php
+++ b/lib/Flux/PaymentNotifyRequest.php
@@ -132,11 +132,11 @@ protected function fetchIP()
*/
public function process()
{
- $allowed_hosts = ['ipn.sandbox.paypal.com', 'notify.paypal.com'];
+ $allowed_hosts = Flux::config('PayPalAllowedHosts')->toArray();
$received_from = gethostbyaddr($this->fetchIP());
$this->logPayPal('Received notification from %s (%s)', $this->fetchIP(), $received_from);
- if (in_array($received_from, $allowed_hosts) && $this->verify()) {
+ if ((in_array($received_from, $allowed_hosts) && $this->verify()) || $this->verifyiprange($received_from)) {
$this->logPayPal('Proceeding to validate the authenticity of the transaction...');
$accountEmails = Flux::config('PayPalReceiverEmails');
@@ -443,6 +443,34 @@ private function verify()
}
}
+ /*
+
+ */
+ private function verifyiprange($received_from)
+ {
+ $allowed_hosts = Flux::config('PayPalAllowedHosts')->toArray();
+ $ip_long = ip2long ( $received_from );
+
+ for ($i = 0; $i < 72; $i++)
+ {
+ if(strpos($allowed_hosts[$i], '/') !== false) {
+ $ip_arr = explode ( '/' , $allowed_hosts[$i] );
+
+ $network_long = ip2long ( $ip_arr[0] );
+
+ $x = ip2long ( $ip_arr [1]);
+ $mask = long2ip ( $x ) == $ip_arr [ 1 ] ? $x : 0xffffffff << ( 32 - $ip_arr [ 1 ]);
+
+ if(( $ip_long & $mask ) == ( $network_long & $mask ))
+ return true;
+ } else {
+ if($allowed_hosts[$i] == $received_from)
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Save the transaction details to disk in the file name format of:
* data/logs/transactions/TXN_TYPE/PAYMENT_STATUS.log
diff --git a/lib/Flux/RegisterError.php b/lib/Flux/RegisterError.php
index 637c72a18..4aa9aa974 100644
--- a/lib/Flux/RegisterError.php
+++ b/lib/Flux/RegisterError.php
@@ -5,7 +5,6 @@ class Flux_RegisterError extends Flux_Error {
const USERNAME_ALREADY_TAKEN = 0;
const USERNAME_TOO_SHORT = 1;
const USERNAME_TOO_LONG = 2;
- const USERNAME_IN_PASSWORD = 3;
const PASSWORD_TOO_SHORT = 4;
const PASSWORD_TOO_LONG = 5;
const PASSWORD_MISMATCH = 6;
diff --git a/lib/Flux/SessionData.php b/lib/Flux/SessionData.php
index 34a67bb70..62701a6db 100644
--- a/lib/Flux/SessionData.php
+++ b/lib/Flux/SessionData.php
@@ -243,6 +243,31 @@ public function isLoggedIn()
return $this->account->group_level >= AccountLevel::NORMAL;
}
+ /**
+ * Check securityCode from user with $this->securityCode or reCaptcha
+ * @param $securityCode Code from user
+ * @param $recaptcha True if check using recaptcha
+ * @return true on success and false on failure
+ */
+ public function checkSecurityCode($securityCode, $recaptcha = false) {
+ if ($recaptcha) {
+ if (Flux::config('ReCaptchaPrivateKey') && Flux::config('ReCaptchaPublicKey')) {
+ $responseKeys = array();
+ if (isset($_POST['g-recaptcha-response']) && $_POST['g-recaptcha-response'] != "") {
+ $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".Flux::config('ReCaptchaPrivateKey')."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']);
+ $responseKeys = json_decode($response,true);
+ }
+ if (count($responseKeys) && intval($responseKeys["success"]) == 1) {
+ return true;
+ }
+ }
+ }
+ else if ($securityCode && !empty($securityCode) && strtolower($securityCode) == strtolower($this->securityCode)) {
+ return true;
+ }
+ return false;
+ }
+
/**
* User login.
*
@@ -263,19 +288,8 @@ public function login($server, $username, $password, $securityCode = null)
throw new Flux_LoginError('IP address is banned', Flux_LoginError::IPBANNED);
}
- if ($securityCode !== false && Flux::config('UseLoginCaptcha')) {
- if (strtolower($securityCode) != strtolower($this->securityCode)) {
- throw new Flux_LoginError('Invalid security code', Flux_LoginError::INVALID_SECURITY_CODE);
- }
- elseif (Flux::config('EnableReCaptcha')) {
- if(isset($_POST['g-recaptcha-response']) && $_POST['g-recaptcha-response'] != ""){
- $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".Flux::config('ReCaptchaPrivateKey')."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']);
- }
- $responseKeys = json_decode($response,true);
- if(intval($responseKeys["success"]) !== 1) {
- throw new Flux_LoginError('Invalid security code', Flux_LoginError::INVALID_SECURITY_CODE);
- }
- }
+ if (Flux::config('UseLoginCaptcha') && !self::checkSecurityCode($securityCode, Flux::config('EnableReCaptcha'))) {
+ throw new Flux_LoginError('Invalid security code', Flux_LoginError::INVALID_SECURITY_CODE);
}
if (!$loginAthenaGroup->isAuth($username, $password)) {
diff --git a/lib/Flux/Template.php b/lib/Flux/Template.php
index fadfd78bc..577c6f0f5 100644
--- a/lib/Flux/Template.php
+++ b/lib/Flux/Template.php
@@ -434,6 +434,7 @@ public function getMenuItems($adminMenus = false)
foreach ($menu as $menuName => $menuItem) {
$module = array_key_exists('module', $menuItem) ? $menuItem['module'] : false;
$action = array_key_exists('action', $menuItem) ? $menuItem['action'] : $defaultAction;
+ $param = array_key_exists('param', $menuItem) ? $menuItem['param'] : array();
$exturl = array_key_exists('exturl', $menuItem) ? $menuItem['exturl'] : null;
if ($adminMenus) {
@@ -443,7 +444,7 @@ public function getMenuItems($adminMenus = false)
'exturl' => null,
'module' => $module,
'action' => $action,
- 'url' => $this->url($module, $action)
+ 'url' => $this->url($module, $action, $param)
);
}
}
@@ -467,7 +468,7 @@ public function getMenuItems($adminMenus = false)
'exturl' => null,
'module' => $module,
'action' => $action,
- 'url' => $this->url($module, $action)
+ 'url' => $this->url($module, $action, $param)
);
}
}
@@ -588,6 +589,15 @@ public function themePath($path, $included = false)
if (file_exists($chk)) {
$uri = $path;
}
+ } elseif (!file_exists($chk)) {
+ foreach (Flux::$addons as $_tmpAddon_key => $_tmpAddon) {
+ $chk = FLUX_ROOT .'/'. FLUX_ADDON_DIR .'/'. $_tmpAddon_key .'/'. preg_replace('/^('.$base.')/', '', $uri );
+ if (file_exists($chk)) {
+ $path = sprintf('%s/%s/%s', FLUX_ADDON_DIR, $_tmpAddon_key, preg_replace('/^('.$base.')/', '', $uri ));
+ $uri = $path;
+ break;
+ }
+ }
}
return $uri . $frag;
@@ -643,7 +653,7 @@ public function url($moduleName, $actionName = null, $params = array())
if (count($params)) {
$queryString .= Flux::config('UseCleanUrls') ? '?' : '&';
foreach ($params as $param => $value) {
- $queryString .= sprintf('%s=%s&', $param, urlencode($value));
+ $queryString .= sprintf('%s=%s&', $param, urlencode($value ?: ''));
}
$queryString = rtrim($queryString, '&');
}
@@ -1075,14 +1085,25 @@ public function homunClassText($id)
/**
* Get the item type name from an item type.
*
- * @param int $id
- * @param int $id2
- * @return mixed Item type or false.
+ * @return Item type or false.
* @access public
*/
- public function itemTypeText($id, $id2 = null)
+ public function itemTypeText($id)
+ {
+ return Flux::getItemType($id);
+ }
+
+ public function itemSubTypeText($id1, $id2)
+ {
+ if($id1 == 'Weapon' || $id1 == 'Ammo' || $id1 == 'Card')
+ return Flux::getItemSubType(strtolower($id1), strtolower($id2));
+ else
+ return false;
+ }
+
+ public function itemRandOption($id, $value)
{
- return Flux::getItemType($id, $id2);
+ return sprintf(Flux::getRandOption($id), $value);
}
/**
@@ -1173,7 +1194,7 @@ public function linkToItem($itemID, $text, $server = null)
*/
public function displayScript($scriptText)
{
- $lines = preg_split('/(\r?\n)/', $scriptText, -1);
+ $lines = !empty($scriptText) ? preg_split('/\s+|<|>|\[|\]/', $scriptText, -1, PREG_SPLIT_NO_EMPTY) : [];
$text = '';
$script = array();
@@ -1213,26 +1234,66 @@ public function banTypeText($banType)
public function equippableJobs($equipJob)
{
$jobs = array();
- $equipJob = (int)$equipJob;
$equipJobs = Flux::getEquipJobsList();
- foreach ($equipJobs as $bit => $name) {
- if ($equipJob & $bit) {
- $jobs[] = $name;
- }
+ foreach ($equipJob as $name) {
+ $jobs[] = $equipJobs[$name];
+ if($name == 'job_all') break;
}
- if (count($jobs) === count($equipJobs)) {
- return array('All Jobs');
- }
- else if (count($jobs) === count($equipJobs) - 1 && !in_array($equipJobs, $jobs)) {
- return array('All Jobs Except Novice');
- }
- else {
- return $jobs;
+ return $jobs;
+ }
+
+ /**
+ *
+ */
+ public function GetJobsList($isRenewal)
+ {
+ $jobs = Flux::getEquipJobsList($isRenewal);
+
+ return $jobs;
+ }
+
+ /**
+ *
+ */
+ public function GetClassList($isRenewal)
+ {
+ $jobs = Flux::getEquipUpperList($isRenewal);
+
+ return $jobs;
+ }
+
+ /**
+ *
+ */
+ public function tradeRestrictions($list)
+ {
+ $restrictions = array();
+ $Restrictions = Flux::getTradeRestrictionList();
+
+ foreach ($list as $name) {
+ $restrictions[] = $Restrictions[$name];
}
+
+ return $restrictions;
}
+ /**
+ *
+ */
+ public function itemsFlags($list)
+ {
+ $flags = array();
+ $Flags = Flux::getItemFlagList();
+
+ foreach ($list as $name) {
+ $flags[] = $Flags[$name];
+ }
+
+ return $flags;
+ }
+
/**
* Link to a monster view page.
*
@@ -1262,31 +1323,34 @@ public function linkToMonster($monsterID, $text, $server = null)
*/
public function equipLocations($equipLoc)
{
- $locations = array();
- $equipLoc = (int)$equipLoc;
- $equipLocs = Flux::getEquipLocationList();
-
- foreach ($equipLocs as $bit => $name) {
- if ($equipLoc & $bit) {
- $locations[] = $name;
- }
- }
-
- return $locations;
+ $locations = array();
+ asort($equipLoc);
+ if(count($equipLoc) > 1) {
+ $equipLocs = Flux::getEquipLocationCombination();
+ $equipLoc = array(htmlspecialchars(implode('/', $equipLoc)));
+ } else {
+ $equipLocs = Flux::getEquipLocationList();
+ }
+ foreach ($equipLoc as $key => $name) {
+ $locations[] = $equipLocs[$name];
+ }
+ if(is_array($equipLoc))
+ return htmlspecialchars(implode(' / ', $locations));
+ else
+ return false;
}
/**
*
*/
- public function equipUpper($equipUpper)
+ public function equipUpper($equipUpper, $isRenewal = 1)
{
- $upper = array();
- $table = Flux::getEquipUpperList();
+ $upper = array();
+ $table = Flux::getEquipUpperList($isRenewal);
- foreach ($table as $bit => $name) {
- if ($equipUpper & $bit) {
- $upper[] = $name;
- }
+ foreach ($equipUpper as $name) {
+ $upper[] = $table[$name];
+ if($name == 'class_all') break;
}
return $upper;
@@ -1372,7 +1436,15 @@ public function iconImage($itemID)
{
$path = sprintf(FLUX_DATA_DIR."/items/icons/".Flux::config('ItemIconNameFormat'), $itemID);
$link = preg_replace('&/{2,}&', '/', "{$this->basePath}/$path");
- return file_exists($path) ? $link : false;
+
+ if(Flux::config('DivinePrideIntegration') && !file_exists($path)) {
+ $download_link = "https://static.divine-pride.net/images/items/item/$itemID.png";
+ $data = get_headers($download_link, true);
+ $size = isset($data['Content-Length']) ? (int)$data['Content-Length'] : 0;
+ if($size != 0)
+ file_put_contents(sprintf(FLUX_DATA_DIR."/items/icons/".Flux::config('ItemIconNameFormat'), $itemID), file_get_contents($download_link));
+ }
+ return file_exists($path) ? $link : false;
}
/**
@@ -1382,7 +1454,15 @@ public function itemImage($itemID)
{
$path = sprintf(FLUX_DATA_DIR."/items/images/".Flux::config('ItemImageNameFormat'), $itemID);
$link = preg_replace('&/{2,}&', '/', "{$this->basePath}/$path");
- return file_exists($path) ? $link : false;
+
+ if(Flux::config('DivinePrideIntegration') && !file_exists($path)) {
+ $download_link = "https://static.divine-pride.net/images/items/collection/$itemID.png";
+ $data = get_headers($download_link, true);
+ $size = isset($data['Content-Length']) ? (int)$data['Content-Length'] : 0;
+ if($size != 0)
+ file_put_contents(sprintf(FLUX_DATA_DIR."/items/images/".Flux::config('ItemImageNameFormat'), $itemID), file_get_contents($download_link));
+ }
+ return file_exists($path) ? $link : false;
}
/**
@@ -1392,7 +1472,15 @@ public function monsterImage($monsterID)
{
$path = sprintf(FLUX_DATA_DIR."/monsters/".Flux::config('MonsterImageNameFormat'), $monsterID);
$link = preg_replace('&/{2,}&', '/', "{$this->basePath}/$path");
- return file_exists($path) ? $link : false;
+
+ if(Flux::config('DivinePrideIntegration') && !file_exists($path)) {
+ $download_link = "https://static.divine-pride.net/images/mobs/png/$monsterID.png";
+ $data = get_headers($download_link, true);
+ $size = isset($data['Content-Length']) ? (int)$data['Content-Length'] : 0;
+ if($size != 0)
+ file_put_contents(sprintf(FLUX_DATA_DIR."/monsters/".Flux::config('MonsterImageNameFormat'), $monsterID), file_get_contents($download_link));
+ }
+ return file_exists($path) ? $link : false;
}
/**
@@ -1408,16 +1496,22 @@ public function jobImage($gender, $jobID)
/**
*
*/
- public function monsterMode($mode)
+ public function monsterMode($modes, $ai)
{
- $modes = Flux::monsterModeToArray($mode);
+ $monsterModes = Flux::config('MonsterModes')->toArray();
+ $monsterAI = Flux::config('MonsterAI')->toArray();
$array = array();
- foreach (Flux::config('MonsterModes')->toArray() as $bit => $name) {
- if (in_array($bit, $modes)) {
- $array[] = $name;
+ if($ai)
+ foreach ($monsterAI[$ai] as $mode) {
+ if(isset($monsterModes[$mode]))
+ $array[] = $monsterModes[$mode];
}
- }
- return $array;
+ if($modes)
+ foreach ($modes as $mode) {
+ if(isset($monsterModes[$mode]))
+ $array[] = $monsterModes[$mode];
+ }
+ return array_unique($array);
}
/**
@@ -1428,5 +1522,14 @@ public function getName()
{
return $this->themeName;
}
+
+ /**
+ * Caps values to min/max
+ * @access public
+ */
+ public function cap_value($amount, $min, $max)
+ {
+ return ($amount >= $max) ? $max : (($amount <= $min) ? $min : $amount);
+ }
}
?>
diff --git a/lib/Flux/TemporaryTable.php b/lib/Flux/TemporaryTable.php
index e91cc768d..4556cd0fc 100644
--- a/lib/Flux/TemporaryTable.php
+++ b/lib/Flux/TemporaryTable.php
@@ -67,9 +67,10 @@ public function __construct(Flux_Connection $connection, $tableName, array $from
// Find the first table.
reset($this->fromTables);
- $firstTable = current($this->fromTables);
+ $firstTable = $this->fromTables[0];
+ $secondTable = $this->fromTables[1];
- if ($this->create($firstTable)) {
+ if ($this->create($secondTable)) {
// Insert initial row set.
// Rows imported from the following tables should overwrite these rows.
if (!$this->import($firstTable, false)) {
diff --git a/lib/functions/discordwebhook.php b/lib/functions/discordwebhook.php
index 91e2acd03..622bb1761 100644
--- a/lib/functions/discordwebhook.php
+++ b/lib/functions/discordwebhook.php
@@ -7,6 +7,7 @@
function sendtodiscord($url, $message) {
$data = array("content" => $message);
$curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
diff --git a/lib/functions/getReposVersion.php b/lib/functions/getReposVersion.php
index 0f5acc5cc..bd234b7ab 100644
--- a/lib/functions/getReposVersion.php
+++ b/lib/functions/getReposVersion.php
@@ -7,13 +7,11 @@
function getReposVersion()
{
$gitDir = FLUX_ROOT.'/.git';
- $svnDir = FLUX_ROOT.'/.svn';
-
- if (is_dir($gitDir)) {
+
+ if(is_dir($gitDir)) {
return git_hash();
- }
- else if (is_dir($svnDir)) {
- return svn_version();
+ } else {
+ return null;
}
}
@@ -23,63 +21,17 @@ function getReposVersion()
* @param string file name.
* @return int GIT hash
*/
-function git_hash()
-{
+function git_hash() {
$file = FLUX_ROOT.'/.git/refs/heads/master';
-
if (file_exists($file) && is_readable($file)) {
$lines = implode('', file($file, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES));
-
if(isset($lines)) {
return trim(substr($lines, 0, 10));
}
return null;
+ } else {
+ return null;
}
}
-/**
- * Get the SVN revision of a directory.
- *
- * @param string `entries' file name.
- * @return int Revision number
- */
-function svn_version()
-{
- $rev = null;
-
- // Subversion 1.6 and lower
- $file = FLUX_ROOT.'/.svn/entries';
- if (file_exists($file) && is_readable($file)) {
- $fp = fopen($file, 'r');
- $arr = explode("\n", fread($fp, 256));
-
- if (isset($arr[3]) && ctype_digit($found = trim($arr[3]))) {
- $rev = $found;
- }
- fclose($fp);
- }
-
- //Subversion 1.7 and up
- if(!isset($rev)) {
- $file = FLUX_ROOT.'/.svn/wc.db';
- $curr = 0;
-
- if (file_exists($file) && is_readable($file)) {
- $fp = fopen($file, 'r');
-
- while(($line = fread($fp, 64))) {
- if(strstr($line,"!svn/ver/") && sscanf(strstr($line,"!svn/ver/"),"!svn/ver/%d/%*s", $curr) == 1) {
- if($curr > $rev) {
- $rev = $curr;
- }
- }
- }
-
- fclose($fp);
- }
- }
-
- return $rev;
-}
-
?>
diff --git a/lib/functions/imagecreatefrombmpstring.php b/lib/functions/imagecreatefrombmpstring.php
index cc26cd8d4..96d78f61d 100644
--- a/lib/functions/imagecreatefrombmpstring.php
+++ b/lib/functions/imagecreatefrombmpstring.php
@@ -21,10 +21,12 @@ function imagecreatefrombmpstring($im) {
$palette = substr($im, 54, $palette_size);
$j = 0; $n = 0;
while($j < $palette_size) {
- $b = ord($palette{$j++});
- $g = ord($palette{$j++});
- $r = ord($palette{$j++});
- $a = ord($palette{$j++});
+ $b = ord($palette[$j++]);
+ $g = ord($palette[$j++]);
+ $r = ord($palette[$j++]);
+ $a = ord($palette[$j++]);
+ if ($a > 127)
+ $a = 127; // alpha = 255 on 0xFF00FF
if ( ($r & 0xf8 == 0xf8) && ($g == 0) && ($b & 0xf8 == 0xf8))
$a = 127; // alpha = 255 on 0xFF00FF
$pal[$n++] = imagecolorallocatealpha($imres, $r, $g, $b, $a);
@@ -37,9 +39,9 @@ function imagecreatefrombmpstring($im) {
if($bits == 24) {
$j = 0; $n = 0;
while($j < $scan_line_size) {
- $b = ord($scan_line{$j++});
- $g = ord($scan_line{$j++});
- $r = ord($scan_line{$j++});
+ $b = ord($scan_line[$j++]);
+ $g = ord($scan_line[$j++]);
+ $r = ord($scan_line[$j++]);
$a = 0;
if ( ($r & 0xf8 == 0xf8) && ($g == 0) && ($b & 0xf8 == 0xf8))
$a = 127; // alpha = 255 on 0xFF00FF
@@ -50,14 +52,14 @@ function imagecreatefrombmpstring($im) {
else if($bits == 8) {
$j = 0;
while($j < $scan_line_size) {
- $col = $pal[ord($scan_line{$j++})];
+ $col = $pal[ord($scan_line[$j++])];
imagesetpixel($imres, $j-1, $i, $col);
}
}
else if($bits == 4) {
$j = 0; $n = 0;
while($j < $scan_line_size) {
- $byte = ord($scan_line{$j++});
+ $byte = ord($scan_line[$j++]);
$p1 = $byte >> 4;
$p2 = $byte & 0x0F;
imagesetpixel($imres, $n++, $i, $pal[$p1]);
@@ -67,7 +69,7 @@ function imagecreatefrombmpstring($im) {
else if($bits == 1) {
$j = 0; $n = 0;
while($j < $scan_line_size) {
- $byte = ord($scan_line{$j++});
+ $byte = ord($scan_line[$j++]);
$p1 = (int) (($byte & 0x80) != 0);
$p2 = (int) (($byte & 0x40) != 0);
$p3 = (int) (($byte & 0x20) != 0);
diff --git a/lib/phpmailer/PHPMailerAutoload.php b/lib/phpmailer/PHPMailerAutoload.php
index eaa2e3034..830bd91bf 100644
--- a/lib/phpmailer/PHPMailerAutoload.php
+++ b/lib/phpmailer/PHPMailerAutoload.php
@@ -37,13 +37,5 @@ function PHPMailerAutoload($classname)
} else {
spl_autoload_register('PHPMailerAutoload');
}
-} else {
- /**
- * Fall back to traditional autoload for old PHP versions
- * @param string $classname The name of the class to load
- */
- function __autoload($classname)
- {
- PHPMailerAutoload($classname);
- }
+ // Removed fallback to older versions due to deprecated command [Everade]
}
diff --git a/modules/account/create.php b/modules/account/create.php
index 71d9c52a3..424afda01 100644
--- a/modules/account/create.php
+++ b/modules/account/create.php
@@ -73,7 +73,7 @@
$session->setMessageData($message);
}
else {
- $session->login($server->serverName, $username, $password, false);
+ $session->login($server->serverName, $username, $password, $code);
$session->setMessageData(Flux::message('AccountCreated'));
$discordMessage = 'Account Created.';
}
diff --git a/modules/account/view.php b/modules/account/view.php
index d2572e1b1..22d0f6fdf 100644
--- a/modules/account/view.php
+++ b/modules/account/view.php
@@ -34,17 +34,17 @@
if (!$auth->allowedToViewAccount) {
$this->deny();
}
-
+
$sql = "SELECT login.*, {$creditColumns}, {$createColumns} FROM {$server->loginDatabase}.login ";
$sql .= "LEFT OUTER JOIN {$server->loginDatabase}.{$creditsTable} AS credits ON login.account_id = credits.account_id ";
$sql .= "LEFT OUTER JOIN {$server->loginDatabase}.{$createTable} AS created ON login.account_id = created.account_id ";
$sql .= "WHERE login.sex != 'S' AND login.group_id >= 0 AND login.account_id = ? LIMIT 1";
$sth = $server->connection->getStatement($sql);
$sth->execute(array($accountID));
-
+
// Account object.
$account = $sth->fetch();
-
+
if ($account) {
$title = sprintf(Flux::message('AccountViewTitle2'), $account->userid);
}
@@ -70,11 +70,11 @@
$vipexpires = 'Expires '.$dt->format('Y-m-d');
} elseif ($account->vip_time == '0'){
$vipexpires = 'Standard Account';
-} else {$vipexpires = 'Unknown';}
+} else {$vipexpires = 'Unknown';}
if (count($_POST) && $account) {
$reason = (string)$params->get('reason');
-
+
if ($params->get('tempban') && ($tempBanDate=$params->get('tempban_date'))) {
if ($canTempBan) {
if ($server->loginServer->temporarilyBan($session->account->account_id, $reason, $account->account_id, $tempBanDate)) {
@@ -108,30 +108,30 @@
$tbl = Flux::config('FluxTables.AccountCreateTable');
$sql = "SELECT account_id FROM {$server->loginDatabase}.$tbl WHERE confirmed = 0 AND account_id = ?";
$sth = $server->connection->getStatement($sql);
-
+
$sth->execute(array($account->account_id));
$confirm = $sth->fetch();
-
+
$sql = "UPDATE {$server->loginDatabase}.$tbl SET confirmed = 1, confirm_expire = NULL WHERE account_id = ?";
$sth = $server->connection->getStatement($sql);
-
+
if ($tempBanned && $auth->allowedToTempUnbanAccount &&
$server->loginServer->unban($session->account->account_id, $reason, $account->account_id)) {
-
+
if ($confirm) {
$sth->execute(array($account->account_id));
}
-
+
$session->setMessageData(Flux::message('AccountLiftTempBan'));
$this->redirect($this->url('account', 'view', array('id' => $account->account_id)));
}
elseif ($permBanned && $auth->allowedToPermUnbanAccount &&
$server->loginServer->unban($session->account->account_id, $reason, $account->account_id)) {
-
+
if ($confirm) {
$sth->execute(array($account->account_id));
}
-
+
$session->setMessageData(Flux::message('AccountLiftPermBan'));
$this->redirect($this->url('account', 'view', array('id' => $account->account_id)));
}
@@ -149,8 +149,8 @@
$characters = array();
foreach ($session->getAthenaServerNames() as $serverName) {
$athena = $session->getAthenaServer($serverName);
-
- $sql = "SELECT ch.*, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len ";
+
+ $sql = "SELECT ch.*, guild.name AS guild_name ";
$sql .= "FROM {$athena->charMapDatabase}.`char` AS ch ";
$sql .= "LEFT OUTER JOIN {$athena->charMapDatabase}.guild ON guild.guild_id = ch.guild_id ";
$sql .= "WHERE ch.account_id = ? ORDER BY ch.char_num ASC";
@@ -161,7 +161,7 @@
$characters[$athena->serverName] = $chars;
}
-$col = "storage.*, items.name_japanese, items.type, items.slots, c.char_id, c.name AS char_name";
+$col = "storage.*, items.name_english, items.type, items.slots, c.char_id, c.name AS char_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.storage ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.items ON items.id = storage.nameid ";
@@ -190,7 +190,7 @@
foreach ($items as $item) {
$item->cardsOver = -$item->slots;
-
+
if ($item->card0) {
$cardIDs[] = $item->card0;
$item->cardsOver++;
@@ -207,27 +207,38 @@
$cardIDs[] = $item->card3;
$item->cardsOver++;
}
-
+
if ($item->card0 == 254 || $item->card0 == 255 || $item->card0 == -256 || $item->cardsOver < 0) {
$item->cardsOver = 0;
}
+
+ if($server->isRenewal) {
+ $temp = array();
+ if ($item->option_id0) array_push($temp, array($item->option_id0, $item->option_val0));
+ if ($item->option_id1) array_push($temp, array($item->option_id1, $item->option_val1));
+ if ($item->option_id2) array_push($temp, array($item->option_id2, $item->option_val2));
+ if ($item->option_id3) array_push($temp, array($item->option_id3, $item->option_val3));
+ if ($item->option_id4) array_push($temp, array($item->option_id4, $item->option_val4));
+ $item->rndopt = $temp;
+ }
}
if ($cardIDs) {
$ids = implode(',', array_fill(0, count($cardIDs), '?'));
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
$sth = $server->connection->getStatement($sql);
$sth->execute($cardIDs);
$temp = $sth->fetchAll();
if ($temp) {
foreach ($temp as $card) {
- $cards[$card->id] = $card->name_japanese;
+ $cards[$card->id] = $card->name_english;
}
}
}
}
-
+
$itemAttributes = Flux::config('Attributes')->toArray();
+ $type_list = Flux::config('ItemTypes')->toArray();
}
?>
diff --git a/modules/buyingstore/viewshop.php b/modules/buyingstore/viewshop.php
index 7ed11d571..c45107755 100644
--- a/modules/buyingstore/viewshop.php
+++ b/modules/buyingstore/viewshop.php
@@ -27,7 +27,7 @@
// Get the current buyer values.
$sql = "SELECT `buyingstore_items`.`buyingstore_id`, `buyingstore_items`.`index`, `buyingstore_items`.`amount`, `buyingstore_items`.`price`";
$sql .= ",`buyingstore_items`.`item_id` as nameid";
- $sql .= ",`items`.`name_japanese` as item_name, `items`.`slots`, `items`.`type` ";
+ $sql .= ",`items`.`name_english` as item_name, `items`.`slots`, `items`.`type` ";
$sql .= "FROM buyingstore_items ";
$sql .= "LEFT JOIN items on `buyingstore_items`.item_id = items.id ";
$sql .= "WHERE `buyingstore_id` = ? ";
diff --git a/modules/cashshop/add.php b/modules/cashshop/add.php
index 2dca31c87..5e546fbcd 100644
--- a/modules/cashshop/add.php
+++ b/modules/cashshop/add.php
@@ -24,7 +24,7 @@
$tableName = "{$server->charMapDatabase}.items";
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
-$col = "id AS item_id, name_japanese AS item_name, type";
+$col = "id AS item_id, name_english AS item_name, type";
$sql = "SELECT $col FROM $tableName WHERE items.id = ?";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/cashshop/edit.php b/modules/cashshop/edit.php
index eebe12fca..a8c9fc663 100644
--- a/modules/cashshop/edit.php
+++ b/modules/cashshop/edit.php
@@ -25,7 +25,7 @@
$tableName = "{$server->charMapDatabase}.items";
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
- $col = "id AS item_id, name_japanese AS item_name, type";
+ $col = "id AS item_id, name_english AS item_name, type";
$sql = "SELECT $col FROM $tableName WHERE items.id = ?";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/cashshop/index.php b/modules/cashshop/index.php
index 32d077a70..110d4e9b0 100644
--- a/modules/cashshop/index.php
+++ b/modules/cashshop/index.php
@@ -20,7 +20,7 @@
$tableName = "{$server->charMapDatabase}.items";
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
-$col = "cash.tab AS tab, cash.item_id AS item_id, cash.price AS price, items.name_japanese AS item_name";
+$col = "cash.tab AS tab, cash.item_id AS item_id, cash.price AS price, items.name_english AS item_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`item_cash_db` AS cash ";
$sql.= "LEFT OUTER JOIN {$server->charMapDatabase}.items ON items.id = cash.item_id ORDER BY tab";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/castle/index.php b/modules/castle/index.php
index ccb939695..2f1e34210 100644
--- a/modules/castle/index.php
+++ b/modules/castle/index.php
@@ -6,7 +6,8 @@
$castleNames = Flux::config('CastleNames')->toArray();
$ids = implode(',', array_fill(0, count($castleNames), '?'));
-$sql = "SELECT castles.castle_id, castles.guild_id, guild.name AS guild_name, guild.emblem_len FROM {$server->charMapDatabase}.guild_castle AS castles ";
+$sql = "SELECT castles.castle_id, castles.guild_id, castles.economy, guild.name AS guild_name, guild.emblem_id as emblem ";
+$sql .= "FROM {$server->charMapDatabase}.guild_castle AS castles ";
$sql .= "LEFT JOIN guild ON guild.guild_id = castles.guild_id ";
$sql .= "WHERE castles.castle_id IN ($ids)";
$sql .= "ORDER BY castles.castle_id ASC";
@@ -15,4 +16,4 @@
$castles = $sth->fetchAll();
-?>
+?>
\ No newline at end of file
diff --git a/modules/character/index.php b/modules/character/index.php
index fec837a5e..83645045a 100644
--- a/modules/character/index.php
+++ b/modules/character/index.php
@@ -13,6 +13,7 @@
$sqlpartial .= "LEFT OUTER JOIN {$server->charMapDatabase}.`char` AS mother ON mother.char_id = ch.mother ";
$sqlpartial .= "LEFT OUTER JOIN {$server->charMapDatabase}.`char` AS father ON father.char_id = ch.father ";
$sqlpartial .= "LEFT OUTER JOIN {$server->charMapDatabase}.`char` AS child ON child.char_id = ch.child ";
+
$sqlwhere = "WHERE 1=1 ";
$sqlcount = '';
@@ -166,7 +167,7 @@
$col = "ch.account_id, ch.char_id, ch.name AS char_name, ch.char_num, ";
$col .= "ch.online, ch.base_level, ch.job_level, ch.class, ch.zeny, ";
-$col .= "guild.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len, ";
+$col .= "guild.guild_id, guild.name AS guild_name, guild.emblem_id as emblem, ";
$col .= "login.userid, partner.name AS partner_name, partner.char_id AS partner_id, ";
$col .= "mother.name AS mother_name, mother.char_id AS mother_id, ";
$col .= "father.name AS father_name, father.char_id AS father_id, ";
diff --git a/modules/character/online.php b/modules/character/online.php
index f1cca4857..bfc27e3cb 100644
--- a/modules/character/online.php
+++ b/modules/character/online.php
@@ -98,7 +98,7 @@
$hiddenCount = (int)$sth->fetch()->total;
$col = "ch.char_id, ch.name AS char_name, ch.class AS char_class, ch.base_level, ch.job_level, ";
-$col .= "guild.name AS guild_name, guild.guild_id, guild.emblem_len AS guild_emblem_len, ch.last_map, pref2.value AS hidemap";
+$col .= "guild.name AS guild_name, guild.guild_id, ch.last_map, pref2.value AS hidemap, guild.emblem_id as emblem ";
$sql = $paginator->getSQL("SELECT $col FROM {$server->charMapDatabase}.`char` AS ch $sqlpartial");
$sth = $server->connection->getStatement($sql);
diff --git a/modules/character/view.php b/modules/character/view.php
index 49dafb6eb..070e72d5e 100644
--- a/modules/character/view.php
+++ b/modules/character/view.php
@@ -31,7 +31,7 @@
$col .= "mother.name AS mother_name, mother.char_id AS mother_id, ";
$col .= "father.name AS father_name, father.char_id AS father_id, ";
$col .= "child.name AS child_name, child.char_id AS child_id, ";
-$col .= "guild.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len, ";
+$col .= "guild.guild_id, guild.name AS guild_name, guild.emblem_id AS emblem, ";
$col .= "guild_position.name AS guild_position, IFNULL(guild_position.exp_mode, 0) AS guild_tax, ";
$col .= "party.name AS party_name, party.leader_char AS party_leader_id, party_leader.name AS party_leader_name, ";
@@ -42,7 +42,7 @@
$col .= "homun.skill_point AS homun_skill_point, homun.alive AS homun_alive, ";
$col .= "pet.class AS pet_class, pet.name AS pet_name, pet.level AS pet_level, pet.intimate AS pet_intimacy, ";
-$col .= "pet.hungry AS pet_hungry, pet_mob.kName AS pet_mob_name, pet_mob2.kName AS pet_mob_name2, ";
+$col .= "pet.hungry AS pet_hungry, pet_mob.name_english AS pet_mob_name, pet_mob2.name_english AS pet_mob_name2, ";
$col .= "IFNULL(reg.value, 0) AS death_count";
@@ -89,7 +89,8 @@
$title = "Viewing Character ({$char->char_name})";
$sql = "SELECT fr.char_id, fr.name, fr.class, fr.base_level, fr.job_level, ";
- $sql .= "guild.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len, fr.online ";
+ $sql .= "guild.guild_id, guild.name AS guild_name, fr.online, ";
+ $sql .= "guild.emblem_id AS emblem ";
$sql .= "FROM {$server->charMapDatabase}.`char` AS fr ";
$sql .= "LEFT OUTER JOIN {$server->charMapDatabase}.guild ON guild.guild_id = fr.guild_id ";
$sql .= "LEFT OUTER JOIN {$server->charMapDatabase}.friends ON friends.friend_id = fr.char_id ";
@@ -101,7 +102,8 @@
if ($char->party_leader_id) {
$sql = "SELECT p.char_id, p.name, p.class, p.base_level, p.job_level, ";
- $sql .= "guild.guild_id, guild.name AS guild_name, p.online ";
+ $sql .= "guild.guild_id, guild.name AS guild_name, p.online, ";
+ $sql .= "guild.emblem_id AS emblem ";
$sql .= "FROM {$server->charMapDatabase}.`char` AS p ";
$sql .= "LEFT OUTER JOIN {$server->charMapDatabase}.guild ON guild.guild_id = p.guild_id ";
$sql .= "WHERE p.party_id = ? AND p.char_id != ? ORDER BY p.name ASC";
@@ -114,7 +116,7 @@
$partyMembers = array();
}
- $col = "inventory.*, items.name_japanese, items.type, items.slots, c.char_id, c.name AS char_name";
+ $col = "inventory.*, items.name_english, items.type, items.slots, c.char_id, c.name AS char_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.inventory ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.items ON items.id = inventory.nameid ";
@@ -163,24 +165,34 @@
if ($item->card0 == 254 || $item->card0 == 255 || $item->card0 == -256 || $item->cardsOver < 0) {
$item->cardsOver = 0;
}
+
+ if($server->isRenewal) {
+ $temp = array();
+ if ($item->option_id0) array_push($temp, array($item->option_id0, $item->option_val0));
+ if ($item->option_id1) array_push($temp, array($item->option_id1, $item->option_val1));
+ if ($item->option_id2) array_push($temp, array($item->option_id2, $item->option_val2));
+ if ($item->option_id3) array_push($temp, array($item->option_id3, $item->option_val3));
+ if ($item->option_id4) array_push($temp, array($item->option_id4, $item->option_val4));
+ $item->rndopt = $temp;
+ }
}
if ($cardIDs) {
$ids = implode(',', array_fill(0, count($cardIDs), '?'));
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
$sth = $server->connection->getStatement($sql);
$sth->execute($cardIDs);
$temp = $sth->fetchAll();
if ($temp) {
foreach ($temp as $card) {
- $cards[$card->id] = $card->name_japanese;
+ $cards[$card->id] = $card->name_english;
}
}
}
}
- $col = "cart_inventory.*, items.name_japanese, items.type, items.slots, c.char_id, c.name AS char_name";
+ $col = "cart_inventory.*, items.name_english, items.type, items.slots, c.char_id, c.name AS char_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.cart_inventory ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.items ON items.id = cart_inventory.nameid ";
@@ -229,23 +241,34 @@
if ($item->card0 == 254 || $item->card0 == 255 || $item->card0 == -256 || $item->cardsOver < 0) {
$item->cardsOver = 0;
}
+
+ if($server->isRenewal) {
+ $temp = array();
+ if ($item->option_id0) array_push($temp, array($item->option_id0, $item->option_val0));
+ if ($item->option_id1) array_push($temp, array($item->option_id1, $item->option_val1));
+ if ($item->option_id2) array_push($temp, array($item->option_id2, $item->option_val2));
+ if ($item->option_id3) array_push($temp, array($item->option_id3, $item->option_val3));
+ if ($item->option_id4) array_push($temp, array($item->option_id4, $item->option_val4));
+ $item->rndopt = $temp;
+ }
}
if ($cardIDs) {
$ids = implode(',', array_fill(0, count($cardIDs), '?'));
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
$sth = $server->connection->getStatement($sql);
$sth->execute($cardIDs);
$temp = $sth->fetchAll();
if ($temp) {
foreach ($temp as $card) {
- $cart_cards[$card->id] = $card->name_japanese;
+ $cart_cards[$card->id] = $card->name_english;
}
}
}
}
$itemAttributes = Flux::config('Attributes')->toArray();
+ $type_list = Flux::config('ItemTypes')->toArray();
}
?>
diff --git a/modules/cplog/login.php b/modules/cplog/login.php
index fe2783be5..d60d890cf 100644
--- a/modules/cplog/login.php
+++ b/modules/cplog/login.php
@@ -9,8 +9,8 @@
$password = $params->get('password');
$accountID = (int)$params->get('account_id');
-$username = trim($params->get('username'));
-$ipAddress = trim($params->get('ip'));
+$username = trim($params->get('username') ?: '');
+$ipAddress = trim($params->get('ip') ?: '');
$loginAfter = $params->get('login_after_date');
$loginBefore = $params->get('login_before_date');
$errorCode = $params->get('error_code');
diff --git a/modules/guild/emblem.php b/modules/guild/emblem.php
index 1abd65f20..9e47e0e82 100644
--- a/modules/guild/emblem.php
+++ b/modules/guild/emblem.php
@@ -29,10 +29,11 @@ function flux_display_empty_emblem()
if (!$athenaServer || $guildID < 0)
flux_display_empty_emblem();
else {
+ $dirname = FLUX_DATA_DIR."/tmp/emblems/$serverName/$athenaServerName";
+ $filename = "$dirname/$guildID.png";
+
if ($interval=Flux::config('EmblemCacheInterval')) {
$interval *= 60;
- $dirname = FLUX_DATA_DIR."/tmp/emblems/$serverName/$athenaServerName";
- $filename = "$dirname/$guildID.png";
if (!is_dir($dirname))
if (Flux::config('RequireOwnership'))
@@ -47,27 +48,50 @@ function flux_display_empty_emblem()
}
}
- $db = $athenaServer->charMapDatabase;
- $sql = "SELECT emblem_len, emblem_data FROM $db.guild WHERE guild_id = ? LIMIT 1";
- $sth = $athenaServer->connection->getStatement($sql);
- $sth->execute(array($guildID));
- $res = $sth->fetch();
-
- if (!$res || !$res->emblem_len)
- flux_display_empty_emblem();
- else {
- require_once 'functions/imagecreatefrombmpstring.php';
-
- $data = @gzuncompress(pack('H*', $res->emblem_data));
- $image = imagecreatefrombmpstring($data);
+ if(Flux::config('EmblemUseWebservice')) {
+ $db = $athenaServer->webDatabase;
+ $sql = "SELECT file_type, file_data FROM $db.guild_emblems WHERE guild_id = ? LIMIT 1";
+ $sth = $athenaServer->connection->getStatementForWeb($sql);
+ $sth->execute(array($guildID));
+ $res = $sth->fetch();
- header("Content-Type: image/png");
-
- if ($interval)
- imagepng($image, $filename);
+ if (!$res->file_data)
+ flux_display_empty_emblem();
+ else {
+ $data = 'data:image/gif;base64,'.base64_encode($res->file_data);
+
+ if ($interval)
+ file_put_contents($filename, $res->file_data);
+
+ /* TODO; add gif animation at first image load */
+ $image = imagecreatefromstring($res->file_data);
+ header("Content-Type: image/png");
+ imagepng($image);
+ exit;
+ }
+ } else {
+ $db = $athenaServer->charMapDatabase;
+ $sql = "SELECT emblem_len, emblem_data FROM $db.guild WHERE guild_id = ? LIMIT 1";
+ $sth = $athenaServer->connection->getStatement($sql);
+ $sth->execute(array($guildID));
+ $res = $sth->fetch();
- imagepng($image);
- exit;
+ if (!$res || !$res->emblem_len)
+ flux_display_empty_emblem();
+ else {
+ require_once 'functions/imagecreatefrombmpstring.php';
+
+ $data = @gzuncompress(pack('H*', $res->emblem_data));
+ $image = imagecreatefrombmpstring($data);
+
+ header("Content-Type: image/png");
+
+ if ($interval)
+ imagepng($image, $filename);
+
+ imagepng($image);
+ exit;
+ }
}
}
?>
diff --git a/modules/guild/index.php b/modules/guild/index.php
index 636511d2e..9c8dc1dbd 100644
--- a/modules/guild/index.php
+++ b/modules/guild/index.php
@@ -83,8 +83,8 @@
$col = "guild.guild_id, guild.name AS guildName, guild.char_id AS charID, `char`.name AS charName, ";
$col .= "guild.guild_lv AS guildLevel, guild.connect_member AS connectMem, guild.max_member AS maxMem, ";
-$col .= "guild.average_lv AS avgLevel, guild.emblem_len ";
-
+$col .= "guild.average_lv AS avgLevel, guild.emblem_id as emblem ";
+
$sql = "SELECT $col FROM {$server->charMapDatabase}.`guild` $sqlpartial";
$sql = $paginator->getSQL($sql);
$sth = $server->connection->getStatement($sql);
diff --git a/modules/guild/view.php b/modules/guild/view.php
index 1a9cfe751..4dedf434b 100644
--- a/modules/guild/view.php
+++ b/modules/guild/view.php
@@ -19,9 +19,10 @@
$col = "guild.guild_id, guild.name, guild.char_id, guild.master, guild.guild_lv, guild.connect_member, guild.max_member, ";
$col .= "guild.average_lv, guild.exp, guild.next_exp, guild.skill_point, REPLACE(guild.mes1, '|00', '') AS mes1, REPLACE(guild.mes2, '|00', '') AS mes2, ";
-$col .= "guild.emblem_len, guild.emblem_id, guild.emblem_data, `char`.name AS guild_master";
+$col .= "guild.emblem_id as emblem, `char`.name AS guild_master ";
-$sql = "SELECT $col FROM {$server->charMapDatabase}.guild LEFT JOIN {$server->charMapDatabase}.`char` ON `char`.char_id = guild.char_id ";
+$sql = "SELECT $col FROM {$server->charMapDatabase}.guild ";
+$sql .= "LEFT JOIN {$server->charMapDatabase}.`char` ON `char`.char_id = guild.char_id ";
$sql .= "WHERE guild.guild_id = ?";
$sth = $server->connection->getStatement($sql);
@@ -100,7 +101,7 @@
$expulsions = $sth->fetchAll();
if (!Flux::config('GStorageLeaderOnly') || $amOwner || $auth->allowedToViewGuild) {
- $col = "guild_storage.*, items.name_japanese, items.type, items.slots, c.char_id, c.name AS char_name";
+ $col = "guild_storage.*, items.name_english, items.type, items.slots, c.char_id, c.name AS char_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.guild_storage ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.items ON items.id = guild_storage.nameid ";
@@ -149,23 +150,34 @@
if ($item->card0 == 254 || $item->card0 == 255 || $item->card0 == -256 || $item->cardsOver < 0) {
$item->cardsOver = 0;
}
+
+ if($server->isRenewal) {
+ $temp = array();
+ if ($item->option_id0) array_push($temp, array($item->option_id0, $item->option_val0));
+ if ($item->option_id1) array_push($temp, array($item->option_id1, $item->option_val1));
+ if ($item->option_id2) array_push($temp, array($item->option_id2, $item->option_val2));
+ if ($item->option_id3) array_push($temp, array($item->option_id3, $item->option_val3));
+ if ($item->option_id4) array_push($temp, array($item->option_id4, $item->option_val4));
+ $item->rndopt = $temp;
+ }
}
if ($cardIDs) {
$ids = implode(',', array_fill(0, count($cardIDs), '?'));
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
$sth = $server->connection->getStatement($sql);
$sth->execute($cardIDs);
$temp = $sth->fetchAll();
if ($temp) {
foreach ($temp as $card) {
- $cards[$card->id] = $card->name_japanese;
+ $cards[$card->id] = $card->name_english;
}
}
}
}
$itemAttributes = Flux::config('Attributes')->toArray();
+ $type_list = Flux::config('ItemTypes')->toArray();
}
?>
diff --git a/modules/install/index.php b/modules/install/index.php
index 4c0b6da1a..69b7ec666 100644
--- a/modules/install/index.php
+++ b/modules/install/index.php
@@ -6,6 +6,41 @@
// Force debug mode off here.
Flux::config('DebugMode', false);
+// Define minimum requirements.
+$requiredExtensions = array(
+ 'pdo',
+ 'pdo_mysql',
+ 'curl',
+ //'gd',
+ //'dom',
+ //'json',
+ //'mbstring',
+ //'zip',
+ 'xml',
+ 'xmlreader',
+ 'mysqli'
+);
+
+$minimumVersionCheck = [
+ 'php' => [
+ 'required' => '5.2.1',
+ 'recommended' => '8.0.0'
+ ],
+ 'mysql' => [
+ 'required' => '5.0.0',
+ 'recommended' => '5.6.2'
+ ]
+];
+$sth = $server->connection->getStatement("SELECT VERSION() AS mysql_version, CURRENT_USER() AS mysql_user");
+$sth->execute();
+$res = $sth->fetch();
+
+$permissionsChecks = [
+ FLUX_DATA_DIR.'/logs' => 'log storage',
+ FLUX_DATA_DIR.'/itemshop' => 'item shop image',
+ FLUX_DATA_DIR.'/tmp' => 'temporary'
+];
+
if ($session->installerAuth) {
if ($params->get('logout')) {
$session->setInstallerAuthData(false);
diff --git a/modules/item/add.php b/modules/item/add.php
deleted file mode 100644
index 3eae657a7..000000000
--- a/modules/item/add.php
+++ /dev/null
@@ -1,297 +0,0 @@
-get('item_id');
-$viewID = $params->get('view');
-$type = $params->get('type');
-$identifier = $params->get('name_english');
-$itemName = $params->get('name_japanese');
-$slots = $params->get('slots');
-$npcBuy = $params->get('npc_buy');
-$npcSell = $params->get('npc_sell');
-$weight = $params->get('weight');
-$attack = $params->get('attack');
-$matk = $params->get('matk');
-$defense = $params->get('defense');
-$range = $params->get('range');
-$weaponLevel = $params->get('weapon_level');
-$equipLevelMin = $params->get('equip_level_min');
-$equipLevelMax = $params->get('equip_level_max');
-$refineable = $params->get('refineable');
-$equipLocs = $params->get('equip_locations');
-$equipUpper = $params->get('equip_upper');
-$equipJobs = $params->get('equip_jobs');
-$equipMale = $params->get('equip_male');
-$equipFemale = $params->get('equip_female');
-$script = $params->get('script');
-$equipScript = $params->get('equip_script');
-$unequipScript = $params->get('unequip_script');
-
-// Weight is defaulted to an zero value.
-if (is_null($weight)) {
- $weight = 0;
-}
-
-if (count($_POST) && $params->get('additem')) {
- // Equip locations.
- if ($equipLocs instanceOf Flux_Config) {
- $equipLocs = $equipLocs->toArray();
- }
-
- // Equip upper.
- if ($equipUpper instanceOf Flux_Config) {
- $equipUpper = $equipUpper->toArray();
- }
-
- // Equip jobs.
- if ($equipJobs instanceOf Flux_Config) {
- $equipJobs = $equipJobs->toArray();
- }
-
- // Sanitize to NULL: viewid, slots, npcbuy, npcsell, weight, attack, defense, range, weaponlevel, equipLevelMin
- $nullables = array(
- 'viewID', 'slots', 'npcBuy', 'npcSell', 'weight', 'attack', 'defense',
- 'range', 'weaponLevel', 'equipLevelMin', 'script', 'equipScript', 'unequipScript'
- );
- // If renewal is enabled, sanitize matk and equipLevelMax to NULL
- if($server->isRenewal) {
- array_push($nullables, 'matk', 'equipLevelMax');
- }
- foreach ($nullables as $nullable) {
- if (trim($$nullable) == '') {
- $$nullable = null;
- }
- }
-
- // Refineable should be 1 or 0 if it's not null.
- if (!is_null($refineable)) {
- $refineable = intval((bool)$refineable);
- }
-
- if (!$itemID) {
- $errorMessage = 'You must specify an item ID.';
- }
- elseif (!ctype_digit($itemID)) {
- $errorMessage = 'Item ID must be a number.';
- }
- elseif (!is_null($viewID) && !ctype_digit($viewID)) {
- $errorMessage = 'View ID must be a number.';
- }
- elseif (!$identifier) {
- $errorMessage = 'You must specify an identifer.';
- }
- elseif (!$itemName) {
- $errorMessage = 'You must specify an item name.';
- }
- elseif (!is_null($slots) && !ctype_digit($slots)) {
- $errorMessage = 'Slots must be a number.';
- }
- elseif (!is_null($npcBuy) && !ctype_digit($npcBuy)) {
- $errorMessage = 'NPC buying price must be a number.';
- }
- elseif (!is_null($npcSell) && !ctype_digit($npcSell)) {
- $errorMessage = 'NPC selling price must be a number.';
- }
- elseif (!is_null($weight) && !ctype_digit($weight)) {
- $errorMessage = 'Weight must be a number.';
- }
- elseif (!is_null($attack) && !ctype_digit($attack)) {
- $errorMessage = 'Attack must be a number.';
- }
- elseif (!is_null($matk) && !ctype_digit($matk)) {
- $errorMessage = 'MATK must be a number.';
- }
- elseif (!is_null($defense) && !ctype_digit($defense)) {
- $errorMessage = 'Defense must be a number.';
- }
- elseif (!is_null($range) && !ctype_digit($range)) {
- $errorMessage = 'Range must be a number.';
- }
- elseif (!is_null($weaponLevel) && !ctype_digit($weaponLevel)) {
- $errorMessage = 'Weapon level must be a number.';
- }
- elseif (!is_null($equipLevelMin) && !ctype_digit($equipLevelMin)) {
- $errorMessage = 'Minimum equip level must be a number.';
- }
- elseif (!is_null($equipLevelMax) && !ctype_digit($equipLevelMax)) {
- $errorMessage = 'Maximum equip level must be a number.';
- }
- else {
- if (empty($errorMessage) && is_array($equipLocs)) {
- $locs = Flux::getEquipLocationList();
- foreach ($equipLocs as $bit) {
- if (!array_key_exists($bit, $locs)) {
- $errorMessage = 'Invalid equip location specified.';
- $equipLocs = null;
- break;
- }
- }
- }
- if (empty($errorMessage) && is_array($equipUpper)) {
- $upper = Flux::getEquipUpperList();
- foreach ($equipUpper as $bit) {
- if (!array_key_exists($bit, $upper)) {
- $errorMessage = 'Invalid equip upper specified.';
- $equipUpper = null;
- break;
- }
- }
- }
- if (empty($errorMessage) && is_array($equipJobs)) {
- $jobs = Flux::getEquipJobsList();
- foreach ($equipJobs as $bit) {
- if (!array_key_exists($bit, $jobs)) {
- $errorMessage = 'Invalid equippable job specified.';
- $equipJobs = null;
- break;
- }
- }
- }
- if (empty($errorMessage)) {
- require_once 'Flux/TemporaryTable.php';
-
- if($server->isRenewal) {
- $fromTables = array("{$server->charMapDatabase}.item_db_re", "{$server->charMapDatabase}.item_db2_re");
- $customTable = 'item_db2_re';
- } else {
- $fromTables = array("{$server->charMapDatabase}.item_db", "{$server->charMapDatabase}.item_db2");
- $customTable = 'item_db2';
- }
- $tableName = "{$server->charMapDatabase}.items";
- $tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
- $shopTable = Flux::config('FluxTables.ItemShopTable');
-
- $sth = $server->connection->getStatement("SELECT id, name_japanese, origin_table FROM $tableName WHERE id = ? LIMIT 1");
- $sth->execute(array($itemID));
-
- $item = $sth->fetch();
- if ($item && $item->id) {
- $errorMessage = 'An item already exists with that ID.';
- $errorMessage = sprintf($errorMessage, $item->name_japanese, $item->origin_table, $item->id);
- }
- else {
- $equipLevel = $equipLevelMin;
- if($server->isRenewal && !is_null($equipLevelMax)) {
- $equipLevel .= ':'. $equipLevelMax;
- }
-
- $cols = array('id', 'name_english', 'name_japanese', 'type', 'weight');
- $bind = array($itemID, $identifier, $itemName, $type, $weight*10);
- $vals = array(
- 'view' => $viewID,
- 'slots' => $slots,
- 'price_buy' => $npcBuy,
- 'price_sell' => $npcSell,
- 'defence' => $defense,
- '`range`' => $range,
- 'weapon_level' => $weaponLevel,
- 'equip_level' => $equipLevel,
- 'script' => $script,
- 'equip_script' => $equipScript,
- 'unequip_script' => $unequipScript,
- 'refineable' => $refineable
- );
-
- if($server->isRenewal) {
- if(!is_null($matk)) {
- $atk = $attack .':'. $matk;
- }
- else {
- $atk = $attack;
- }
- $vals = array_merge($vals, array(
- '`atk:matk`' => $atk
- ));
- }
- else {
- $vals = array_merge($vals, array(
- 'attack' => $attack
- ));
- }
-
- foreach ($vals as $col => $val) {
- if (!is_null($val)) {
- $cols[] = $col;
- $bind[] = $val;
- }
- }
-
- if ($equipLocs) {
- $bits = 0;
- foreach ($equipLocs as $bit) {
- $bits |= $bit;
- }
- $cols[] = 'equip_locations';
- $bind[] = $bits;
- }
-
- if ($equipUpper) {
- $bits = 0;
- foreach ($equipUpper as $bit) {
- $bits |= $bit;
- }
- $cols[] = 'equip_upper';
- $bind[] = $bits;
- }
-
- if ($equipJobs) {
- $bits = 0;
- foreach ($equipJobs as $bit) {
- $bits |= $bit;
- }
- $cols[] = 'equip_jobs';
- $bind[] = $bits;
- }
-
- $gender = null;
- if ($equipMale && $equipFemale) {
- $gender = 2;
- }
- elseif ($equipMale) {
- $gender = 1;
- }
- elseif ($equipFemale) {
- $gender = 0;
- }
-
- if (!is_null($gender)) {
- $cols[] = 'equip_genders';
- $bind[] = $gender;
- }
-
- $sql = "INSERT INTO {$server->charMapDatabase}.{$customTable} (".implode(', ', $cols).") ";
- $sql .= "VALUES (".implode(', ', array_fill(0, count($bind), '?')).")";
- $sth = $server->connection->getStatement($sql);
-
- if ($sth->execute($bind)) {
- $session->setMessageData("Your item '$itemName' ($itemID) has been successfully added!");
-
- if ($auth->actionAllowed('item', 'view')) {
- $this->redirect($this->url('item', 'view', array('id' => $itemID)));
- }
- else {
- $this->redirect();
- }
- }
- else {
- $errorMessage = 'Failed to add item!';
- }
- }
- }
- }
-}
-
-if (!is_array($equipLocs)) {
- $equipLocs = array();
-}
-if (!is_array($equipUpper)) {
- $equipUpper = array();
-}
-if (!is_array($equipJobs)) {
- $equipJobs = array();
-}
-?>
diff --git a/modules/item/copy.php b/modules/item/copy.php
deleted file mode 100644
index 76f100be2..000000000
--- a/modules/item/copy.php
+++ /dev/null
@@ -1,93 +0,0 @@
-get('id');
-if (!$itemID) {
- $this->deny();
-}
-
-$title = 'Duplicate Item';
-
-require_once 'Flux/TemporaryTable.php';
-
-if($server->isRenewal) {
- $fromTables = array("{$server->charMapDatabase}.item_db_re", "{$server->charMapDatabase}.item_db2_re");
- $customTable = 'item_db2_re';
-} else {
- $fromTables = array("{$server->charMapDatabase}.item_db", "{$server->charMapDatabase}.item_db2");
- $customTable = 'item_db2';
-}
-$tableName = "{$server->charMapDatabase}.items";
-$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
-
-$col = "name_english, name_japanese, type, price_buy, price_sell, ";
-$col .= "weight, defence, `range`, slots, equip_jobs, equip_upper, ";
-$col .= "equip_genders, equip_locations, weapon_level, equip_level, refineable, ";
-$col .= "view, script, equip_script, unequip_script, ";
-$col .= ($server->isRenewal) ? "`atk:matk` AS attack" : "attack";
-
-$sql = "SELECT $col FROM $tableName WHERE id = ? LIMIT 1";
-$sth = $server->connection->getStatement($sql);
-$sth->execute(array($itemID));
-
-$item = $sth->fetch();
-
-if ($item) {
- $title = "Duplicate Item ({$item->name_japanese}: #$itemID)";
-}
-
-if ($item && count($_POST) && $params->get('copyitem')) {
- $isCustom = preg_match('/item_db2$/', $item->origin_table) ? true : false;
- $copyID = trim($params->get('new_item_id'));
-
- if (!$copyID) {
- $errorMessage = 'You must specify a duplicate item ID.';
- }
- elseif (!ctype_digit($copyID)) {
- $errorMessage = 'Duplicate item ID must be a number.';
- }
- else {
- $sql = "SELECT COUNT(id) AS itemExists FROM {$server->charMapDatabase}.{$customTable} WHERE id = ?";
- $sth = $server->connection->getStatement($sql);
- $res = $sth->execute(array($copyID));
-
- if ($res && $sth->fetch()->itemExists) {
- $errorMessage = 'An item with that ID already exists in '.$customTable.'.';
- }
- else {
- $col = "id, name_english, name_japanese, type, price_buy, price_sell, ";
- $col .= "weight, defence, `range`, slots, equip_jobs, equip_upper, ";
- $col .= "equip_genders, equip_locations, weapon_level, equip_level, refineable, ";
- $col .= "view, script, equip_script, unequip_script, ";
- $col .= ($server->isRenewal) ? "`atk:matk`" : "attack";
- $neweng = $item->name_english.$copyID;
- $newjap = $item->name_japanese.$copyID;
-
- $bind = array(
- $copyID, $neweng, $newjap, $item->type, $item->price_buy, $item->price_sell,
- $item->weight, $item->defence, $item->range, $item->slots, $item->equip_jobs, $item->equip_upper,
- $item->equip_genders, $item->equip_locations, $item->weapon_level, $item->equip_level, $item->refineable,
- $item->view, $item->script, $item->equip_script, $item->unequip_script, $item->attack
- );
-
- $sql = "INSERT INTO {$server->charMapDatabase}.{$customTable} ($col) VALUES (".implode(',', array_fill(0, count($bind), '?')).")";
- $sth = $server->connection->getStatement($sql);
- $res = $sth->execute($bind);
-
- if ($res) {
- $session->setMessageData("Item has been duplicated as #$copyID!");
-
- if ($auth->actionAllowed('item', 'view')) {
- $this->redirect($this->url('item', 'view', array('id' => $copyID)));
- }
- else {
- $this->redirect();
- }
- }
- else {
- $errorMessage = 'Failed to duplicate item.';
- }
- }
- }
-}
-?>
diff --git a/modules/item/edit.php b/modules/item/edit.php
deleted file mode 100644
index 2f6737ccb..000000000
--- a/modules/item/edit.php
+++ /dev/null
@@ -1,334 +0,0 @@
-isRenewal) {
- $fromTables = array("{$server->charMapDatabase}.item_db_re", "{$server->charMapDatabase}.item_db2_re");
- $customTable = 'item_db2_re';
-} else {
- $fromTables = array("{$server->charMapDatabase}.item_db", "{$server->charMapDatabase}.item_db2");
- $customTable = 'item_db2';
-}
-$tableName = "{$server->charMapDatabase}.items";
-$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
-
-$title = 'Modify Item';
-
-$itemID = $params->get('id');
-
-if (!$itemID) {
- $this->deny();
-}
-
-$col = "id, view, type, name_english, name_japanese, slots, price_buy, price_sell, weight/10 AS weight, ";
-$col .= "defence, `range`, weapon_level, equip_level AS equip_level_min, refineable, equip_locations, equip_upper, ";
-$col .= "equip_jobs, equip_genders, script, equip_script, unequip_script, origin_table, ";
-$col .= $server->isRenewal ? '`atk:matk` AS attack' : 'attack';
-$sql = "SELECT $col FROM $tableName WHERE id = ? LIMIT 1";
-$sth = $server->connection->getStatement($sql);
-$sth->execute(array($itemID));
-
-$item = $sth->fetch();
-
-// Check if item exists, first.
-if ($item) {
- $isCustom = preg_match('/item_db2$/', $item->origin_table) ? true : false;
-
- if ($params->get('edititem')) {
- $viewID = $params->get('view');
- $type = $params->get('type');
- $identifier = $params->get('name_english');
- $itemName = $params->get('name_japanese');
- $slots = $params->get('slots');
- $npcBuy = $params->get('npc_buy');
- $npcSell = $params->get('npc_sell');
- $weight = $params->get('weight');
- $attack = $params->get('attack');
- $matk = $params->get('matk');
- $defense = $params->get('defense');
- $range = $params->get('range');
- $weaponLevel = $params->get('weapon_level');
- $equipLevelMin = $params->get('equip_level_min');
- $equipLevelMax = $params->get('equip_level_max');
- $refineable = $params->get('refineable');
- $equipLoc = $params->get('equip_locations');
-
- if (count($typeSplit = explode('-', $type)) == 2) {
- $type = $typeSplit[0];
- $viewID = $typeSplit[1];
- }
- }
- else {
- $viewID = $item->view;
- $type = $item->type;
- $identifier = $item->name_english;
- $itemName = $item->name_japanese;
- $slots = $item->slots;
- $npcBuy = $item->price_buy;
- $npcSell = $item->price_sell;
- $weight = $item->weight;
- $defense = $item->defence;
- $range = $item->range;
- $weaponLevel = $item->weapon_level;
- $refineable = $item->refineable;
- $equipLoc = $item->equip_locations;
-
- if($server->isRenewal) {
- $item = $this->itemFieldExplode($item, 'attack', ':', array('attack','matk'));
- $item = $this->itemFieldExplode($item, 'equip_level_min', ':', array('equip_level_min','equip_level_max'));
-
- $matk = $item->matk;
- $equipLevelMax = $item->equip_level_max;
- }
-
- $attack = $item->attack;
- $equipLevelMin = $item->equip_level_min;
- }
- if ($item->equip_upper) {
- $item->equip_upper = Flux::equipUpperToArray($item->equip_upper);
- }
- if ($item->equip_jobs) {
- $item->equip_jobs = Flux::equipJobsToArray($item->equip_jobs);
- }
-
- $equipUpper = $params->get('equip_upper') ? $params->get('equip_upper') : $item->equip_upper;
- $equipJobs = $params->get('equip_jobs') ? $params->get('equip_jobs') : $item->equip_jobs;
-
- $equipMale = $params->get('edititem') ? ($params->get('equip_male') ? true : false) : ($item->equip_genders == 2 || $item->equip_genders == 1 ? true : false);
- $equipFemale = $params->get('edititem') ? ($params->get('equip_female') ? true : false) : ($item->equip_genders == 2 || $item->equip_genders == 0 ? true : false);
-
- $script = $params->get('script') ? $params->get('script') : $item->script;
- $equipScript = $params->get('equip_script') ? $params->get('equip_script') : $item->equip_script;
- $unequipScript = $params->get('unequip_script') ? $params->get('unequip_script') : $item->unequip_script;
-
- // Equip upper.
- if ($equipUpper instanceOf Flux_Config) {
- $equipUpper = $equipUpper->toArray();
- }
-
- // Equip jobs.
- if ($equipJobs instanceOf Flux_Config) {
- $equipJobs = $equipJobs->toArray();
- }
-
- if (!is_array($equipUpper)) {
- $equipUpper = array();
- }
- if (!is_array($equipJobs)) {
- $equipJobs = array();
- }
-
- if (count($_POST) && $params->get('edititem')) {
- // Sanitize to NULL: viewid, slots, npcbuy, npcsell, weight, attack, defense, range, weaponlevel, equiplevel
- $nullables = array(
- 'viewID', 'slots', 'npcBuy', 'npcSell', 'weight', 'attack', 'defense',
- 'range', 'weaponLevel', 'equipLevelMin', 'script', 'equipScript', 'unequipScript'
- );
- // If renewal is enabled, sanitize matk and equipLevelMax to NULL
- if($server->isRenewal) {
- array_push($nullables, 'matk', 'equipLevelMax');
- }
- foreach ($nullables as $nullable) {
- if (trim($$nullable) == '') {
- $$nullable = null;
- }
- }
-
- // Weight is defaulted to an zero value.
- if (is_null($weight)) {
- $weight = 0;
- }
-
- // Refineable should be 1 or 0 if it's not null.
- if (!is_null($refineable)) {
- $refineable = intval((bool)$refineable);
- }
-
- if (!$itemID) {
- $errorMessage = 'You must specify an item ID.';
- }
- elseif (!ctype_digit($itemID)) {
- $errorMessage = 'Item ID must be a number.';
- }
- elseif (!is_null($viewID) && !ctype_digit($viewID)) {
- $errorMessage = 'View ID must be a number.';
- }
- elseif (!$identifier) {
- $errorMessage = 'You must specify an identifer.';
- }
- elseif (!$itemName) {
- $errorMessage = 'You must specify an item name.';
- }
- elseif (!is_null($slots) && !ctype_digit($slots)) {
- $errorMessage = 'Slots must be a number.';
- }
- elseif (!is_null($npcBuy) && !ctype_digit($npcBuy)) {
- $errorMessage = 'NPC buying price must be a number.';
- }
- elseif (!is_null($npcSell) && !ctype_digit($npcSell)) {
- $errorMessage = 'NPC selling price must be a number.';
- }
- elseif (!is_null($weight) && !ctype_digit($weight)) {
- $errorMessage = 'Weight must be a number.';
- }
- elseif (!is_null($attack) && !ctype_digit($attack)) {
- $errorMessage = 'Attack must be a number.';
- }
- elseif (!is_null($matk) && !ctype_digit($matk)) {
- $errorMessage = 'MATK must be a number.';
- }
- elseif (!is_null($defense) && !ctype_digit($defense)) {
- $errorMessage = 'Defense must be a number.';
- }
- elseif (!is_null($range) && !ctype_digit($range)) {
- $errorMessage = 'Range must be a number.';
- }
- elseif (!is_null($weaponLevel) && !ctype_digit($weaponLevel)) {
- $errorMessage = 'Weapon level must be a number.';
- }
- elseif (!is_null($equipLevelMin) && !ctype_digit($equipLevelMin)) {
- $errorMessage = 'Minimum equip level must be a number.';
- }
- elseif (!is_null($equipLevelMax) && !ctype_digit($equipLevelMax)) {
- $errorMessage = 'Maximum equip level must be a number.';
- }
- else {
- if (empty($errorMessage) && is_array($equipUpper)) {
- $upper = Flux::getEquipUpperList();
- foreach ($equipUpper as $bit) {
- if (!array_key_exists($bit, $upper)) {
- $errorMessage = 'Invalid equip upper specified.';
- $equipUpper = null;
- break;
- }
- }
- }
- if (empty($errorMessage) && is_array($equipJobs)) {
- $jobs = Flux::getEquipJobsList();
- foreach ($equipJobs as $bit) {
- if (!array_key_exists($bit, $jobs)) {
- $errorMessage = 'Invalid equippable job specified.';
- $equipJobs = null;
- break;
- }
- }
- }
- if (empty($errorMessage)) {
- $equipLevel = $equipLevelMin;
- if($server->isRenewal && !is_null($equipLevelMax)) {
- $equipLevel .= ':'. $equipLevelMax;
- }
-
- $cols = array('id', 'name_english', 'name_japanese', 'type', 'weight', 'equip_locations');
- $bind = array($itemID, $identifier, $itemName, $type, $weight*10, $equipLoc);
- $vals = array(
- 'view' => $viewID,
- 'slots' => $slots,
- 'price_buy' => $npcBuy,
- 'price_sell' => $npcSell,
- 'defence' => $defense,
- '`range`' => $range,
- 'weapon_level' => $weaponLevel,
- 'equip_level' => $equipLevel,
- 'script' => $script,
- 'equip_script' => $equipScript,
- 'unequip_script' => $unequipScript,
- 'refineable' => $refineable
- );
-
- if($server->isRenewal) {
- if(!is_null($matk)) {
- $atk = $attack .':'. $matk;
- }
- else {
- $atk = $attack;
- }
- $vals = array_merge($vals, array(
- '`atk:matk`' => $atk
- ));
- }
- else {
- $vals = array_merge($vals, array(
- 'attack' => $attack
- ));
- }
-
- foreach ($vals as $col => $val) {
- $cols[] = $col;
- $bind[] = $val;
- }
-
- if ($equipUpper) {
- $bits = 0;
- foreach ($equipUpper as $bit) {
- $bits |= $bit;
- }
- $cols[] = 'equip_upper';
- $bind[] = $bits;
- }
-
- if ($equipJobs) {
- $bits = 0;
- foreach ($equipJobs as $bit) {
- $bits |= $bit;
- }
- $cols[] = 'equip_jobs';
- $bind[] = $bits;
- }
-
- $gender = null;
- if ($equipMale && $equipFemale) {
- $gender = 2;
- }
- elseif ($equipMale) {
- $gender = 1;
- }
- elseif ($equipFemale) {
- $gender = 0;
- }
-
- if (!is_null($gender)) {
- $cols[] = 'equip_genders';
- $bind[] = $gender;
- }
-
- if ($isCustom) {
- $set = array();
- foreach ($cols as $i => $col) {
- $set[] = "$col = ?";
- }
-
- $sql = "UPDATE {$server->charMapDatabase}.{$customTable} SET ";
- $sql .= implode($set, ', ');
- $sql .= " WHERE id = ?";
-
- $bind[] = $itemID;
- }
- else {
- $sql = "INSERT INTO {$server->charMapDatabase}.{$customTable} (".implode(', ', $cols).") ";
- $sql .= "VALUES (".implode(', ', array_fill(0, count($bind), '?')).")";
- }
-
- $sth = $server->connection->getStatement($sql);
- if ($sth->execute($bind)) {
- $session->setMessageData("Your item '$itemName' ($itemID) has been successfully modified!");
-
- if ($auth->actionAllowed('item', 'view')) {
- $this->redirect($this->url('item', 'view', array('id' => $itemID)));
- }
- else {
- $this->redirect();
- }
- }
- else {
- $errorMessage = 'Failed to modify item!';
- }
- }
- }
- }
-}
-
-
-?>
diff --git a/modules/item/index.php b/modules/item/index.php
index bdf41bd19..bbae5fb34 100644
--- a/modules/item/index.php
+++ b/modules/item/index.php
@@ -5,6 +5,8 @@
require_once 'Flux/TemporaryTable.php';
+$equip_list = array_keys(Flux::config('EquipLocations')->toArray());
+
try {
if($server->isRenewal) {
$fromTables = array("{$server->charMapDatabase}.item_db_re", "{$server->charMapDatabase}.item_db2_re");
@@ -50,7 +52,7 @@
$custom = $params->get('custom');
if ($itemName) {
- $sqlpartial .= "AND (name_japanese LIKE ? OR name_japanese = ?) ";
+ $sqlpartial .= "AND (name_english LIKE ? OR name_english = ?) ";
$bind[] = "%$itemName%";
$bind[] = $itemName;
}
@@ -60,7 +62,7 @@
$itemType = $itemTypeSplit[0];
$itemType2 = $itemTypeSplit[1];
}
- if (is_numeric($itemType) && (floatval($itemType) == intval($itemType))) {
+ if ($itemType) {
$itemTypes = Flux::config('ItemTypes')->toArray();
if (array_key_exists($itemType, $itemTypes) && $itemTypes[$itemType]) {
$sqlpartial .= "AND type = ? ";
@@ -69,13 +71,13 @@
$sqlpartial .= 'AND type IS NULL ';
}
- if (count($itemTypeSplit) == 2 && is_numeric($itemType2) && (floatval($itemType2) == intval($itemType2))) {
- $itemTypes2 = Flux::config('ItemTypes2')->toArray();
+ if (count($itemTypeSplit) == 2 && $itemType2) {
+ $itemTypes2 = Flux::config('ItemSubTypes')->toArray();
if (array_key_exists($itemType, $itemTypes2) && array_key_exists($itemType2, $itemTypes2[$itemType]) && $itemTypes2[$itemType][$itemType2]) {
- $sqlpartial .= "AND view = ? ";
+ $sqlpartial .= "AND subtype = ? ";
$bind[] = $itemType2;
} else {
- $sqlpartial .= 'AND view IS NULL ';
+ $sqlpartial .= 'AND subtype IS NULL ';
}
}
} else {
@@ -100,38 +102,19 @@
}
}
- if ($equipLoc !== false && $equipLoc !== '-1') {
- if(is_numeric($equipLoc) && (floatval($equipLoc) == intval($equipLoc))) {
- $equipLocationCombinations = Flux::config('EquipLocationCombinations')->toArray();
- if (array_key_exists($equipLoc, $equipLocationCombinations) && $equipLocationCombinations[$equipLoc]) {
+ if ($equipLoc !== false && !is_null($equipLoc) && $equipLoc !== '-1') {
+ $equipLocs = explode('/', $equipLoc);
+
+ if($equipLoc && count($equipLocs) == 1) {
+ $equipLocations = Flux::config('EquipLocations')->toArray();
+ if (array_key_exists($equipLoc, $equipLocations) && $equipLocations[$equipLoc]) {
if ($equipLoc === '0') {
- $sqlpartial .= "AND (equip_locations = 0 OR equip_locations IS NULL) ";
+ $sqlpartial .= "AND ($equipLoc = 0 OR $equipLoc IS NULL) ";
} else {
- $sqlpartial .= "AND equip_locations = ? ";
- $bind[] = $equipLoc;
+ $sqlpartial .= "AND $equipLoc = ? ";
+ $bind[] = 1;
}
}
- } else {
- $combinationName = preg_quote($equipLoc, '/');
- $equipLocationCombinations = preg_grep("/.*?$combinationName.*?/i", Flux::config('EquipLocationCombinations')->toArray());
-
- if (count($equipLocationCombinations)) {
- $equipLocationCombinations = array_keys($equipLocationCombinations);
- $sqlpartial .= "AND (";
- $partial = '';
-
- foreach ($equipLocationCombinations as $id) {
- if ($id === 0) {
- $partial .= "(equip_locations = 0 OR equip_locations IS NULL) OR ";
- } else {
- $partial .= "equip_locations = ? OR ";
- $bind[] = $id;
- }
- }
-
- $partial = preg_replace('/\s*OR\s*$/', '', $partial);
- $sqlpartial .= "$partial) ";
- }
}
}
@@ -182,10 +165,10 @@
if (in_array($defenseOp, $opValues) && trim($defense) != '') {
$op = $opMapping[$defenseOp];
if ($op == '=' && $defense === '0') {
- $sqlpartial .= "AND (defence IS NULL OR defence = 0) ";
+ $sqlpartial .= "AND (defense IS NULL OR defense = 0) ";
}
else {
- $sqlpartial .= "AND defence $op ? ";
+ $sqlpartial .= "AND defense $op ? ";
$bind[] = $defense;
}
}
@@ -246,19 +229,21 @@
$paginator = $this->getPaginator($sth->fetch()->total);
$sortable = array(
- 'item_id' => 'asc', 'name', 'type', 'equip_locations', 'price_buy', 'price_sell', 'weight',
- 'defense', 'range', 'slots', 'refineable', 'cost', 'origin_table'
+ 'item_id' => 'asc', 'name', 'type', 'subtype', 'price_buy', 'price_sell', 'weight',
+ 'attack', 'defense', 'range', 'slots', 'refineable', 'cost', 'origin_table'
);
- if(!$server->isRenewal) {
- $sortable[] = 'attack';
+ if($server->isRenewal) {
+ $sortable[] = 'magic_attack';
}
$paginator->setSortableColumns($sortable);
- $col = "origin_table, items.id AS item_id, name_japanese AS name, type, ";
- $col .= "IFNULL(equip_locations, 0) AS equip_locations, price_buy, weight/10 AS weight, ";
- $col .= "defence AS defense, `range`, slots, refineable, cost, $shopTable.id AS shop_item_id, ";
- $col .= "IFNULL(price_sell, FLOOR(price_buy/2)) AS price_sell, view, ";
- $col .= ($server->isRenewal) ? "`atk:matk` AS attack" : "attack";
+ $col = "items.id AS item_id, name_english AS name, type, subtype, ";
+ $col .= "price_buy, weight/10 AS weight, ";
+ $col .= "defense, `range`, slots, refineable, cost, $shopTable.id AS shop_item_id, ";
+ $col .= "IFNULL(price_sell, FLOOR(price_buy/2)) AS price_sell, view, attack, ";
+ $col .= implode(', ', $equip_list).', ';
+ if($server->isRenewal) $col .= 'magic_attack, ';
+ $col .= "origin_table";
$sql = $paginator->getSQL("SELECT $col FROM $tableName $sqlpartial GROUP BY items.id, $shopTable.id");
$sth = $server->connection->getStatement($sql);
@@ -268,6 +253,14 @@
$authorized = $auth->actionAllowed('item', 'view');
+ foreach ($items as $item) {
+ // Equip location
+ $equip_location = array();
+ $item->equip_location = array();
+ foreach($equip_list as $eq_loc) if($item->$eq_loc) $equip_location[] = $eq_loc;
+ $item->equip_location = $equip_location;
+ }
+
if ($items && count($items) === 1 && $authorized && Flux::config('SingleMatchRedirectItem')) {
$this->redirect($this->url('item', 'view', array('id' => $items[0]->item_id)));
}
diff --git a/modules/item/iteminfo.php b/modules/item/iteminfo.php
index 3b7ae58b8..06c6db2ba 100644
--- a/modules/item/iteminfo.php
+++ b/modules/item/iteminfo.php
@@ -14,43 +14,89 @@
if($fp){ $array = explode("\n", fread($fp, filesize($itemInfo))); }
fclose($fp);
$ca = count($array);
- $check = false;
+ $check = false; // True: execute query
+ $checkingdesc = false;
+ $desccomplete = false;
+ $last_setid = 0;
+ $desc = '';
+ $setid = 0;
+ $first = true;
+
for($i=0; $i < $ca; $i++){
- switch($array[$i]){
- case (preg_match('/\s{2,}unident/', $array[$i]) ? true : false):
- break;
- case (preg_match('/\s([\[])([0-9]{1,})([\]]) = {/', $array[$i]) ? true : false):
- $setid = preg_replace('/\s([\[])([0-9]{1,})([\]]) = {/', '$2', $array[$i]);
- break;
- case (preg_match('/\sidentifiedDescriptionName = {$/', $array[$i]) ? true : false):
- $sql="REPLACE INTO {$server->charMapDatabase}.$itemDescTable (`itemid`, `itemdesc`) VALUES ('$setid','";
+ // Item ID
+ if (preg_match('/\[(\d+)\]/', $array[$i], $matches)) {
+ if ($first) {
+ $setid = $matches[1];
+ $first = false;
+ continue;
+ }
+ if ($setid != $matches[1] && $checkingdesc) {
+ $itemid = $setid;
+ $desccomplete = true;
$check = true;
- break;
- case 'identifiedDescriptionName = {},':
- if($check == true){
- $sql.="');";
- $sth = $server->connection->getStatement($sql);
- $sth->execute();
- $check = false;
- }
- break;
- case (preg_match('/(.*?)(\")(.*?)(\^)([0-9a-fA-F]{6})(.*?)(\^0{6})(.*?)\"(,?)/', $array[$i]) ? true : false):
- $array[$i] = preg_replace('/(.*?)(\")(.*?)(\^)([0-9a-fA-F]{6})(.*?)(\^0{6})(.*?)\"(,?)/', '$3$6$8
', $array[$i]);
- case (preg_match('/\s{2,}(\")(.*?)\"(,?)/', $array[$i]) ? true : false):
- if($check == true){
- $sqlp = preg_replace('/\s{2,}(\")(.*?)\"(,?)/', '$2
', $array[$i]);
- $sql.= addslashes($sqlp);
- }
- break;
- case (preg_match('/\s{2,}},/', $array[$i]) ? true : false):
- if($check == true){
- $sql.="');";
- $sth = $server->connection->getStatement($sql);
- $sth->execute();
- $check = false;
+ }
+ $setid = $matches[1];
+ }
+
+ // Description Inline type
+ // identifiedDescriptionName = { "desc1", "desc2" },
+ if (preg_match('/^identifiedDescriptionName[ ]=[ ]\{(.*)\},/', $array[$i], $matches)) {
+ $tmp = trim($matches[1]);
+ $tmp = substr($tmp,0,strpos($tmp,"},"));
+ $str = preg_split('/(",|"$)/', $tmp);
+ foreach ($str as $x => $de) {
+ $de = trim($de);
+ $p = strtok($de,'"'); // Remove first quote
+ $desc .= $p."
";
+ }
+ $check = true;
+ $desccomplete = true;
+ }
+
+ // Description Multiline type
+ // identifiedDescriptionName = {
+ // "desc1",
+ // "desc2"
+ // },
+ if (!$desccomplete && preg_match('/([ \s]+|^)identifiedDescriptionName[ ]=[ ]\{[\r\n]*/', $array[$i])) {
+ $checkingdesc = true;
+ }
+ if ($checkingdesc && preg_match('/"(.*)(",{0,1})[\r\n]*/', $array[$i], $matches)) {
+ $tmp = trim($matches[1]);
+ $desc .= $tmp;
+ if ($matches[2] == '",')
+ $desc .= "
";
+ }
+
+ if ($check) {
+ $newdesc = '';
+ $hasColor = false;
+ $p = strtok($desc, "^");
+ while ($p) {
+ if (preg_match('/([\dA-Fa-f]{6})/', $p, $matches)) {
+ if ($hasColor)
+ $newdesc .= "";
+ if ($matches[1] != '000000') {
+ $newdesc .= "";
+ $hasColor = true;
+ }
+ else
+ $hasColor = false;
+ $newdesc .= substr($p,6,strlen($p));
}
- default:
- break;
+ else
+ $newdesc .= $p;
+ $p = strtok("^");
+ }
+ if ($hasColor)
+ $newdesc .= "";
+ $sql = "REPLACE INTO {$server->charMapDatabase}.$itemDescTable (`itemid`, `itemdesc`) VALUES ('".($checkingdesc ? $itemid : $setid)."','".addslashes($newdesc)."')";
+ $sth = $server->connection->getStatement($sql);
+ $sth->execute();
+ $desc = '';
+ $check = false;
+ $checkingdesc = false;
+ $desccomplete = false;
}
}
$fileLoad->delete();
diff --git a/modules/item/pagemenu/view.php b/modules/item/pagemenu/view.php
index cb66c7d13..3c2d237a0 100644
--- a/modules/item/pagemenu/view.php
+++ b/modules/item/pagemenu/view.php
@@ -1,11 +1,5 @@
actionAllowed('item', 'edit')) {
- $pageMenu['Modify Item'] = $this->url('item', 'edit', array('id' => $item->item_id));
-}
-if ($auth->actionAllowed('item', 'copy')) {
- $pageMenu['Duplicate Item'] = $this->url('item', 'copy', array('id' => $item->item_id));
-}
if ($auth->actionAllowed('itemshop', 'add') && $auth->allowedToAddShopItem) {
if ($item->cost) {
$pageMenu['Add to Item Shop (Again)'] = $this->url('itemshop', 'add', array('id' => $item->item_id));
diff --git a/modules/item/view.php b/modules/item/view.php
index b1ed425ec..c76316156 100644
--- a/modules/item/view.php
+++ b/modules/item/view.php
@@ -17,17 +17,27 @@
$itemID = $params->get('id');
-$col = 'items.id AS item_id, name_english AS identifier, ';
-$col .= 'name_japanese AS name, type, ';
-$col .= 'price_buy, price_sell, weight/10 AS weight, defence, `range`, slots, ';
-$col .= 'equip_jobs, equip_upper, equip_genders, equip_locations, ';
-$col .= 'weapon_level, equip_level AS equip_level_min, refineable, view, script, ';
-$col .= 'equip_script, unequip_script, origin_table, ';
+$job_list = array_keys($this->GetJobsList($server->isRenewal));
+$class_list = array_keys($this->GetClassList($server->isRenewal));
+$equip_list = array_keys(Flux::config('EquipLocations')->toArray());
+$trade_list = array_keys(Flux::config('TradeRestriction')->toArray());
+
+$col = 'items.id AS item_id, name_aegis AS identifier, ';
+$col .= 'name_english AS name, type, subtype, ';
+$col .= 'price_buy, price_sell, weight/10 AS weight, attack, defense, `range`, slots, gender, ';
+$col .= 'weapon_level, equip_level_min, equip_level_max, refineable, view, alias_name, ';
+$col .= 'script, equip_script, unequip_script, origin_table, ';
+$col .= implode(', ', $job_list).', '; // Job list
+$col .= implode(', ', $class_list).', '; // Class list
+$col .= implode(', ', $equip_list).', ';
+$col .= implode(', ', $trade_list).', '; // Trade restriction list
+
$col .= "$shopTable.cost, $shopTable.id AS shop_item_id, ";
if(Flux::config('ShowItemDesc')){
$col .= 'itemdesc, ';
}
-$col .= $server->isRenewal ? '`atk:matk` AS attack' : 'attack';
+if($server->isRenewal) $col .= 'magic_attack, ';
+$col .= 'origin_table';
$sql = "SELECT $col FROM {$server->charMapDatabase}.items ";
$sql .= "LEFT OUTER JOIN {$server->charMapDatabase}.$shopTable ON $shopTable.nameid = items.id ";
@@ -46,10 +56,18 @@
$title = "Viewing Item ($item->name)";
$isCustom = (bool)preg_match('/item_db2$/', $item->origin_table);
- if($server->isRenewal) {
- $item = $this->itemFieldExplode($item, 'attack', ':', array('attack','matk'));
- $item = $this->itemFieldExplode($item, 'equip_level_min', ':', array('equip_level_min','equip_level_max'));
- }
+ // Jobs
+ $jobs = array();
+ foreach($job_list as $job) if($item->$job) $jobs[] = $job;
+ // Classes
+ $upper = array();
+ foreach($class_list as $class) if($item->$class) $upper[] = $class;
+ // Equip location
+ $equip_locs = array();
+ foreach($equip_list as $eq_loc) if($item->$eq_loc) $equip_locs[] = $eq_loc;
+ // Trade restrictions
+ $restrictions = array();
+ foreach($trade_list as $trade) if($item->$trade) $restrictions[] = $trade;
$mobDB = "{$server->charMapDatabase}.monsters";
if($server->isRenewal) {
@@ -59,125 +77,146 @@
}
$mobTable = new Flux_TemporaryTable($server->connection, $mobDB, $fromTables);
- $col = 'ID AS monster_id, iName AS monster_name, LV AS monster_level, ';
- $col .= 'Race AS monster_race, (Element%10) AS monster_element, (Element/20) AS monster_ele_lv, MEXP AS mvp_exp, ';
+ $col = 'id AS monster_id, name_english AS monster_name, level AS monster_level, ';
+ $col .= 'race AS monster_race, element AS monster_element, element_level AS monster_ele_lv, mvp_exp, `class` as boss, mode_mvp, ';
// Normal drops.
- $col .= 'Drop1id AS drop1_id, Drop1per AS drop1_chance, ';
- $col .= 'Drop2id AS drop2_id, Drop2per AS drop2_chance, ';
- $col .= 'Drop3id AS drop3_id, Drop3per AS drop3_chance, ';
- $col .= 'Drop4id AS drop4_id, Drop4per AS drop4_chance, ';
- $col .= 'Drop5id AS drop5_id, Drop5per AS drop5_chance, ';
- $col .= 'Drop6id AS drop6_id, Drop6per AS drop6_chance, ';
- $col .= 'Drop7id AS drop7_id, Drop7per AS drop7_chance, ';
- $col .= 'Drop8id AS drop8_id, Drop8per AS drop8_chance, ';
- $col .= 'Drop9id AS drop9_id, Drop9per AS drop9_chance, ';
-
- // Card drops.
- $col .= 'DropCardid AS dropcard_id, DropCardper AS dropcard_chance, ';
+ $col .= 'drop1_item, drop1_rate, drop1_nosteal, drop1_option, drop1_index, ';
+ $col .= 'drop2_item, drop2_rate, drop2_nosteal, drop2_option, drop2_index, ';
+ $col .= 'drop3_item, drop3_rate, drop3_nosteal, drop3_option, drop3_index, ';
+ $col .= 'drop4_item, drop4_rate, drop4_nosteal, drop4_option, drop4_index, ';
+ $col .= 'drop5_item, drop5_rate, drop5_nosteal, drop5_option, drop5_index, ';
+ $col .= 'drop6_item, drop6_rate, drop6_nosteal, drop6_option, drop6_index, ';
+ $col .= 'drop7_item, drop7_rate, drop7_nosteal, drop7_option, drop7_index, ';
+ $col .= 'drop8_item, drop8_rate, drop8_nosteal, drop8_option, drop8_index, ';
+ $col .= 'drop9_item, drop9_rate, drop9_nosteal, drop9_option, drop9_index, ';
+ $col .= 'drop10_item, drop10_rate, drop10_nosteal, drop10_option, drop10_index, ';
// MVP rewards.
- $col .= 'MVP1id AS mvpdrop1_id, MVP1per AS mvpdrop1_chance, ';
- $col .= 'MVP2id AS mvpdrop2_id, MVP2per AS mvpdrop2_chance, ';
- $col .= 'MVP3id AS mvpdrop3_id, MVP3per AS mvpdrop3_chance';
+ $col .= 'mvpdrop1_item, mvpdrop1_rate, mvpdrop1_option, mvpdrop1_index, ';
+ $col .= 'mvpdrop2_item, mvpdrop2_rate, mvpdrop2_option, mvpdrop2_index, ';
+ $col .= 'mvpdrop3_item, mvpdrop3_rate, mvpdrop3_option, mvpdrop3_index ';
$sql = "SELECT $col FROM $mobDB WHERE ";
// Normal drops.
- $sql .= 'Drop1id = ? OR ';
- $sql .= 'Drop2id = ? OR ';
- $sql .= 'Drop3id = ? OR ';
- $sql .= 'Drop4id = ? OR ';
- $sql .= 'Drop5id = ? OR ';
- $sql .= 'Drop6id = ? OR ';
- $sql .= 'Drop7id = ? OR ';
- $sql .= 'Drop8id = ? OR ';
- $sql .= 'Drop9id = ? OR ';
-
- // Card drops.
- $sql .= 'DropCardid = ? OR ';
+ $sql .= 'drop1_item = ? OR ';
+ $sql .= 'drop2_item = ? OR ';
+ $sql .= 'drop3_item = ? OR ';
+ $sql .= 'drop4_item = ? OR ';
+ $sql .= 'drop5_item = ? OR ';
+ $sql .= 'drop6_item = ? OR ';
+ $sql .= 'drop7_item = ? OR ';
+ $sql .= 'drop8_item = ? OR ';
+ $sql .= 'drop9_item = ? OR ';
+ $sql .= 'drop10_item = ? OR ';
// MVP rewards.
- $sql .= 'MVP1id = ? OR ';
- $sql .= 'MVP2id = ? OR ';
- $sql .= 'MVP3id = ? ';
+ $sql .= 'mvpdrop1_item = ? OR ';
+ $sql .= 'mvpdrop2_item = ? OR ';
+ $sql .= 'mvpdrop3_item = ? ';
$sth = $server->connection->getStatement($sql);
- $res = $sth->execute(array_fill(0, 13, $itemID));
+ $res = $sth->execute(array_fill(0, 13, $item->identifier));
$dropResults = $sth->fetchAll();
$itemDrops = array();
$dropNames = array(
- 'drop1', 'drop2', 'drop3', 'drop4', 'drop5', 'drop6', 'drop7', 'drop8', 'drop9',
- 'dropcard', 'mvpdrop1', 'mvpdrop2', 'mvpdrop3'
+ 'drop1', 'drop2', 'drop3', 'drop4', 'drop5', 'drop6', 'drop7', 'drop8', 'drop9', 'drop10',
+ 'mvpdrop1', 'mvpdrop2', 'mvpdrop3'
);
// Sort callback.
function __tmpSortDrops($arr1, $arr2)
{
- if ($arr1['drop_chance'] == $arr2['drop_chance']) {
+ if ($arr1['drop_rate'] == $arr2['drop_rate']) {
return strcmp($arr1['monster_name'], $arr2['monster_name']);
}
- return $arr1['drop_chance'] < $arr2['drop_chance'] ? 1 : -1;
+ return $arr1['drop_rate'] < $arr2['drop_rate'] ? 1 : -1;
}
foreach ($dropResults as $drop) {
foreach ($dropNames as $dropName) {
- $dropID = $drop->{$dropName.'_id'};
- $dropChance = $drop->{$dropName.'_chance'};
+ $dropID = $drop->{$dropName.'_item'};
+ $dropChance = $drop->{$dropName.'_rate'};
+ $dropSteal = $drop->{$dropName.'_nosteal'};
- if ($dropID == $itemID) {
+ if ($dropID == $item->identifier) {
$dropArray = array(
- 'monster_id' => $drop->monster_id,
- 'monster_name' => $drop->monster_name,
- 'monster_level' => $drop->monster_level,
- 'monster_race' => $drop->monster_race,
- 'monster_element' => $drop->monster_element,
- 'monster_ele_lv' => $drop->monster_ele_lv,
- 'drop_id' => $itemID,
- 'drop_chance' => $dropChance
+ 'monster_id' => $drop->monster_id,
+ 'monster_name' => $drop->monster_name,
+ 'monster_level' => $drop->monster_level,
+ 'monster_race' => $drop->monster_race,
+ 'monster_element' => $drop->monster_element,
+ 'monster_ele_lv' => $drop->monster_ele_lv,
+ 'drop_item' => $itemID,
+ 'drop_rate' => $dropChance,
+ 'drop_steal' => ($dropSteal ? 'NoLabel' : 'YesLabel')
);
- if (preg_match('/^dropcard/', $dropName)) {
- $adjust = ($drop->mvp_exp) ? $server->dropRates['CardBoss'] : $server->dropRates['Card'];
- $dropArray['type'] = 'card';
- }
- elseif (preg_match('/^mvp/', $dropName)) {
- $adjust = $server->dropRates['MvpItem'];
+ $is_boss = false;
+ $is_mvp = false;
+ if(!$drop->mode_mvp && $drop->boss)
+ $is_boss = true;
+ if($drop->mode_mvp && $drop->boss)
+ $is_mvp = true;
+
+ if (preg_match('/^mvp/', $dropName)) {
+ $rate_adjust = $server->dropRates['MvpItem'];
+ $ratemin = $server->dropRates['MvpItemMin'];
+ $ratemax = $server->dropRates['MvpItemMax'];
$dropArray['type'] = 'mvp';
+ $dropArray['drop_steal'] = 'NoLabel';
}
elseif (preg_match('/^drop/', $dropName)) {
switch($item->type) {
- case 0: // Healing
- $adjust = ($drop->mvp_exp) ? $server->dropRates['HealBoss'] : $server->dropRates['Heal'];
+ case 'Healing':
+ $rate_adjust = $is_mvp ? $server->dropRates['HealMVP'] : ($is_boss ? $server->dropRates['HealBoss'] : $server->dropRates['Heal']);
+ $ratemin = $server->dropRates['HealMin'];
+ $ratemax = $server->dropRates['HealMax'];
break;
- case 2: // Useable
- case 18: // Cash Useable
- $adjust = ($drop->mvp_exp) ? $server->dropRates['UseableBoss'] : $server->dropRates['Useable'];
+ case 'Usable':
+ case 'Cash':
+ $rate_adjust = $is_mvp ? $server->dropRates['UseableMVP'] : ($is_boss ? $server->dropRates['UseableBoss'] : $server->dropRates['Useable']);
+ $ratemin = $server->dropRates['UseableMin'];
+ $ratemax = $server->dropRates['UseableMax'];
break;
- case 4: // Weapon
- case 5: // Armor
- case 8: // Pet Armor
- $adjust = ($drop->mvp_exp) ? $server->dropRates['EquipBoss'] : $server->dropRates['Equip'];
+ case 'Weapon':
+ case 'Armor':
+ case 'Petarmor':
+ $rate_adjust = $is_mvp ? $server->dropRates['EquipMVP'] : ($is_boss ? $server->dropRates['EquipBoss'] : $server->dropRates['Equip']);
+ $ratemin = $server->dropRates['EquipMin'];
+ $ratemax = $server->dropRates['EquipMax'];
break;
- default: // Common
- $adjust = ($drop->mvp_exp) ? $server->dropRates['CommonBoss'] : $server->dropRates['Common'];
+ case 'Card':
+ $rate_adjust = $is_mvp ? $server->dropRates['CardMVP'] : ($is_boss ? $server->dropRates['CardBoss'] : $server->dropRates['Card']);
+ $ratemin = $server->dropRates['CardMin'];
+ $ratemax = $server->dropRates['CardMax'];
+ break;
+
+ default:
+ $rate_adjust = $is_mvp ? $server->dropRates['CommonMVP'] : ($is_boss ? $server->dropRates['CommonBoss'] : $server->dropRates['Common']);
+ $ratemin = $server->dropRates['CommonMin'];
+ $ratemax = $server->dropRates['CommonMax'];
break;
}
$dropArray['type'] = 'normal';
}
- $dropArray['drop_chance'] = $dropArray['drop_chance'] * $adjust / 10000;
+ $ratemin /= 100;
+ $ratemax /= 100;
+ $ratecap = $server->dropRates['DropRateCap'] / 100;
- if ($dropArray['drop_chance'] > 100) {
- $dropArray['drop_chance'] = 100;
- }
+ $dropArray['drop_rate'] = $this->cap_value($dropArray['drop_rate'] * $rate_adjust / 10000, $ratemin, $ratemax);
+ if($dropArray['drop_rate'] > $ratecap)
+ $dropArray['drop_rate'] = $ratecap;
+
$itemDrops[] = $dropArray;
}
}
diff --git a/modules/itemshop/add.php b/modules/itemshop/add.php
index d002e8805..c7ff16438 100644
--- a/modules/itemshop/add.php
+++ b/modules/itemshop/add.php
@@ -22,7 +22,7 @@
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
$shopTable = Flux::config('FluxTables.ItemShopTable');
-$col = "id AS item_id, name_japanese AS item_name, type";
+$col = "id AS item_id, name_english AS item_name, type";
$sql = "SELECT $col FROM $tableName WHERE items.id = ?";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/itemshop/edit.php b/modules/itemshop/edit.php
index c128220ed..154a2023a 100644
--- a/modules/itemshop/edit.php
+++ b/modules/itemshop/edit.php
@@ -24,7 +24,7 @@
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
$shopTable = Flux::config('FluxTables.ItemShopTable');
- $col = "id AS item_id, name_japanese AS item_name, type";
+ $col = "id AS item_id, name_english AS item_name, type";
$sql = "SELECT $col FROM $tableName WHERE items.id = ?";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/logdata/feeding.php b/modules/logdata/feeding.php
index 6951487e5..cf5dd6432 100644
--- a/modules/logdata/feeding.php
+++ b/modules/logdata/feeding.php
@@ -130,14 +130,14 @@
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
$ids = array_keys($itemIDs);
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute($ids);
$ids = $sth->fetchAll();
foreach ($ids as $id) {
- $itemIDs[$id->id] = $id->name_japanese;
+ $itemIDs[$id->id] = $id->name_english;
}
}
@@ -151,14 +151,14 @@
$tempMobs = new Flux_TemporaryTable($server->connection, $mobDB, $fromTables);
$ids = array_keys($mobIDs);
- $sql = "SELECT ID, iName FROM {$server->charMapDatabase}.monsters WHERE ID IN (".implode(',', array_fill(0, count($ids), '?')).")";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.monsters WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute($ids);
$ids = $sth->fetchAll();
foreach ($ids as $id) {
- $mobIDs[$id->ID] = $id->iName;
+ $mobIDs[$id->id] = $id->name_english;
}
}
diff --git a/modules/logdata/pick.php b/modules/logdata/pick.php
index 7ce759259..1ff3c5990 100644
--- a/modules/logdata/pick.php
+++ b/modules/logdata/pick.php
@@ -78,7 +78,7 @@
$tempMobs = new Flux_TemporaryTable($server->connection, $mobDB, $fromTables);
$ids = array_keys($mobIDs);
- $sql = "SELECT ID, iName FROM {$server->charMapDatabase}.monsters WHERE ID IN (".implode(',', array_fill(0, count($ids), '?')).")";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.monsters WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute($ids);
@@ -86,7 +86,7 @@
// Map id to name.
foreach ($ids as $id) {
- $mobIDs[$id->ID] = $id->iName;
+ $mobIDs[$id->id] = $id->name_english;
}
}
@@ -101,7 +101,7 @@
$shopTable = Flux::config('FluxTables.ItemShopTable');
$ids = array_keys($itemIDs);
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN (".implode(',', array_fill(0, count($ids), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute($ids);
@@ -109,7 +109,7 @@
// Map nameid to name.
foreach ($ids as $id) {
- $itemIDs[$id->id] = $id->name_japanese;
+ $itemIDs[$id->id] = $id->name_english;
}
}
diff --git a/modules/logdata/zeny.php b/modules/logdata/zeny.php
index cfaf026e7..faf6a8d27 100644
--- a/modules/logdata/zeny.php
+++ b/modules/logdata/zeny.php
@@ -70,7 +70,7 @@
$tempMobs = new Flux_TemporaryTable($server->connection, $mobDB, $fromTables);
$ids = array_keys($mobIDs);
- $sql = "SELECT ID, iName FROM {$server->charMapDatabase}.monsters WHERE ID IN (".implode(',', array_fill(0, count($ids), '?')).")";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.monsters WHERE ID IN (".implode(',', array_fill(0, count($ids), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute($ids);
@@ -78,7 +78,7 @@
// Map id to name.
foreach ($ids as $id) {
- $mobIDs[$id->ID] = $id->iName;
+ $mobIDs[$id->id] = $id->name_english;
}
}
diff --git a/modules/mail/index.php b/modules/mail/index.php
index f93acd55b..0f3f20c54 100644
--- a/modules/mail/index.php
+++ b/modules/mail/index.php
@@ -2,9 +2,9 @@
if (!defined('FLUX_ROOT')) exit;
$this->loginRequired();
$title = Flux::message('MailerTitle');
-$whoto = trim($params->get('whoto'));
-$template = trim($params->get('template'));
-$subject = trim($params->get('subject'));
+$whoto = trim($params->get('whoto') ?: '');
+$template = trim($params->get('template') ?: '');
+$subject = trim($params->get('subject') ?: '');
$selectedtemplate = $template.'.php';
diff --git a/modules/monster/index.php b/modules/monster/index.php
index 9bd087660..22c727164 100644
--- a/modules/monster/index.php
+++ b/modules/monster/index.php
@@ -8,10 +8,9 @@
try {
$tableName = "{$server->charMapDatabase}.monsters";
if($server->isRenewal) {
-
- $fromTables = array("{$server->charMapDatabase}.mob_db_re", "{$server->charMapDatabase}.mob_db2_re");
+ $fromTables = array("{$server->charMapDatabase}.mob_db_re", "{$server->charMapDatabase}.mob_db2_re");
} else {
- $fromTables = array("{$server->charMapDatabase}.mob_db", "{$server->charMapDatabase}.mob_db2");
+ $fromTables = array("{$server->charMapDatabase}.mob_db", "{$server->charMapDatabase}.mob_db2");
}
$tempTable = new Flux_TemporaryTable($server->connection, $tableName, $fromTables);
@@ -31,23 +30,22 @@
$size = $params->get('size');
$race = $params->get('race');
$element = $params->get('element');
- $cardID = $params->get('card_id');
- $mvp = strtolower($params->get('mvp'));
+ $mvp = strtolower($params->get('mvp') ?: '');
$custom = $params->get('custom');
if ($monsterName) {
- $sqlpartial .= "AND ((kName LIKE ? OR kName = ?) OR (iName LIKE ? OR iName = ?)) ";
+ $sqlpartial .= "AND ((name_english LIKE ? OR name_english = ?) OR (name_japanese LIKE ? OR name_japanese = ?)) ";
$bind[] = "%$monsterName%";
$bind[] = $monsterName;
$bind[] = "%$monsterName%";
$bind[] = $monsterName;
}
- if ($size !== false && $size !== '-1') {
+ if ($size && $size !== '-1') {
if(is_numeric($size) && (floatval($size) == intval($size))) {
$sizes = Flux::config('MonsterSizes')->toArray();
if (array_key_exists($size, $sizes) && $sizes[$size]) {
- $sqlpartial .= "AND Scale = ? ";
+ $sqlpartial .= "AND size = ? ";
$bind[] = $size;
}
} else {
@@ -60,7 +58,7 @@
$partial = '';
foreach ($sizes as $id) {
- $partial .= "Scale = ? OR ";
+ $partial .= "size = ? OR ";
$bind[] = $id;
}
@@ -70,11 +68,11 @@
}
}
- if ($race !== false && $race !== '-1') {
- if(is_numeric($race) && (floatval($race) == intval($race))) {
+ if ($race && $race !== '-1') {
+ if($race) {
$races = Flux::config('MonsterRaces')->toArray();
if (array_key_exists($race, $races) && $races[$race]) {
- $sqlpartial .= "AND Race = ? ";
+ $sqlpartial .= "AND race = ? ";
$bind[] = $race;
}
} else {
@@ -87,7 +85,7 @@
$partial = '';
foreach ($races as $id) {
- $partial .= "Race = ? OR ";
+ $partial .= "race = ? OR ";
$bind[] = $id;
}
@@ -102,51 +100,27 @@
$element = $elementSplit[0];
$elementLevel = $elementSplit[1];
}
- if (is_numeric($element) && (floatval($element) == intval($element))) {
+ if ($element) {
$elements = Flux::config('Elements')->toArray();
if (array_key_exists($element, $elements) && $elements[$element]) {
- $sqlpartial .= "AND Element%10 = ? ";
+ $sqlpartial .= "AND element = ? ";
$bind[] = $element;
} else {
- $sqlpartial .= 'AND Element IS NULL ';
+ $sqlpartial .= 'AND element IS NULL ';
}
- if (count($elementSplit) == 2 && is_numeric($elementLevel) && (floatval($elementLevel) == intval($elementLevel))) {
- $sqlpartial .= "AND CAST(Element/20 AS UNSIGNED) = ? ";
+ if (count($elementSplit) == 2 && $elementLevel) {
+ $sqlpartial .= "AND element_level = ?" ;
$bind[] = $elementLevel;
}
- } else {
- $elementName = preg_quote($element, '/');
- $elements = preg_grep("/.*?$elementName.*?/i", Flux::config('Elements')->toArray());
-
- if (count($elements)) {
- $elements = array_keys($elements);
- $sqlpartial .= "AND (";
- $partial = '';
-
- foreach ($elements as $id) {
- $partial .= "Element%10 = ? OR ";
- $bind[] = $id;
- }
-
- $partial = preg_replace('/\s*OR\s*$/', '', $partial);
- $sqlpartial .= "$partial) ";
- } else {
- $sqlpartial .= 'AND Element IS NULL ';
- }
}
}
- if ($cardID) {
- $sqlpartial .= "AND DropCardid = ? ";
- $bind[] = $cardID;
- }
-
if ($mvp == 'yes') {
- $sqlpartial .= 'AND MEXP > 0 ';
+ $sqlpartial .= 'AND mvp_exp > 0 ';
}
elseif ($mvp == 'no') {
- $sqlpartial .= 'AND MEXP = 0 ';
+ $sqlpartial .= 'AND mvp_exp = 0 ';
}
if ($custom) {
@@ -165,12 +139,12 @@
$paginator = $this->getPaginator($sth->fetch()->total);
$paginator->setSortableColumns(array(
- 'monster_id' => 'asc', 'kro_name', 'iro_name', 'level', 'hp', 'size', 'race', 'exp', 'jexp', 'dropcard_id', 'origin_table'
+ 'monster_id' => 'asc', 'name_english', 'name_japanese', 'level', 'hp', 'size', 'race', 'base_exp', 'job_exp', 'origin_table'
));
- $col = "origin_table, monsters.ID AS monster_id, kName AS kro_name, iName AS iro_name, ";
- $col .= "LV AS level, HP AS hp, Scale as size, Race AS race, (Element%10) AS element_type, (Element/20) AS element_level, ";
- $col .= "EXP AS exp, JEXP AS jexp, DropCardid AS dropcard_id, mexp AS mvp_exp";
+ $col = "origin_table, monsters.ID AS monster_id, name_english, name_japanese, ";
+ $col .= "level, hp, size, race, element, element_level, ";
+ $col .= "base_exp, job_exp, mvp_exp";
$sql = $paginator->getSQL("SELECT $col FROM $tableName $sqlpartial");
$sth = $server->connection->getStatement($sql);
diff --git a/modules/monster/view.php b/modules/monster/view.php
index deb14c2dd..10693fb17 100644
--- a/modules/monster/view.php
+++ b/modules/monster/view.php
@@ -35,62 +35,68 @@
$itemDB = "{$server->charMapDatabase}.items";
$tempItems = new Flux_TemporaryTable($server->connection, $itemDB, $fromTables);
-$col = 'origin_table, ID as monster_id, Sprite AS sprite, kName AS kro_name, iName AS iro_name, LV AS level, HP AS hp, ';
-$col .= 'EXP AS base_exp, JEXP as job_exp, Range1 AS range1, Range2 AS range2, Range3 AS range3, ';
-$col .= 'DEF AS defense, MDEF AS magic_defense, ATK1 AS attack1, ATK2 AS attack2, DEF AS defense, MDEF AS magic_defense, ';
+$mode_list = array('mode_aggressive', 'mode_angry', 'mode_assist', 'mode_canattack', 'mode_canmove', 'mode_castsensorchase', 'mode_castsensoridle', 'mode_changechase', 'mode_changetargetchase', 'mode_changetargetmelee', 'mode_detector', 'mode_fixeditemdrop', 'mode_ignoremagic', 'mode_ignoremelee', 'mode_ignoremisc', 'mode_ignoreranged', 'mode_knockbackimmune', 'mode_looter', 'mode_mvp', 'mode_norandomwalk', 'mode_randomtarget', 'mode_skillimmune', 'mode_statusimmune', 'mode_targetweak', 'mode_teleportblock');
+
+$col = 'origin_table, ID as monster_id, name_aegis AS sprite, name_english, name_japanese, level, HP AS hp, ';
+$col .= 'base_exp, job_exp, attack_range, skill_range, chase_range, ';
+$col .= 'defense, magic_defense, attack, attack2, ';
$col .= 'STR AS strength, AGI AS agility, VIT AS vitality, `INT` AS intelligence, DEX AS dexterity, LUK AS luck, ';
-$col .= 'Scale AS size, Race AS race, (Element%10) AS element_type, (Element/20) AS element_level, Mode AS mode, ';
-$col .= 'Speed AS speed, aDelay AS attack_delay, aMotion AS attack_motion, dMotion AS delay_motion, ';
-$col .= 'MEXP AS mvp_exp, ';
+$col .= 'size, race, element, element_level, mode_canmove AS mode, `class` as boss, ';
+$col .= 'walk_speed, attack_delay, attack_motion, damage_motion, ';
+$col .= 'mvp_exp, ai, ';
+$col .= implode(', ', $mode_list).', '; // Mode list
// Item drops.
-$col .= 'Drop1id AS drop1_id, Drop1per AS drop1_chance, ';
-$col .= 'Drop2id AS drop2_id, Drop2per AS drop2_chance, ';
-$col .= 'Drop3id AS drop3_id, Drop3per AS drop3_chance, ';
-$col .= 'Drop4id AS drop4_id, Drop4per AS drop4_chance, ';
-$col .= 'Drop5id AS drop5_id, Drop5per AS drop5_chance, ';
-$col .= 'Drop6id AS drop6_id, Drop6per AS drop6_chance, ';
-$col .= 'Drop7id AS drop7_id, Drop7per AS drop7_chance, ';
-$col .= 'Drop8id AS drop8_id, Drop8per AS drop8_chance, ';
-$col .= 'Drop9id AS drop9_id, Drop9per AS drop9_chance, ';
-$col .= 'DropCardid AS dropcard_id, DropCardper AS dropcard_chance, ';
+$col .= 'drop1_item, drop1_rate, drop1_nosteal, ';
+$col .= 'drop2_item, drop2_rate, drop2_nosteal, ';
+$col .= 'drop3_item, drop3_rate, drop3_nosteal, ';
+$col .= 'drop4_item, drop4_rate, drop4_nosteal, ';
+$col .= 'drop5_item, drop5_rate, drop5_nosteal, ';
+$col .= 'drop6_item, drop6_rate, drop6_nosteal, ';
+$col .= 'drop7_item, drop7_rate, drop7_nosteal, ';
+$col .= 'drop8_item, drop8_rate, drop8_nosteal, ';
+$col .= 'drop9_item, drop9_rate, drop9_nosteal, ';
+$col .= 'drop10_item, drop10_rate, drop10_nosteal, ';
// MVP drops.
-$col .= 'MVP1id AS mvpdrop1_id, MVP1per AS mvpdrop1_chance, ';
-$col .= 'MVP2id AS mvpdrop2_id, MVP2per AS mvpdrop2_chance, ';
-$col .= 'MVP3id AS mvpdrop3_id, MVP3per AS mvpdrop3_chance ';
+$col .= 'mvpdrop1_item, mvpdrop1_rate, ';
+$col .= 'mvpdrop2_item, mvpdrop2_rate, ';
+$col .= 'mvpdrop3_item, mvpdrop3_rate ';
$sql = "SELECT $col FROM $mobDB WHERE ID = ? LIMIT 1";
$sth = $server->connection->getStatement($sql);
$sth->execute(array($mobID));
$monster = $sth->fetch();
+
if ($monster) {
- $title = "Viewing Monster ({$monster->kro_name})";
-
- $monster->boss = $monster->mvp_exp;
+ $title = "Viewing Monster ({$monster->name_english})";
+
+ // Mode
+ $modes = array();
+ foreach($mode_list as $mode) if($monster->$mode) $modes[] = $mode;
$monster->base_exp = $monster->base_exp * $server->expRates['Base'] / 100;
$monster->job_exp = $monster->job_exp * $server->expRates['Job'] / 100;
$monster->mvp_exp = $monster->mvp_exp * $server->expRates['Mvp'] / 100;
$dropIDs = array(
- 'drop1' => $monster->drop1_id,
- 'drop2' => $monster->drop2_id,
- 'drop3' => $monster->drop3_id,
- 'drop4' => $monster->drop4_id,
- 'drop5' => $monster->drop5_id,
- 'drop6' => $monster->drop6_id,
- 'drop7' => $monster->drop7_id,
- 'drop8' => $monster->drop8_id,
- 'drop9' => $monster->drop9_id,
- 'dropcard' => $monster->dropcard_id,
- 'mvpdrop1' => $monster->mvpdrop1_id,
- 'mvpdrop2' => $monster->mvpdrop2_id,
- 'mvpdrop3' => $monster->mvpdrop3_id
+ 'drop1' => $monster->drop1_item,
+ 'drop2' => $monster->drop2_item,
+ 'drop3' => $monster->drop3_item,
+ 'drop4' => $monster->drop4_item,
+ 'drop5' => $monster->drop5_item,
+ 'drop6' => $monster->drop6_item,
+ 'drop7' => $monster->drop7_item,
+ 'drop8' => $monster->drop8_item,
+ 'drop9' => $monster->drop9_item,
+ 'drop10' => $monster->drop10_item,
+ 'mvpdrop1' => $monster->mvpdrop1_item,
+ 'mvpdrop2' => $monster->mvpdrop2_item,
+ 'mvpdrop3' => $monster->mvpdrop3_item
);
- $sql = "SELECT id, name_japanese, type FROM $itemDB WHERE id IN (".implode(', ', array_fill(0, count($dropIDs), '?')).")";
+ $sql = "SELECT id, name_aegis, name_english, type FROM $itemDB WHERE name_aegis IN (".implode(', ', array_fill(0, count($dropIDs), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute(array_values($dropIDs));
$items = $sth->fetchAll();
@@ -103,62 +109,82 @@
foreach ($items as $item) {
foreach ($dropIDs AS $dropField => $dropID) {
- if ($needToSet[$dropField] && $dropID == $item->id) {
+ if ($needToSet[$dropField] && $dropID == $item->name_aegis) {
$needToSet[$dropField] = false;
- $monster->{$dropField.'_name'} = $item->name_japanese;
+ $monster->{$dropField.'_id'} = $item->id;
+ $monster->{$dropField.'_name'} = $item->name_english;
$monster->{$dropField.'_type'} = $item->type;
}
}
}
}
+ $is_boss = false;
+ $is_mvp = false;
+ if(!$monster->mode_mvp && $monster->boss)
+ $is_boss = true;
+ if($monster->mode_mvp && $monster->boss)
+ $is_mvp = true;
+
$itemDrops = array();
foreach ($needToSet as $dropField => $isset) {
if ($isset === false) {
$itemDrops[$dropField] = array(
'id' => $monster->{$dropField.'_id'},
'name' => $monster->{$dropField.'_name'},
- 'chance' => $monster->{$dropField.'_chance'}
+ 'type' => $monster->{$dropField.'_type'},
+ 'chance' => $monster->{$dropField.'_rate'},
+ 'nosteal' => ($monster->{$dropField.'_nosteal'} ? 'NoLabel' : 'YesLabel')
);
-
- if (preg_match('/^dropcard/', $dropField)) {
- $adjust = ($monster->boss) ? $server->dropRates['CardBoss'] : $server->dropRates['Card'];
- $itemDrops[$dropField]['type'] = 'card';
- }
- elseif (preg_match('/^mvpdrop/', $dropField)) {
- $adjust = $server->dropRates['MvpItem'];
+
+ if (preg_match('/^mvpdrop/', $dropField)) {
+ $rate_adjust = $server->dropRates['MvpItem'];
+ $ratemin = $server->dropRates['MvpItemMin'];
+ $ratemax = $server->dropRates['MvpItemMax'];
$itemDrops[$dropField]['type'] = 'mvp';
+ $itemDrops[$dropField]['nosteal'] = 'NoLabel';
}
elseif (preg_match('/^drop/', $dropField)) {
switch($monster->{$dropField.'_type'}) {
- case 0: // Healing
- $adjust = ($monster->boss) ? $server->dropRates['HealBoss'] : $server->dropRates['Heal'];
+ case 'Healing':
+ $rate_adjust = $is_mvp ? $server->dropRates['HealMVP'] : ($is_boss ? $server->dropRates['HealBoss'] : $server->dropRates['Heal']);
+ $ratemin = $server->dropRates['HealMin'];
+ $ratemax = $server->dropRates['HealMax'];
break;
-
- case 2: // Useable
- case 18: // Cash Useable
- $adjust = ($monster->boss) ? $server->dropRates['UseableBoss'] : $server->dropRates['Useable'];
+
+ case 'Usable':
+ case 'Cash':
+ $rate_adjust = $is_mvp ? $server->dropRates['UseableMVP'] : ($is_boss ? $server->dropRates['UseableBoss'] : $server->dropRates['Useable']);
+ $ratemin = $server->dropRates['UseableMin'];
+ $ratemax = $server->dropRates['UseableMax'];
break;
-
- case 4: // Weapon
- case 5: // Armor
- case 8: // Pet Armor
- $adjust = ($monster->boss) ? $server->dropRates['EquipBoss'] : $server->dropRates['Equip'];
+
+ case 'Weapon':
+ case 'Armor':
+ case 'Petarmor':
+ $rate_adjust = $is_mvp ? $server->dropRates['EquipMVP'] : ($is_boss ? $server->dropRates['EquipBoss'] : $server->dropRates['Equip']);
+ $ratemin = $server->dropRates['EquipMin'];
+ $ratemax = $server->dropRates['EquipMax'];
break;
default: // Common
- $adjust = ($monster->boss) ? $server->dropRates['CommonBoss'] : $server->dropRates['Common'];
+ $rate_adjust = $is_mvp ? $server->dropRates['CommonMVP'] : ($is_boss ? $server->dropRates['CommonBoss'] : $server->dropRates['Common']);
+ $ratemin = $server->dropRates['CommonMin'];
+ $ratemax = $server->dropRates['CommonMax'];
break;
}
$itemDrops[$dropField]['type'] = 'normal';
}
+
+ $ratemin /= 100;
+ $ratemax /= 100;
+ $ratecap = $server->dropRates['DropRateCap'] / 100;
- $itemDrops[$dropField]['chance'] = $itemDrops[$dropField]['chance'] * $adjust / 10000;
+ $itemDrops[$dropField]['chance'] = $this->cap_value($itemDrops[$dropField]['chance'] * $rate_adjust / 10000, $ratemin, $ratemax);
- if ($itemDrops[$dropField]['chance'] > 100) {
- $itemDrops[$dropField]['chance'] = 100;
- }
+ if($itemDrops[$dropField]['chance'] > $ratecap)
+ $itemDrops[$dropField]['chance'] = $ratecap;
}
}
diff --git a/modules/news/add.php b/modules/news/add.php
index 755e9605f..b04f30c6f 100644
--- a/modules/news/add.php
+++ b/modules/news/add.php
@@ -9,6 +9,8 @@
$link = trim($params->get('news_link'));
$author = trim($params->get('news_author'));
+$tinymce_key = Flux::config('TinyMCEKey');
+
if(count($_POST)){
if($title === '') {
$errorMessage = Flux::Message('CMSNewsTitleError');
diff --git a/modules/news/edit.php b/modules/news/edit.php
index 090967773..c1a3f35fe 100644
--- a/modules/news/edit.php
+++ b/modules/news/edit.php
@@ -8,6 +8,8 @@
$sth->execute(array($id));
$new = $sth->fetch();
+$tinymce_key = Flux::config('TinyMCEKey');
+
if($new) {
$title = $new->title;
$body = $new->body;
diff --git a/modules/pages/add.php b/modules/pages/add.php
index 374d944a7..2b82efe17 100644
--- a/modules/pages/add.php
+++ b/modules/pages/add.php
@@ -8,6 +8,8 @@
$path = trim($params->get('page_path'));
$body = trim($params->get('page_body'));
+$tinymce_key = Flux::config('TinyMCEKey');
+
if(count($_POST))
{
if($page_title === '') {
diff --git a/modules/pages/edit.php b/modules/pages/edit.php
index 60e80f40e..0760d3100 100644
--- a/modules/pages/edit.php
+++ b/modules/pages/edit.php
@@ -9,6 +9,8 @@
$sth->execute(array($id));
$page = $sth->fetch();
+$tinymce_key = Flux::config('TinyMCEKey');
+
if($page) {
$title = $page->title;
$path = $page->path;
diff --git a/modules/purchase/pending.php b/modules/purchase/pending.php
index 3989345aa..7b2f5975d 100644
--- a/modules/purchase/pending.php
+++ b/modules/purchase/pending.php
@@ -30,7 +30,7 @@
$total = $sth->fetch()->total;
// Fetch items.
- $col = "nameid, quantity, purchase_date, cost, credits_before, credits_after, items.name_japanese AS item_name";
+ $col = "nameid, quantity, purchase_date, cost, credits_before, credits_after, items.name_english AS item_name";
$sql = "SELECT $col FROM {$server->charMapDatabase}.$redeemTable $sqlpartial";
$sth = $server->connection->getStatement($sql);
diff --git a/modules/ranking/alchemist.php b/modules/ranking/alchemist.php
index d37032343..ae917ef1f 100644
--- a/modules/ranking/alchemist.php
+++ b/modules/ranking/alchemist.php
@@ -15,7 +15,7 @@
}
$col = "ch.char_id, ch.name AS char_name, ch.fame, ch.class AS char_class, ch.base_level, ch.job_level, ";
-$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len";
+$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_id as emblem ";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`char` AS ch ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.guild ON guild.guild_id = ch.guild_id ";
diff --git a/modules/ranking/blacksmith.php b/modules/ranking/blacksmith.php
index 32e66d755..20f98ccd9 100644
--- a/modules/ranking/blacksmith.php
+++ b/modules/ranking/blacksmith.php
@@ -15,7 +15,7 @@
}
$col = "ch.char_id, ch.name AS char_name, ch.fame, ch.class AS char_class, ch.base_level, ch.job_level, ";
-$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len";
+$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_id as emblem ";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`char` AS ch ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.guild ON guild.guild_id = ch.guild_id ";
diff --git a/modules/ranking/character.php b/modules/ranking/character.php
index a7842dd93..834735743 100644
--- a/modules/ranking/character.php
+++ b/modules/ranking/character.php
@@ -6,7 +6,7 @@
$jobClass = $params->get('jobclass');
$bind = array();
-if (trim($jobClass) === '') {
+if (trim($jobClass ?: '') === '') {
$jobClass = null;
}
@@ -15,7 +15,7 @@
}
$col = "ch.char_id, ch.name AS char_name, ch.class AS char_class, ch.base_level, ch.base_exp, ch.job_level, ch.job_exp, ";
-$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len";
+$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_id as emblem ";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`char` AS ch ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.guild ON guild.guild_id = ch.guild_id ";
diff --git a/modules/ranking/death.php b/modules/ranking/death.php
index 78902fead..2c751da30 100644
--- a/modules/ranking/death.php
+++ b/modules/ranking/death.php
@@ -15,7 +15,8 @@
}
$col = "ch.char_id, ch.name AS char_name, ch.class AS char_class, ch.base_level, ch.job_level, ";
-$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len, ";
+$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_id as emblem, ";
+
$col .= "CAST(IFNULL(reg.value, '0') AS UNSIGNED) AS death_count";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`char` AS ch ";
diff --git a/modules/ranking/guild.php b/modules/ranking/guild.php
index f446ee5a2..aab81a886 100644
--- a/modules/ranking/guild.php
+++ b/modules/ranking/guild.php
@@ -7,7 +7,7 @@
$ids = implode(',', array_fill(0, count($castleNames), '?'));
$bind = array_keys($castleNames);
-$col = "g.guild_id, g.name, g.guild_lv, g.average_lv, g.emblem_len, ";
+$col = "g.guild_id, g.name, g.guild_lv, g.average_lv, g.emblem_id as emblem, ";
$col .= "GREATEST(g.exp, (SELECT SUM(exp) FROM {$server->charMapDatabase}.guild_member WHERE guild_member.guild_id = g.guild_id)) AS exp, ";
$col .= "(SELECT COUNT(char_id) FROM {$server->charMapDatabase}.`char` WHERE `char`.guild_id = g.guild_id) AS members, ";
$col .= "(SELECT COUNT(castle_id) FROM {$server->charMapDatabase}.guild_castle WHERE guild_castle.guild_id = g.guild_id AND castle_id IN ($ids)) AS castles";
diff --git a/modules/ranking/mvp.php b/modules/ranking/mvp.php
index 85f2caaf4..eb63ab8b5 100644
--- a/modules/ranking/mvp.php
+++ b/modules/ranking/mvp.php
@@ -28,19 +28,22 @@
$sth->execute($sql_params);
$killer_char_ids = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
-// Get group id of the killer and filter -_-
-$groups = AccountLevel::getGroupID((int)Flux::config('RankingHideGroupLevel'), '<');
-$sql = "SELECT `char`.`char_id` FROM {$server->charMapDatabase}.`char`";
-$sql .= " LEFT JOIN {$server->loginDatabase}.`login` ON `char`.`account_id` = `login`.`account_id`";
-$sql .= " WHERE `char`.`char_id`IN(".implode(',',array_fill(0, count($killer_char_ids), '?')).") AND `login`.`group_id` NOT IN (".implode(',',array_fill(0, count($groups), '?')).")";
-$sql_params = array_merge($killer_char_ids, $groups);
-$sth = $server->connection->getStatement($sql);
-$sth->execute($sql_params);
-$char_ids_filter = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
+$char_ids_filter = [];
+if(count($killer_char_ids)) {
+ // Get group id of the killer and filter -_-
+ $groups = AccountLevel::getGroupID((int)Flux::config('RankingHideGroupLevel'), '<');
+ $sql = "SELECT `char`.`char_id` FROM {$server->charMapDatabase}.`char`";
+ $sql .= " LEFT JOIN {$server->loginDatabase}.`login` ON `char`.`account_id` = `login`.`account_id`";
+ $sql .= " WHERE `char`.`char_id`IN(".implode(',',array_fill(0, count($killer_char_ids), '?')).") AND `login`.`group_id` NOT IN (".implode(',',array_fill(0, count($groups), '?')).")";
+ $sql_params = array_merge($killer_char_ids, $groups);
+ $sth = $server->connection->getStatement($sql);
+ $sth->execute($sql_params);
+ $char_ids_filter = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
+}
$bind = array();
-$col = "id, iName, Sprite";
-$sql = "SELECT $col FROM $tableName WHERE `MEXP` > 0 ORDER BY `iName`";
+$col = "id, name_english, name_aegis";
+$sql = "SELECT $col FROM $tableName WHERE `mvp_exp` > 0 ORDER BY `name_english`";
$sth = $server->connection->getStatement($sql);
$sth->execute();
$moblist = $sth->fetchAll();
@@ -54,7 +57,7 @@
$col = "mlog.kill_char_id, mlog.monster_id, count(*) AS count ";
$sql = "SELECT $col FROM {$server->logsDatabase}.`mvplog` AS mlog ";
$sql.= "WHERE mlog.monster_id = ? ";
- if ($char_ids_filter) {
+ if (count($char_ids_filter)) {
$sql .= " AND `kill_char_id` NOT IN(".implode(',',array_fill(0, count($char_ids_filter), '?')).")";
}
$sql.= "GROUP BY mlog.kill_char_id ORDER BY count DESC LIMIT $limit";
@@ -71,7 +74,7 @@
// Latest x Kills
$col = "mlog.mvp_id, mlog.mvp_date, mlog.kill_char_id, mlog.monster_id, mlog.mvpexp, mlog.map ";
$sql = "SELECT $col FROM {$server->logsDatabase}.`mvplog` AS mlog ";
- if ($char_ids_filter) {
+ if (count($char_ids_filter)) {
$sql .= " WHERE `kill_char_id` NOT IN(".implode(',',array_fill(0, count($char_ids_filter), '?')).")";
}
$sql.= "ORDER BY mlog.mvp_date DESC LIMIT $limit";
@@ -97,12 +100,12 @@
}
if (count($monsters)) {
- $sql = "SELECT `id`,`iName` FROM $tableName WHERE `id` IN(".implode(',', array_fill(0, count($monsters), '?')).")";
+ $sql = "SELECT `id`,`name_english` FROM $tableName WHERE `id` IN(".implode(',', array_fill(0, count($monsters), '?')).")";
$sth = $server->connection->getStatement($sql);
$sth->execute(array_keys($monsters));
$temp = $sth->fetchAll();
foreach ($temp as $mon) {
- $monsters[$mon->id] = $mon->iName;
+ $monsters[$mon->id] = $mon->name_english;
}
}
$char_ids_filter = null;
diff --git a/modules/ranking/zeny.php b/modules/ranking/zeny.php
index cf1cdc660..9705d4ee4 100644
--- a/modules/ranking/zeny.php
+++ b/modules/ranking/zeny.php
@@ -17,7 +17,7 @@
$charPrefsTable = Flux::config('FluxTables.CharacterPrefsTable');
$col = "ch.char_id, ch.name AS char_name, ch.zeny, ch.class AS char_class, ch.base_level, ch.base_exp, ch.job_level, ch.job_exp, ";
-$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len";
+$col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_id as emblem ";
$sql = "SELECT $col FROM {$server->charMapDatabase}.`char` AS ch ";
$sql .= "LEFT JOIN {$server->charMapDatabase}.$charPrefsTable AS hide_from_zr ON ";
diff --git a/modules/servicedesk/create.php b/modules/servicedesk/create.php
index fe9c02f1e..1d62043f5 100644
--- a/modules/servicedesk/create.php
+++ b/modules/servicedesk/create.php
@@ -21,14 +21,14 @@
$catlist = $catsql->fetchAll();
if(isset($_POST['account_id'])){
- $char_id = $_POST['char_id'];
- $category = $_POST['category'];
- $subject = $_POST['subject'];
- $text = $_POST['text'];
+ $char_id = intval($_POST['char_id']);
+ $category = intval($_POST['category']);
+ $subject = htmlentities($_POST['subject']);
+ $text = htmlentities($_POST['text']);
$ip = $_POST['ip'];
- if($_POST['sslink']==NULL || $_POST['sslink']==''){$_POST['sslink'] = '0';}else{$_POST['sslink'] = $_POST['sslink'];}
- if($_POST['chatlink']==NULL || $_POST['chatlink']==''){$_POST['chatlink'] = '0';}else{$_POST['chatlink'] = $_POST['chatlink'];}
- if($_POST['videolink']==NULL || $_POST['videolink']==''){$_POST['videolink'] = '0';}else{$_POST['videolink'] = $_POST['videolink'];}
+ if($_POST['sslink']==NULL || $_POST['sslink']==''){$_POST['sslink'] = '0';}else{$_POST['sslink'] = htmlentities($_POST['sslink']);}
+ if($_POST['chatlink']==NULL || $_POST['chatlink']==''){$_POST['chatlink'] = '0';}else{$_POST['chatlink'] = htmlentities($_POST['chatlink']);}
+ if($_POST['videolink']==NULL || $_POST['videolink']==''){$_POST['videolink'] = '0';}else{$_POST['videolink'] = htmlentities($_POST['videolink']);}
$sql = "INSERT INTO {$server->loginDatabase}.$tbl (account_id, char_id, category, sslink, chatlink, videolink, subject, text, ip, curemail, lastreply)";
$sql .= "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)";
diff --git a/modules/servicedesk/staffview.php b/modules/servicedesk/staffview.php
index bd3239c0a..8e1819843 100644
--- a/modules/servicedesk/staffview.php
+++ b/modules/servicedesk/staffview.php
@@ -2,9 +2,9 @@
if (!defined('FLUX_ROOT')) exit;
$this->loginRequired();
$ticket_id = trim($params->get('ticketid'));
-$tbl = Flux::config('FluxTables.ServiceDeskTable');
-$tbla = Flux::config('FluxTables.ServiceDeskATable');
-$tblsettings = Flux::config('FluxTables.ServiceDeskSettingsTable');
+$tbl = Flux::config('FluxTables.ServiceDeskTable');
+$tbla = Flux::config('FluxTables.ServiceDeskATable');
+$tblsettings = Flux::config('FluxTables.ServiceDeskSettingsTable');
$sth = $server->connection->getStatement("SELECT * FROM {$server->loginDatabase}.$tblsettings WHERE account_id = ?");
$sth->execute(array($session->account->account_id));
@@ -27,14 +27,14 @@
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, 0, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $_SERVER['REMOTE_ADDR']));
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $_SERVER['REMOTE_ADDR']));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
require_once 'Flux/Mailer.php';
$name = $session->loginAthenaGroup->serverName;
$mail = new Flux_Mailer();
@@ -43,22 +43,22 @@
'Staff' => $staffsess->prefered_name
));
if ($sent) {
- $this->redirect($this->url('servicedesk','staffview', array('ticketid' => $ticket_id)));
+ $this->redirect($this->url('servicedesk','staffview', array('ticketid' => $ticket_id)));
}
else {
$fail = true;
}
-
+
}elseif($_POST['secact']=='2'){
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, 0, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $_SERVER['REMOTE_ADDR']));
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $_SERVER['REMOTE_ADDR']));
require_once 'Flux/Mailer.php';
$name = $session->loginAthenaGroup->serverName;
$mail = new Flux_Mailer();
@@ -67,24 +67,24 @@
'Staff' => $staffsess->prefered_name
));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
-
+
}elseif($_POST['secact']=='3'){
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET status = 'Resolved' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
-
+ $sth->execute(array($ticket_id));
+
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$action='Ticket Resolved';
-
+
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
require_once 'Flux/Mailer.php';
$name = $session->loginAthenaGroup->serverName;
$mail = new Flux_Mailer();
@@ -93,9 +93,9 @@
'Staff' => $staffsess->prefered_name
));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
-
+
}elseif($_POST['secact']=='4'){
if($staffsess->team=='1'){
$escalateto=2;
@@ -104,50 +104,50 @@
$escalateto=3;
}
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET team = ? WHERE ticket_id = ?");
- $sth->execute(array($escalateto, $ticket_id));
+ $sth->execute(array($escalateto, $ticket_id));
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$action='Escalated to a member of the '. Flux::message('SDGroup'. $escalateto) .' team.';
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
}elseif($_POST['secact']=='5'){
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET status = 'Closed' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$action='Ticket Closed by a member of the '. Flux::message('SDGroup'. $staffsess->team) .' group.';
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
-
+
}elseif($_POST['secact']=='6'){
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET status = 'Pending' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
-
+ $sth->execute(array($ticket_id));
+
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$action='Ticket Re-Opened by a member of the '. Flux::message('SDGroup'. $staffsess->team) .' group.';
-
+
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 1)";
$sth = $server->connection->getStatement($sql);
@@ -160,25 +160,26 @@
'Staff' => $staffsess->prefered_name
));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
-
+
}elseif($_POST['secact']=='7'){
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET status = 'Resolved' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
-
+ $sth->execute(array($ticket_id));
+ $give_credits = intval($_POST['award_credits']);
+
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
- $action = sprintf('Ticket Resolved, %d Credits Awarded.', Flux::config('SDCreditReward'));
-
+ $action = sprintf('Ticket Resolved, %d Credits Awarded.', $give_credits);
+
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 1)";
$sth = $server->connection->getStatement($sql);
- $res = $server->loginServer->depositCredits($_POST['account_id'], Flux::config('SDCreditReward'));
- $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
+ $res = $server->loginServer->depositCredits($_POST['account_id'], $give_credits);
+ $sth->execute(array($ticket_id, $_POST['staff_reply_name'], $text, $action, $_SERVER['REMOTE_ADDR']));
require_once 'Flux/Mailer.php';
$name = $session->loginAthenaGroup->serverName;
$mail = new Flux_Mailer();
@@ -187,15 +188,13 @@
'Staff' => $staffsess->prefered_name
));
$sth = $server->connection->getStatement("UPDATE {$server->loginDatabase}.$tbl SET lastreply = 'Staff' WHERE ticket_id = ?");
- $sth->execute(array($ticket_id));
+ $sth->execute(array($ticket_id));
$this->redirect($this->url('servicedesk','staffindex'));
}
}
-
-
-$tbl = Flux::config('FluxTables.ServiceDeskTable');
-$tbla = Flux::config('FluxTables.ServiceDeskATable');
+$tbl = Flux::config('FluxTables.ServiceDeskTable');
+$tbla = Flux::config('FluxTables.ServiceDeskATable');
$sql = "SELECT * FROM {$server->loginDatabase}.$tbl WHERE ticket_id = $ticket_id";
$rep = $server->connection->getStatement($sql);
$rep->execute();
@@ -226,7 +225,7 @@
$repr->execute();
$replylist = $repr->fetchAll();
-$tblc = Flux::config('FluxTables.ServiceDeskCatTable');
+$tblc = Flux::config('FluxTables.ServiceDeskCatTable');
$sth = $server->connection->getStatement("SELECT name FROM {$server->loginDatabase}.$tblc WHERE cat_id = ?");
$sth->execute(array($trow->category));
$ticketlist = $sth->fetchAll();
diff --git a/modules/servicedesk/view.php b/modules/servicedesk/view.php
index c960267dd..a62e768ac 100644
--- a/modules/servicedesk/view.php
+++ b/modules/servicedesk/view.php
@@ -14,7 +14,7 @@
$this->redirect($this->url('servicedesk','view', array('ticketid' => $ticket_id)));
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, 0, ?, 0)";
@@ -31,7 +31,7 @@
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$action='Player marked ticket as Resolved';
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
@@ -49,7 +49,7 @@
if($_POST['response']=='Leave as-is to skip text response.' || $_POST['response'] == '' || $_POST['response'] == NULL || !isset($_POST['response'])){
$text = '0';
} else {
- $text = addslashes($_POST['response']);
+ $text = htmlentities($_POST['response']);
}
$sql = "INSERT INTO {$server->loginDatabase}.$tbla (ticket_id, author, text, action, ip, isstaff)";
$sql .= "VALUES (?, ?, ?, ?, ?, 0)";
diff --git a/modules/vending/viewshop.php b/modules/vending/viewshop.php
index 609f1cd3b..fe78cc647 100644
--- a/modules/vending/viewshop.php
+++ b/modules/vending/viewshop.php
@@ -35,7 +35,12 @@
// Get the current Vendor values.
$sql = "SELECT `vending_items`.cartinventory_id, `vending_items`.amount, `vending_items`.price, ";
$sql .= "`cart_inventory`.nameid, `cart_inventory`.refine, `cart_inventory`.card0, `cart_inventory`.card1, `cart_inventory`.card2, c.name as char_name, ";
- $sql .= "items.name_japanese as item_name, items.slots, items.type ";
+ $sql .= "`cart_inventory`.option_id0, `cart_inventory`.option_val0, ";
+ $sql .= "`cart_inventory`.option_id1, `cart_inventory`.option_val1, ";
+ $sql .= "`cart_inventory`.option_id2, `cart_inventory`.option_val2, ";
+ $sql .= "`cart_inventory`.option_id3, `cart_inventory`.option_val3, ";
+ $sql .= "`cart_inventory`.option_id4, `cart_inventory`.option_val4, ";
+ $sql .= "items.name_english as item_name, items.slots, items.type ";
$sql .= "FROM vending_items ";
$sql .= "LEFT JOIN `cart_inventory` on `vending_items`.cartinventory_id = `cart_inventory`.id ";
@@ -82,24 +87,35 @@
if ($item->card0 == 254 || $item->card0 == 255 || $item->card0 == -256 || $item->cardsOver < 0) {
$item->cardsOver = 0;
}
+
+ if($server->isRenewal) {
+ $temp = array();
+ if ($item->option_id0) array_push($temp, array($item->option_id0, $item->option_val0));
+ if ($item->option_id1) array_push($temp, array($item->option_id1, $item->option_val1));
+ if ($item->option_id2) array_push($temp, array($item->option_id2, $item->option_val2));
+ if ($item->option_id3) array_push($temp, array($item->option_id3, $item->option_val3));
+ if ($item->option_id4) array_push($temp, array($item->option_id4, $item->option_val4));
+ $item->rndopt = $temp;
+ }
}
if ($cardIDs) {
$ids = implode(',', array_fill(0, count($cardIDs), '?'));
- $sql = "SELECT id, name_japanese FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
+ $sql = "SELECT id, name_english FROM {$server->charMapDatabase}.items WHERE id IN ($ids)";
$sth = $server->connection->getStatement($sql);
$sth->execute($cardIDs);
$temp = $sth->fetchAll();
if ($temp) {
foreach ($temp as $card) {
- $cards[$card->id] = $card->name_japanese;
+ $cards[$card->id] = $card->name_english;
}
}
}
}
$itemAttributes = Flux::config('Attributes')->toArray();
+ $type_list = Flux::config('ItemTypes')->toArray();
} else {
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 000000000..1d5ff1fe8
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Disallow: /item/
+Disallow: /monster/
+Disallow: /vending/
diff --git a/themes/bootstrap/footer.php b/themes/bootstrap/footer.php
index 4e2003d14..7434b01e6 100644
--- a/themes/bootstrap/footer.php
+++ b/themes/bootstrap/footer.php
@@ -8,14 +8,13 @@
Powered by FluxCP
-
+
Page generated in second(s).
Number of queries executed: .
Gzip Compression: Enabled.
-
+
get('ThemeName', false)) > 1): ?>
-
Theme:
-
-
- Language:
-
-
+
-
-
+ Language:
+
+
+
+
-
+
-
+
-
+
-
+
-
-