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: + + +

+
+ +
- + - + - + - + - - diff --git a/themes/bootstrap/header.php b/themes/bootstrap/header.php index a27d50da0..cedc4b460 100644 --- a/themes/bootstrap/header.php +++ b/themes/bootstrap/header.php @@ -21,7 +21,7 @@ + @@ -32,34 +32,27 @@ - + themePath('main/navbar.php', true) ?> - -
+ + + +

Please change your ServerAddress directive in your application config to your server's real address (e.g., myserver.com).

+ + + getMessage()): ?> +

+ + + themePath('main/submenu.php', true) ?> - + + themePath('main/pagemenu.php', true) ?> - - - -

Please change your ServerAddress directive in your application config to your server's real address (e.g., myserver.com).

- - - - getMessage()): ?> -

- - - - themePath('main/submenu.php', true) ?> - - - themePath('main/pagemenu.php', true) ?> - - - get('module'), array('donate', 'purchase'))) include 'main/balance.php' ?> + + get('module'), array('donate', 'purchase'))) include 'main/balance.php' ?> diff --git a/themes/bootstrap/js/flux.datefields.js b/themes/bootstrap/js/flux.datefields.js deleted file mode 100644 index 5af11baff..000000000 --- a/themes/bootstrap/js/flux.datefields.js +++ /dev/null @@ -1,48 +0,0 @@ -function processDateFields(){ - var dateFields = new Array(); - var dateName; - var dateCheckBox; - var dateSelects; - var dateSelects2; - - $(':checkbox').filter(function(){ - return /^use_/.test($(this).attr('id')); - }).each(function(){ - dateFields[dateFields.length] = this.id.substr('use_'.length); - }); - - for (var i = 0; i < dateFields.length; ++i) { - dateName = dateFields[i]; - dateCheckBox = $('#use_'+dateName); - dateSelects = $('select[name='+dateName+'_year],select[name='+dateName+'_month],select[name='+dateName+'_day]'); - dateSelects2 = $('select[name='+dateName+'_hour],select[name='+dateName+'_minute],select[name='+dateName+'_second]'); - - processDateInit(dateCheckBox, dateSelects, dateSelects2); - processDateBoxes(dateCheckBox, dateSelects, dateSelects2); - } -} - -function processDateInit(dateCheckBox, dateSelects, dateSelects2){ - if ($(dateCheckBox).attr('checked')) { - dateEnable(dateSelects); - dateEnable(dateSelects2); - } - else { - dateDisable(dateSelects); - dateDisable(dateSelects2); - } -} - -function processDateBoxes(dateCheckBox, dateSelects, dateSelects2){ - $(dateCheckBox).click(function(){ - processDateInit(dateCheckBox, dateSelects, dateSelects2); - }); -} - -function dateEnable(sel){ - sel.attr('disabled', false); -} - -function dateDisable(sel){ - sel.attr('disabled', 'disabled'); -} diff --git a/themes/bootstrap/js/flux.unitip.js b/themes/bootstrap/js/flux.unitip.js deleted file mode 100644 index 6e02ef0e0..000000000 --- a/themes/bootstrap/js/flux.unitip.js +++ /dev/null @@ -1,223 +0,0 @@ -// uniTip - written by Nathan Ford for Unit Interactive -// -// uniTip is based on qTip: -// qTip - CSS Tool Tips - by Craig Erskine -// http://qrayg.com - -var uniTipTag = "*"; //Which tag do you want to uniTip-ize? Keep it lowercase. No spaces around commas.// -var uniTipClass = ""; //Which classes do you want to uniTip-ize? If you leave this blank, then all the tags designated above will get uniTip-ized. Match case. No spaces around commas. - -var uniTipX = 0; // X offset from cursor// -var uniTipY = 15; // Y offset from cursor// - -//______________________________________________There's no need to edit anything below this line// - -var offsetX = uniTipX, offsetY = uniTipY, elewidth = null, eleheight = null, tipid = null, tiptop = null, tipbot = null, tipcapin=null, tippointin=null, altText=false; - -var x=0, y=0, WinWidth=0, WinHeight=0, TipWidth=0, TipHeight=0, CapHeight=0, PointHeight=0; - -// first, find all the correct elements -init = function () { - var elementList = uniTipTag.split(","); - for(var j = 0; j < elementList.length; j++) { - var elements = document.getElementsByTagName(elementList[j]); - - if(elements) { - for (var i = 0; i < elements.length; i ++) { - if (uniTipClass != '') { - - var elClass = elements[i].className; - var elClassList = uniTipClass.split(","); - - for (var h=0; h < elClassList.length; h++) { if (elClass.match(elClassList[h])) unitipize(elements[i]); } - - } else unitipize(elements[i]); - } - } - } -} - -// next, add the tooltip function to those elements -unitipize = function (element) { - var a = element; - var id = a.getAttribute('id'); - - if (id != null && id.indexOf('recaptcha_') == 0) { - return; - } - - //altText = (a.alt && a.getAttribute("alt") != '' ) ? true : false; - //var sTitle = (altText == true) ? a.getAttribute("alt") : a.getAttribute("title"); - var sTitle = a.getAttribute('title'); - if(sTitle) { - a.onmouseover = function() {build(a, sTitle);}; - a.onmouseout = function() {hide(a, sTitle);}; - } -} - -// now, we build the tooltip -build = function (a, sTitle) { - - if (a.title) a.title = ""; - if (altText==true) a.alt = ""; - - var tipContainer = document.createElement("div"); - tipContainer.setAttribute("id", "unitip"); - document.body.appendChild(tipContainer); - - var tipContainerTop = document.createElement("div"); - tipContainerTop.setAttribute("id", "unitippoint"); - tipContainer.appendChild(tipContainerTop); - - var tipContainerMid = document.createElement("div"); - tipContainerMid.setAttribute("id", "unitipmid"); - tipContainer.appendChild(tipContainerMid); - - var tipContainerBot = document.createElement("div"); - tipContainerBot.setAttribute("id", "unitipcap"); - tipContainer.appendChild(tipContainerBot); - - tipid = document.getElementById("unitip"); - tippoint = document.getElementById("unitippoint"); - tipmid = document.getElementById("unitipmid"); - tipcap = document.getElementById("unitipcap"); - - document.getElementById("unitipmid").innerHTML = sTitle; - tipid.style.display = "block"; - - elewidth = document.getElementById("unitipmid").offsetWidth; - eleheight = document.getElementById("unitip").offsetHeight; - - WinWidth = document.body.offsetWidth; - WinHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight; - - CapHeight = document.getElementById('unitipcap').offsetHeight; - PointHeight = document.getElementById('unitippoint').offsetHeight; - - if (typeof pngfix=="function") { // if IE, rebuilds wraps unitippoint and unitipcap in outer div - if (tippoint.currentStyle.backgroundImage.match(/\.png/gi)) { - var tipP = tippoint.innerHTML; - - tippoint.id = 'unitipP'; // switch unitippoint to outer div - - tippoint.style.overflow = "hidden"; - tippoint.style.height = PointHeight + "px"; - tippoint.style.width = elewidth + "px"; - tippoint.style.position = "relative"; - tippoint.style.display = "block"; - - tippoint.innerHTML = '
' + tipP + '
'; // inject unitippoint - - tippointin = document.getElementById("unitippoint"); // redefine styles for unitippoint to fit filter image - tippointin.style.width = (elewidth * 2) + "px"; - tippointin.style.height = (PointHeight * 2) + "px"; - tippointin.style.backgroundImage = tippoint.style.backgroundImage; - tippointin.style.position = "absolute"; - - tippoint.style.backgroundImage = "none"; - } - if (tipcap.currentStyle.backgroundImage.match(/\.png/gi)) { - var tipC = tipcap.innerHTML; - - tipcap.id = 'unitipC'; - - tipcap.style.overflow = "hidden"; - tipcap.style.height = CapHeight + "px"; - tipcap.style.width = elewidth + "px"; - tipcap.style.position = "relative"; - tipcap.style.display = "block"; - - tipcap.innerHTML = '
' + tipP + '
'; - - tipcapin = document.getElementById("unitipcap"); - tipcapin.style.height = (CapHeight * 2) + "px"; - tipcapin.style.backgroundImage = tipcap.style.backgroundImage; - tipcapin.style.position = "absolute"; - - tipcap.style.backgroundImage = "none"; - } - - pngfix(); // png fix - - } - - document.onmousemove = function (evt) {move (evt)}; -} - -// now, we track the mouse and make the tooltip follow -move = function (evt) { - - if (window.event) { - x = window.event.clientX; - y = window.event.clientY; - - if (document.documentElement.scrollLeft) tipid.style.left = (TipWidth >= WinWidth ) ? ((x - offsetX - elewidth) + document.documentElement.scrollLeft) + "px" : (x + offsetX + document.documentElement.scrollLeft) + "px"; - else tipid.style.left = (TipWidth >= WinWidth ) ? ((x - offsetX - elewidth) + document.body.scrollLeft) + "px" : (x + offsetX + document.body.scrollLeft) + "px"; - - if (document.documentElement.scrollTop) tipid.style.top = (TipHeight >= WinHeight) ? ((y - offsetY - eleheight) + document.documentElement.scrollTop) + "px" : (y + offsetY + document.documentElement.scrollTop) + "px"; - else tipid.style.top = (TipHeight >= WinHeight) ? ((y - offsetY - eleheight) + document.body.scrollTop) + "px" : (y + offsetY + document.body.scrollTop) + "px"; - - } else { - x = evt.clientX; - y = evt.clientY; - - tipid.style.left = (TipWidth >= WinWidth ) ? ((x - offsetX - elewidth) + window.scrollX) + "px" : (x + offsetX + window.scrollX) + "px"; - tipid.style.top = (TipHeight >= WinHeight) ? ((y - offsetY - eleheight) + window.scrollY) + "px" : (y + offsetY + window.scrollY) + "px"; - } - - TipWidth = x + elewidth + 20; - TipHeight = y + eleheight + 20; - - if (TipHeight >= WinHeight ) { // rearrange the inner divs [123 to 321] - tipid.removeChild(tippoint); - tipid.removeChild(tipmid); - tipid.removeChild(tipcap); - tipid.appendChild(tipcap); - tipid.appendChild(tipmid); - tipid.appendChild(tippoint); - } else { // rearrange the inner divs [321 to 123] - tipid.removeChild(tippoint); - tipid.removeChild(tipmid); - tipid.removeChild(tipcap); - tipid.appendChild(tippoint); - tipid.appendChild(tipmid); - tipid.appendChild(tipcap); - } - - if (TipHeight >= WinHeight) { - - if (document.getElementById('uniTipP')) { - tippointin.style.left = (TipWidth >= WinWidth ) ? "-" + elewidth + "px" : "0px"; - tippointin.style.top = "-" + PointHeight + "px"; - } else tippoint.style.backgroundPosition = (TipWidth >= WinWidth ) ? "right bottom" : "left bottom"; - - if (document.getElementById('uniTipC')) tipcapin.style.top = "-" + CapHeight + "px"; - else tipcap.style.backgroundPosition = "0 -" + CapHeight + "px"; - - } else { - - if (document.getElementById('uniTipP')) { - tippointin.style.left = (TipWidth >= WinWidth ) ? "-" + elewidth + "px" : "0px"; - tippointin.style.top = "0px"; - } else tippoint.style.backgroundPosition = (TipWidth >= WinWidth ) ? "right top" : "left top"; - - if (document.getElementById('uniTipC')) tipcapin.style.top = "0px"; - else tipcap.style.backgroundPosition = "0 0"; - - } -} - -// lastly, hide the tooltip -hide = function (a, sTitle) { - document.getElementById("unitipmid").innerHTML = ""; - document.onmousemove = ''; - document.body.removeChild(tipid); - tipid.style.display = "none"; - if (altText==false) a.setAttribute("title", sTitle); - else a.setAttribute("alt", sTitle); - altText=false; -} - -// add the event to the page -if (window.addEventListener) window.addEventListener("load", init, false); -if (window.attachEvent) window.attachEvent("onload", init); diff --git a/themes/bootstrap/js/flux.unitpngfix.js b/themes/bootstrap/js/flux.unitpngfix.js deleted file mode 100644 index 227e71a70..000000000 --- a/themes/bootstrap/js/flux.unitpngfix.js +++ /dev/null @@ -1,4 +0,0 @@ -var clear="img/clear.gif" //path to clear.gif - -pngfix=function(){var els=document.getElementsByTagName('*');var ip=/\.png/i;var i=els.length;while(i-- >0){var el=els[i];var es=el.style;if(el.src&&el.src.match(ip)&&!es.filter){es.height=el.height;es.width=el.width;es.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+el.src+"',sizingMethod='crop')";el.src=clear;}else{var elb=el.currentStyle.backgroundImage;if(elb.match(ip)){var path=elb.split('"');var rep=(el.currentStyle.backgroundRepeat=='no-repeat')?'crop':'scale';es.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+path[1]+"',sizingMethod='"+rep+"')";es.height=el.clientHeight+'px';es.backgroundImage='none';var elkids=el.getElementsByTagName('*');if (elkids){var j=elkids.length;if(el.currentStyle.position!="absolute")es.position='static';while (j-- >0)if(!elkids[j].style.position)elkids[j].style.position="relative";}}}}} -window.attachEvent('onload',pngfix); diff --git a/themes/default/account/create.php b/themes/default/account/create.php index 64e6c2b51..c9e45ebdd 100644 --- a/themes/default/account/create.php +++ b/themes/default/account/create.php @@ -40,32 +40,32 @@ - + - + - + - + - + - + - + - + - + @@ -76,14 +76,18 @@

- + dateField('birthdate',null,0) ?> - + + + +
+
@@ -93,16 +97,17 @@
- +
+ - + diff --git a/themes/default/account/index.php b/themes/default/account/index.php index 5985c0bcb..30891b617 100644 --- a/themes/default/account/index.php +++ b/themes/default/account/index.php @@ -5,21 +5,21 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... - + ... - + ... - + ... - + ... - +

@@ -61,7 +61,7 @@ - + ... get('use_birthdate_after')) echo ' checked="checked"' ?> /> diff --git a/themes/default/account/login.php b/themes/default/account/login.php index 1b2c9a03d..d35df218a 100644 --- a/themes/default/account/login.php +++ b/themes/default/account/login.php @@ -16,7 +16,7 @@ - + diff --git a/themes/default/account/transfer.php b/themes/default/account/transfer.php index 009f8cfa9..2e57e862b 100644 --- a/themes/default/account/transfer.php +++ b/themes/default/account/transfer.php @@ -13,12 +13,12 @@
- + - + diff --git a/themes/default/account/view.php b/themes/default/account/view.php index ddf9b06ac..d9e11442e 100644 --- a/themes/default/account/view.php +++ b/themes/default/account/view.php @@ -199,6 +199,9 @@ allowedToModifyCharPrefs) && $auth->actionAllowed('character', 'prefs')): ?> + + + zeny; ?> @@ -215,10 +218,10 @@ guild_name): ?> - guild_emblem_len): ?> + emblem): ?> - guild_emblem_len) echo ' colspan="2"' ?>> + emblem) echo ' colspan="2"' ?>> actionAllowed('guild', 'view')): ?> linkToGuild($char->guild_id, $char->guild_name) ?> @@ -243,6 +246,18 @@ class="block-link"> + +

job_level ?> zeny) ?> + + + + + + + +
@@ -266,6 +281,9 @@ class="block-link"> + isRenewal): ?> + + Extra @@ -307,8 +325,8 @@ class="block-link"> card0 == 255 && array_key_exists($item->card1%1280, $itemAttributes)): ?> card1%1280]) ?> - name_japanese): ?> - name_japanese) ?> + name_english): ?> + name_english) ?> @@ -332,7 +350,7 @@ class="block-link"> - card0 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card0 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card0])): ?> actionAllowed('item', 'view')): ?> linkToItem($item->card0, $cards[$item->card0]) ?> @@ -351,7 +369,7 @@ class="block-link"> - card1 && ($item->type == 4 || $item->type == 5) && $item->card0 != 255 && $item->card0 != -256): ?> + card1 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 255 && $item->card0 != -256): ?> card1])): ?> actionAllowed('item', 'view')): ?> linkToItem($item->card1, $cards[$item->card1]) ?> @@ -370,7 +388,7 @@ class="block-link"> - card2 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card2 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card2])): ?> actionAllowed('item', 'view')): ?> linkToItem($item->card2, $cards[$item->card2]) ?> @@ -389,7 +407,7 @@ class="block-link"> - card3 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card3 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card3])): ?> actionAllowed('item', 'view')): ?> linkToItem($item->card3, $cards[$item->card3]) ?> @@ -407,6 +425,17 @@ class="block-link"> + isRenewal): ?> + + rndopt): ?> +

    + rndopt as $rndopt) echo "
  • ".$this->itemRandOption($rndopt[0], $rndopt[1])."
  • "; ?> +
+ + None + + + bound == 1):?> Account Bound diff --git a/themes/default/cashshop/add.php b/themes/default/cashshop/add.php index 4e62edb66..66831dcac 100644 --- a/themes/default/cashshop/add.php +++ b/themes/default/cashshop/add.php @@ -27,7 +27,7 @@ - + diff --git a/themes/default/castle/index.php b/themes/default/castle/index.php index 1fe335f2e..a454079d0 100644 --- a/themes/default/castle/index.php +++ b/themes/default/castle/index.php @@ -7,19 +7,22 @@ Castle ID Castle Guild + Economy castle_id) ?> castle_id]) ?> guild_name): ?> - emblem_len): ?> + emblem): ?> actionAllowed('guild', 'view') && $auth->allowedToViewGuild): ?> linkToGuild($castle->guild_id, $castle->guild_name) ?> + economy; ?> guild_name) ?> + @@ -29,6 +32,7 @@ + diff --git a/themes/default/character/index.php b/themes/default/character/index.php index e49802bc8..b46298b64 100644 --- a/themes/default/character/index.php +++ b/themes/default/character/index.php @@ -5,16 +5,16 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... - + ... - +

@@ -23,7 +23,7 @@ - + ... - + ... - +

- + ... - + ... - + ... - + ... - +

@@ -71,7 +71,7 @@ - + @@ -124,10 +124,10 @@ job_level) ?> zeny) ?> guild_name): ?> - guild_emblem_len): ?> + emblem): ?> - guild_emblem_len) echo ' colspan="2"' ?>> + emblem) echo ' colspan="2"' ?>> actionAllowed('guild', 'view') && $auth->allowedToViewGuild): ?> linkToGuild($char->guild_id, $char->guild_name) ?> diff --git a/themes/default/character/online.php b/themes/default/character/online.php index 81abaffa6..eef62557d 100644 --- a/themes/default/character/online.php +++ b/themes/default/character/online.php @@ -7,13 +7,13 @@ moduleActionFormInputs($params->get('module'), $params->get('action')) ?>

- + ... - + ... - + @@ -53,10 +53,10 @@ base_level) ?> job_level) ?> guild_name): ?> - guild_emblem_len): ?> + emblem): ?> - guild_emblem_len) echo ' colspan="2"' ?>> + emblem) echo ' colspan="2"' ?>> actionAllowed('guild', 'view') && $auth->allowedToViewGuild): ?> linkToGuild($char->guild_id, $char->guild_name) ?> diff --git a/themes/default/character/view.php b/themes/default/character/view.php index 11857aae0..3ca358691 100644 --- a/themes/default/character/view.php +++ b/themes/default/character/view.php @@ -125,10 +125,10 @@ Guild Name guild_name): ?> - guild_emblem_len): ?> + emblem): ?> - guild_emblem_len) echo ' colspan="2"' ?>> + emblem) echo ' colspan="2"' ?>> actionAllowed('guild', 'view')): ?> linkToGuild($char->guild_id, $char->guild_name) ?> @@ -257,14 +257,24 @@ base_level) ?> job_level) ?> guild_name): ?> - - - actionAllowed('guild', 'view') && $partyMember->guild_id == $char->guild_id) || $auth->allowedToViewGuild): ?> - linkToGuild($partyMember->guild_id, $partyMember->guild_name) ?> - - guild_name) ?> - - + emblem): ?> + + + actionAllowed('guild', 'view') && $partyMember->guild_id == $char->guild_id) || $auth->allowedToViewGuild): ?> + linkToGuild($partyMember->guild_id, $partyMember->guild_name) ?> + + guild_name) ?> + + + + + actionAllowed('guild', 'view') && $partyMember->guild_id == $char->guild_id) || $auth->allowedToViewGuild): ?> + linkToGuild($partyMember->guild_id, $partyMember->guild_name) ?> + + guild_name) ?> + + + None @@ -313,10 +323,10 @@ base_level) ?> job_level) ?> guild_name): ?> - guild_emblem_len): ?> + emblem): ?> - guild_emblem_len) echo ' colspan="2"' ?>> + emblem) echo ' colspan="2"' ?>> actionAllowed('guild', 'view') && $friend->guild_id == $char->guild_id) || $auth->allowedToViewGuild): ?> linkToGuild($friend->guild_id, $friend->guild_name) ?> @@ -350,10 +360,13 @@ Amount Identified Broken - Card0 - Card1 - Card2 - Card3 + Slot 1 + Slot 2 + Slot 3 + Slot 4 + isRenewal): ?> + + Extra @@ -388,8 +401,8 @@ card0 == 255 && array_key_exists($item->card1%1280, $itemAttributes)): ?> card1%1280]) ?> - name_japanese): ?> - name_japanese) ?> + name_english): ?> + name_english) ?> Unknown Item @@ -413,7 +426,7 @@ - card0 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card0 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card0])): ?> linkToItem($item->card0, $cards[$item->card0]) ?> @@ -424,7 +437,7 @@ - card1 && ($item->type == 4 || $item->type == 5) && $item->card0 != 255 && $item->card0 != -256): ?> + card1 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 255 && $item->card0 != -256): ?> card1])): ?> linkToItem($item->card1, $cards[$item->card1]) ?> @@ -435,7 +448,7 @@ - card2 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card2 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card2])): ?> linkToItem($item->card2, $cards[$item->card2]) ?> @@ -446,7 +459,7 @@ - card3 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card3 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card3])): ?> linkToItem($item->card3, $cards[$item->card3]) ?> @@ -456,6 +469,17 @@ None + isRenewal): ?> + + rndopt): ?> +

    + rndopt as $rndopt) echo "
  • ".$this->itemRandOption($rndopt[0], $rndopt[1])."
  • "; ?> +
+ + None + + + bound == 1):?> Account Bound @@ -486,10 +510,13 @@ Amount Identified Broken - Card0 - Card1 - Card2 - Card3 + Slot 1 + Slot 2 + Slot 3 + Slot 4 + isRenewal): ?> + + Extra @@ -525,8 +552,8 @@ card0 == 255 && array_key_exists($item->card1%1280, $itemAttributes)): ?> card1%1280]) ?> - name_japanese): ?> - name_japanese) ?> + name_english): ?> + name_english) ?> Unknown Item @@ -550,7 +577,7 @@ - card0 && ($cart_item->type == 4 || $cart_item->type == 5) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> + card0 && ($cart_item->type == $type_list['armor'] || $cart_item->type == $type_list['weapon']) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> card0])): ?> linkToItem($cart_item->card0, $cart_cards[$cart_item->card0]) ?> @@ -561,7 +588,7 @@ - card1 && ($cart_item->type == 4 || $cart_item->type == 5) && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> + card1 && ($cart_item->type == $type_list['armor'] || $cart_item->type == $type_list['weapon']) && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> card1])): ?> linkToItem($cart_item->card1, $cart_cards[$cart_item->card1]) ?> @@ -572,7 +599,7 @@ - card2 && ($cart_item->type == 4 || $cart_item->type == 5) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> + card2 && ($cart_item->type == $type_list['armor'] || $cart_item->type == $type_list['weapon']) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> card2])): ?> linkToItem($cart_item->card2, $cart_cards[$cart_item->card2]) ?> @@ -583,7 +610,7 @@ - card3 && ($cart_item->type == 4 || $cart_item->type == 5) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> + card3 && ($cart_item->type == $type_list['armor'] || $cart_item->type == $type_list['weapon']) && $cart_item->card0 != 254 && $cart_item->card0 != 255 && $cart_item->card0 != -256): ?> card3])): ?> linkToItem($cart_item->card3, $cart_cards[$cart_item->card3]) ?> @@ -593,14 +620,25 @@ None + isRenewal): ?> + + rndopt): ?> +
    + rndopt as $rndopt) echo "
  • ".$this->itemRandOption($rndopt[0], $rndopt[1])."
  • "; ?> +
+ + None + + + - bound == 1):?> + bound == 1):?> Account Bound - bound == 2):?> + bound == 2):?> Guild Bound - bound == 3):?> + bound == 3):?> Party Bound - bound == 4):?> + bound == 4):?> Character Bound None diff --git a/themes/default/cplog/ban.php b/themes/default/cplog/ban.php index b7f271e06..bf64d2b52 100644 --- a/themes/default/cplog/ban.php +++ b/themes/default/cplog/ban.php @@ -5,10 +5,10 @@ moduleActionFormInputs($params->get('module'), $params->get('action')) ?>

- + ... - + ... + ... - + ... - + ... - +

- + ... - + diff --git a/themes/default/cplog/changepass.php b/themes/default/cplog/changepass.php index b7d3c4a8c..f06f19956 100644 --- a/themes/default/cplog/changepass.php +++ b/themes/default/cplog/changepass.php @@ -13,13 +13,13 @@

- + ... - + ... - + allowedToSearchCpChangePass): ?> @@ -29,10 +29,10 @@ allowedToSearchCpChangePass): ?>

- + ... - + diff --git a/themes/default/cplog/create.php b/themes/default/cplog/create.php index e7dde78d4..2c3c8db20 100644 --- a/themes/default/cplog/create.php +++ b/themes/default/cplog/create.php @@ -13,18 +13,18 @@ allowedToSearchCpLoginLogPw): ?> ... - +

- + ... - + ... - + ... diff --git a/themes/default/cplog/ipban.php b/themes/default/cplog/ipban.php index 1e904fa33..f9d479ccf 100644 --- a/themes/default/cplog/ipban.php +++ b/themes/default/cplog/ipban.php @@ -5,10 +5,10 @@ moduleActionFormInputs($params->get('module'), $params->get('action')) ?>

- + ... - + ... +

- + ... - + ... - + ... + ... - + ... - + ... - +

@@ -23,7 +23,7 @@ - + ... - + ... - +

diff --git a/themes/default/cplog/resetpass.php b/themes/default/cplog/resetpass.php index 739ca466f..2c80d613f 100644 --- a/themes/default/cplog/resetpass.php +++ b/themes/default/cplog/resetpass.php @@ -21,16 +21,16 @@

- + ... - + ... - + ... - + allowedToSearchCpResetPass): ?> @@ -40,10 +40,10 @@ allowedToSearchCpResetPass): ?>

- + ... - + diff --git a/themes/default/donate/index.php b/themes/default/donate/index.php index f6aff362f..370e2d916 100644 --- a/themes/default/donate/index.php +++ b/themes/default/donate/index.php @@ -51,7 +51,7 @@ diff --git a/themes/default/guild/index.php b/themes/default/guild/index.php index 3f7ed1b1c..784abbf44 100644 --- a/themes/default/guild/index.php +++ b/themes/default/guild/index.php @@ -5,16 +5,16 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... - + ... - +

@@ -23,7 +23,7 @@ - + ... - + ... - +

@@ -48,7 +48,7 @@ - + @@ -76,7 +76,7 @@ guild_id) ?> - emblem_len): ?> + emblem): ?> guildName) ?> diff --git a/themes/default/guild/view.php b/themes/default/guild/view.php index da55d4f17..50bae9f5d 100644 --- a/themes/default/guild/view.php +++ b/themes/default/guild/view.php @@ -9,7 +9,7 @@ Guild Name name) ?> Emblem ID - emblem_id) ?> + emblem) ?> @@ -215,10 +215,13 @@ Amount Identified Broken - Card0 - Card1 - Card2 - Card3 + Slot 1 + Slot 2 + Slot 3 + Slot 4 + isRenewal): ?> + + Extra @@ -254,8 +257,8 @@ card0 == 255 && array_key_exists($item->card1%1280, $itemAttributes)): ?> card1%1280]) ?> - name_japanese): ?> - name_japanese) ?> + name_english): ?> + name_english) ?> Unknown Item @@ -279,7 +282,7 @@ - card0 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card0 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card0])): ?> linkToItem($item->card0, $cards[$item->card0]) ?> @@ -290,7 +293,7 @@ - card1 && ($item->type == 4 || $item->type == 5) && $item->card0 != 255 && $item->card0 != -256): ?> + card1 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 255 && $item->card0 != -256): ?> card1])): ?> linkToItem($item->card1, $cards[$item->card1]) ?> @@ -301,7 +304,7 @@ - card2 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card2 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card2])): ?> linkToItem($item->card2, $cards[$item->card2]) ?> @@ -312,7 +315,7 @@ - card3 && ($item->type == 4 || $item->type == 5) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> + card3 && ($item->type == $type_list['armor'] || $item->type == $type_list['weapon']) && $item->card0 != 254 && $item->card0 != 255 && $item->card0 != -256): ?> card3])): ?> linkToItem($item->card3, $cards[$item->card3]) ?> @@ -322,19 +325,30 @@ None - - bound == 1):?> - Account Bound - bound == 2):?> - Guild Bound - bound == 3):?> - Party Bound - bound == 4):?> - Character Bound - - None - - + isRenewal): ?> + + rndopt): ?> +

    + rndopt as $rndopt) echo "
  • ".$this->itemRandOption($rndopt[0], $rndopt[1])."
  • "; ?> +
+ + None + + + + + bound == 1):?> + Account Bound + bound == 2):?> + Guild Bound + bound == 3):?> + Party Bound + bound == 4):?> + Character Bound + + None + + diff --git a/themes/default/ipban/add.php b/themes/default/ipban/add.php index 8d149bcf1..b8fbbced5 100644 --- a/themes/default/ipban/add.php +++ b/themes/default/ipban/add.php @@ -8,13 +8,13 @@ - + diff --git a/themes/default/item/add.php b/themes/default/item/add.php deleted file mode 100644 index 29a566853..000000000 --- a/themes/default/item/add.php +++ /dev/null @@ -1,147 +0,0 @@ - -

Add Item

-

The only required fields are the Item ID, Identifier, Name and Type fields.

-

Note: An empty NPC Sell price defaults to half of the buy price in-game.

- -

- - - -

- +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - isRenewal): ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - -
- -

- Select All | - Select None -

-
- -

- Select All | - Select None -

-
- -

- Select All | - Select None -

-
- - -
- diff --git a/themes/default/item/copy.php b/themes/default/item/copy.php deleted file mode 100644 index f36d2cb86..000000000 --- a/themes/default/item/copy.php +++ /dev/null @@ -1,40 +0,0 @@ - -

Duplicate Item

- - -

- -

Here you can copy an item into item_db2 with a new item ID.

- -
- - - - - - - - - - - - - - - - -
-

- name_japanese) ?> - actionAllowed('item', 'view')): ?> - () - - () - -

- -

Specify the new item ID you would like for the duplicate item.

-
- -

No such item found. Go back.

- diff --git a/themes/default/item/edit.php b/themes/default/item/edit.php deleted file mode 100644 index aab617071..000000000 --- a/themes/default/item/edit.php +++ /dev/null @@ -1,158 +0,0 @@ - -

Modify Item

- -

The only required fields are the Item ID, Identifier, Name and Type fields.

-

Note: An empty NPC Sell price defaults to half of the buy price in-game.

- -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - isRenewal): ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - -
- -
- -

- Select All | - Select None -

-
- -

- Select All | - Select None -

-
- - -
-
- -

No such item found. Go back.

- diff --git a/themes/default/item/index.php b/themes/default/item/index.php index 65967d7a4..c0cde9762 100644 --- a/themes/default/item/index.php +++ b/themes/default/item/index.php @@ -5,10 +5,10 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... - + ... - + ... - +

@@ -74,7 +74,7 @@ - + ... - + ... - +

@@ -99,16 +99,16 @@ - + ... isRenewal): ?> - + - + ... @@ -142,14 +142,15 @@ sortableColumn('item_id', 'Item ID') ?> sortableColumn('name', 'Name') ?> - Type + sortableColumn('type', 'Type') ?> + sortableColumn('subtype', 'SubType') ?> Equip Locations sortableColumn('price_buy', 'NPC Buy') ?> sortableColumn('price_sell', 'NPC Sell') ?> sortableColumn('weight', 'Weight') ?> sortableColumn('attack', 'Attack') ?> isRenewal): ?> - sortableColumn('matk', 'MATK') ?> + sortableColumn('magic_attack', 'MATK') ?> sortableColumn('defense', 'Defense') ?> sortableColumn('range', 'Range') ?> @@ -169,30 +170,37 @@ iconImage($item->item_id)): ?> - name) ?> + name ?: '') ?> - name) ?> + name ?: '') ?> - itemTypeText($item->type, $item->view)): ?> + itemTypeText($item->type)): ?> - Unknowntype.")" ?> + Unknown - equipLocationCombinationText($item->equip_locations)): ?> - + itemSubTypeText($item->type, $item->subtype)): ?> + - Unknownequip_locations.")" ?> + None + + + + equipLocations($item->equip_location)): ?> + + + None price_buy) ?> price_sell) ?> - weight, 1) ?> + weight ?: 0, 1) ?> attack) ?> isRenewal): ?> - matk) ?> + magic_attack) ?> defense) ?> range) ?> @@ -223,5 +231,9 @@ getHTML() ?> -

No items found. Go back.

+

No items found. Go back.

+ + errorInfo(), true)); ?> + + diff --git a/themes/default/item/view.php b/themes/default/item/view.php index 1f53ff926..9342b8423 100644 --- a/themes/default/item/view.php +++ b/themes/default/item/view.php @@ -44,7 +44,7 @@ Name name) ?> Type - itemTypeText($item->type, $item->view) ?> + itemTypeText($item->type) ?>subtype) echo ' - '.$this->itemSubTypeText($item->type, $item->subtype) ?> NPC Buy @@ -68,7 +68,7 @@ Range range) ?> Defense - defence) ?> + defense) ?> Slots @@ -86,14 +86,21 @@ Attack attack) ?> Min Equip Level - equip_level_min) ?> + + equip_level_min == 0): ?> + None + + equip_level_min) ?> + + - isRenewal): ?> - MATK - matk) ?> + isRenewal): ?> + MATK + magic_attack) ?> + Max Equip Level - + equip_level_max == 0): ?> None @@ -101,12 +108,11 @@ - Equip Locations - equipLocations($item->equip_locations)): ?> - + equipLocations($equip_locs)): ?> + None @@ -115,8 +121,8 @@ Equip Upper - equipUpper($item->equip_upper)): ?> - + equipUpper($upper)): ?> + equipUpper($upper))) ?> None @@ -125,8 +131,8 @@ Equippable Jobs - equippableJobs($item->equip_jobs)): ?> - + equippableJobs($jobs)): ?> + equippableJobs($jobs))) ?> None @@ -135,14 +141,24 @@ Equip Gender - equip_genders === '0'): ?> + gender == 'Female'): ?> Female - equip_genders === '1'): ?> + gender == 'Male'): ?> Male - equip_genders === '2'): ?> + gender == 'Both' || $item->gender == NULL): ?> Both (Male and Female) - Unknown + None + + + + + Trade restriction + + tradeRestrictions($restrictions)): ?> + tradeRestrictions($restrictions))) ?> + + None @@ -185,7 +201,7 @@ itemdesc): ?> itemdesc ?> - Unknown + None @@ -199,6 +215,7 @@ Monster ID Monster Name name) ?> Drop Chance + Can be stealed Monster Level Monster Race Monster Element @@ -218,7 +235,8 @@ - % + % + diff --git a/themes/default/itemshop/add.php b/themes/default/itemshop/add.php index 417f66dac..087979783 100644 --- a/themes/default/itemshop/add.php +++ b/themes/default/itemshop/add.php @@ -33,18 +33,18 @@ - + - + - + diff --git a/themes/default/logdata/feeding.php b/themes/default/logdata/feeding.php index de32a2f2f..853173de7 100644 --- a/themes/default/logdata/feeding.php +++ b/themes/default/logdata/feeding.php @@ -6,16 +6,16 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... - + ... - + ... toArray() as $feedtype => $typename): ?> @@ -24,10 +24,10 @@

- + ... - + ... diff --git a/themes/default/logdata/login.php b/themes/default/logdata/login.php index 79287172f..8586404d7 100644 --- a/themes/default/logdata/login.php +++ b/themes/default/logdata/login.php @@ -13,16 +13,16 @@

- + ... - + ... - + ... - + diff --git a/themes/default/logdata/pick.php b/themes/default/logdata/pick.php index 78334a3ca..ca3da1ed7 100644 --- a/themes/default/logdata/pick.php +++ b/themes/default/logdata/pick.php @@ -80,7 +80,7 @@ amount >= 0 ? '+'.number_format($pick->amount) : number_format($pick->amount) ?> refine ?> - + card0_name): ?> actionAllowed('item', 'view')): ?> @@ -98,7 +98,7 @@ - + card1_name): ?> actionAllowed('item', 'view')): ?> @@ -116,7 +116,7 @@ - + card2_name): ?> actionAllowed('item', 'view')): ?> @@ -134,7 +134,7 @@ - + card3_name): ?> actionAllowed('item', 'view')): ?> diff --git a/themes/default/monster/index.php b/themes/default/monster/index.php index 6b43656f1..7dd69ca09 100644 --- a/themes/default/monster/index.php +++ b/themes/default/monster/index.php @@ -5,14 +5,14 @@ moduleActionFormInputs($params->get('module')) ?>

- + ... - + ... @@ -60,9 +60,6 @@

- - - ...