heliotrope

This commit is contained in:
flash 2015-04-27 00:41:59 +00:00
parent 0067f88197
commit 4039201e7a
18 changed files with 618 additions and 93 deletions

View file

@ -5,9 +5,7 @@ SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP DATABASE IF EXISTS `sakura`;
CREATE DATABASE `sakura` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
USE `sakura`;
USE `flashiidev`;
DROP TABLE IF EXISTS `fii_actioncodes`;
CREATE TABLE `fii_actioncodes` (
@ -17,7 +15,7 @@ CREATE TABLE `fii_actioncodes` (
`actkey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The URL key for using this code.',
`instruction` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Things the backend should do upon using this code',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_apikeys`;
@ -50,34 +48,6 @@ CREATE TABLE `fii_config` (
`config_value` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The value, obviously.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
TRUNCATE `fii_config`;
INSERT INTO `fii_config` (`config_name`, `config_value`) VALUES
('recaptcha_public', ''),
('recaptcha_private', ''),
('charset', 'utf-8'),
('cookie_prefix', ''),
('cookie_domain', ''),
('cookie_path', '/'),
('site_style', 'yuuno'),
('manage_style', 'Manage'),
('allow_registration', '0'),
('smtp_server', ''),
('smtp_auth', ''),
('smtp_secure', ''),
('smtp_port', ''),
('smtp_username', ''),
('smtp_password', ''),
('smtp_replyto_mail', ''),
('smtp_replyto_name', ''),
('smtp_from_email', ''),
('smtp_from_name', 'Sakura Noreply'),
('sitename', 'Sakura'),
('recaptcha', '1'),
('require_activation', '1'),
('require_registration_code', '0'),
('disable_registration', '1'),
('max_reg_keys', '5'),
('mail_signature', 'Team Flashii');
DROP TABLE IF EXISTS `fii_infopages`;
CREATE TABLE `fii_infopages` (
@ -117,24 +87,26 @@ CREATE TABLE `fii_profilefields` (
`id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID used for ordering on the userpage.',
`name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Name of the field.',
`formtype` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Type attribute in the input element.',
`islink` tinyint(1) unsigned NOT NULL COMMENT 'Set if this value should be put in a href.',
`linkformat` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'If the form is a link how should it be formatted? {{ VAL }} gets replace with the value.',
`description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field displayed in the control panel.',
`additional` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Undocumented JSON array containing special options if needed (probably only going to be used for the YouTube field).',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
TRUNCATE `fii_profilefields`;
INSERT INTO `fii_profilefields` (`id`, `name`, `formtype`, `description`, `additional`) VALUES
(1, 'Website', 'url', 'URL to your website', ''),
(2, 'Twitter', 'text', 'Your @twitter Username', ''),
(3, 'GitHub', 'text', 'Your GitHub Username', ''),
(4, 'Skype', 'text', 'Your Skype Username', ''),
(5, 'YouTube', 'text', 'ID or Username excluding http://youtube.com/*/', '{\"youtubetype\": [\"checkbox\", \"I <b>don\'t</b> have a Channel Username (url looks like https://www.youtube.com/channel/UCXZcw5hw5C7Neto-T_nRXBQ).\"]}'),
(6, 'SoundCloud', 'text', 'Your SoundCloud username', ''),
(7, 'Steam', 'text', 'Your Steam Community Username (may differ from login username)', ''),
(8, 'osu!', 'text', 'Your osu! Username', ''),
(9, 'Origin', 'text', 'Your Origin User ID', ''),
(10, 'Xbox Live', 'text', 'Your Xbox User ID', ''),
(11, 'PSN', 'text', 'Your PSN User ID', '');
INSERT INTO `fii_profilefields` (`id`, `name`, `formtype`, `islink`, `linkformat`, `description`, `additional`) VALUES
(1, 'Website', 'url', 1, '{{ VAL }}', 'URL to your website', ''),
(2, 'Twitter', 'text', 1, 'https://twitter.com/{{ VAL }}', 'Your @twitter Username', ''),
(3, 'GitHub', 'text', 1, 'https://github.com/{{ VAL }}', 'Your GitHub Username', ''),
(4, 'Skype', 'text', 1, 'skype:{{ VAL }}?userinfo', 'Your Skype Username', ''),
(5, 'YouTube', 'text', 0, '', 'ID or Username excluding http://youtube.com/*/', '{\"youtubetype\": [\"checkbox\", \"I <b>don\'t</b> have a Channel Username (url looks like https://www.youtube.com/channel/UCXZcw5hw5C7Neto-T_nRXBQ).\"]}'),
(6, 'SoundCloud', 'text', 1, 'https://soundcloud.com/{{ VAL }}', 'Your SoundCloud username', ''),
(7, 'Steam', 'text', 1, 'https://steamcommunity.com/id/{{ VAL }}', 'Your Steam Community Username (may differ from login username)', ''),
(8, 'osu!', 'text', 1, 'https://osu.ppy.sh/u/{{ VAL }}', 'Your osu! Username', ''),
(9, 'Origin', 'text', 0, '', 'Your Origin User ID', ''),
(10, 'Xbox Live', 'text', 1, 'https://account.xbox.com/en-GB/Profile?Gamertag={{ VAL }}', 'Your Xbox User ID', ''),
(11, 'PSN', 'text', 1, 'http://psnprofiles.com/{{ VAL }}', 'Your PSN User ID', '');
DROP TABLE IF EXISTS `fii_ranks`;
CREATE TABLE `fii_ranks` (
@ -144,20 +116,21 @@ CREATE TABLE `fii_ranks` (
`colour` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Colour used for the username of a member of this rank.',
`description` text COLLATE utf8_bin NOT NULL COMMENT 'A description of what a user of this rank can do/is supposed to do.',
`title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Default user title if user has none set.',
`is_premium` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Flag to set if the user group is a premium group.',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
TRUNCATE `fii_ranks`;
INSERT INTO `fii_ranks` (`id`, `name`, `multi`, `colour`, `description`, `title`) VALUES
(1, 'Deactivated', 0, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated'),
(2, 'Regular user', 1, 'inherit', 'Regular users with regular permissions.', 'Regular user'),
(3, 'Site moderator', 1, '#0A0', 'Users with special permissions like being able to ban and modify users if needed.', 'Staff'),
(4, 'Administrator', 1, '#C00', 'Users that manage the server and everything around that.', 'Administrator'),
(5, 'Developer', 1, '#824CA0', 'Users that either create or test new features of the site.', 'Staff'),
(6, 'Bot', 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot'),
(7, 'Chat moderator', 1, '#09F', 'Moderators of the chat room.', 'Staff'),
(8, 'Tenshi', 0, '#EE9400', 'Users that donated $5.00 or more in order to keep the site and it\'s services alive!', 'Tenshi'),
(9, 'Alumnii', 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii');
INSERT INTO `fii_ranks` (`id`, `name`, `multi`, `colour`, `description`, `title`, `is_premium`) VALUES
(1, 'Deactivated', 0, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated', 0),
(2, 'Regular user', 1, 'inherit', 'Regular users with regular permissions.', 'Regular user', 0),
(3, 'Site moderator', 1, '#0A0', 'Users with special permissions like being able to ban and modify users if needed.', 'Staff', 1),
(4, 'Administrator', 1, '#C00', 'Users that manage the server and everything around that.', 'Administrator', 1),
(5, 'Developer', 1, '#824CA0', 'Users that either create or test new features of the site.', 'Staff', 1),
(6, 'Bot', 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot', 0),
(7, 'Chat moderator', 1, '#09F', 'Moderators of the chat room.', 'Staff', 1),
(8, 'Tenshi', 0, '#EE9400', 'Users that donated $5.00 or more in order to keep the site and it\'s services alive!', 'Tenshi', 1),
(9, 'Alumnii', 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii', 1);
DROP TABLE IF EXISTS `fii_regcodes`;
CREATE TABLE `fii_regcodes` (
@ -181,7 +154,7 @@ CREATE TABLE `fii_sessions` (
`expire` int(64) unsigned NOT NULL COMMENT 'The timestamp for when this session should end, -1 for permanent. ',
`remember` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'If set to 1 session will be extended each time a page is loaded.',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_tenshi`;
@ -223,7 +196,7 @@ CREATE TABLE `fii_users` (
`profile_data` text COLLATE utf8_bin NOT NULL COMMENT 'Modular array containing profile data.',
PRIMARY KEY (`id`),
UNIQUE KEY `username_clean` (`username_clean`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_warnings`;
@ -238,4 +211,4 @@ CREATE TABLE `fii_warnings` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- 2015-04-19 12:58:09
-- 2015-04-27 00:38:20

View file

@ -2,6 +2,18 @@
"versions": {
"Heliotrope": {
"colour": "#DF73FF",
"builds": [
"20150427"
]
},
"Cyan": {
"colour": "#4EC9B0",
@ -594,10 +606,6 @@
"20150426": [
{
"type": "ADD",
"change": "Begin work on profile system."
},
{
"type": "FIX",
"change": "The system thinking 0 is the rank ID for deactivated while it's 1."
@ -611,6 +619,59 @@
"change": "Add changelog page."
}
],
"20150427": [
{
"type": "ADD",
"change": "Begin work on profile system."
},
{
"type": "ADD",
"change": "Created function to get profile data from a user."
},
{
"type": "UPD",
"change": "Made profile data display properly."
},
{
"type": "FIX",
"change": "Fix rank title not displaying on profiles."
},
{
"type": "ADD",
"change": "Show country name on profile."
},
{
"type": "ADD",
"change": "Show tenshi tag on user's profile if they're tenshi."
},
{
"type": "FIX",
"change": "Actually update last online date."
},
{
"type": "FIX",
"change": "Activation broken methods in the activation process."
},
{
"type": "ADD",
"change": "Add glow around a user's avatar on their profile if they're online or offline (active in the last 5 minutes)."
},
{
"type": "ADD",
"change": "Show all online users on the frontpage."
},
{
"type": "FIX",
"change": "Fix JavaScript forms not submitting on hitting enter."
},
{
"type": "FIX",
"change": "Fix chat redirect."
}
]
}

View file

@ -199,14 +199,22 @@ class Main {
}
// Cleaning strings
public static function cleanString($string, $lower = false) {
public static function cleanString($string, $lower = false, $nospecial = false) {
// Run common sanitisation function over string
$string = htmlentities($string, ENT_QUOTES | ENT_IGNORE, Configuration::getConfig('charset'));
$string = stripslashes($string);
$string = strip_tags($string);
// If set also make the string lowercase
if($lower)
$string = strtolower($string);
// If set remove all characters that aren't a-z or 0-9
if($nospecial)
$string = preg_replace('/[^a-z0-9]/', '', $string);
// Return clean string
return $string;
}
@ -481,4 +489,18 @@ class Main {
}
// Get country name from ISO 3166 code
public static function getCountryName($code) {
// Parse JSON file
$iso3166 = json_decode(file_get_contents(Configuration::getLocalConfig('etc', 'iso3166')), true);
// Check if key exists
if(array_key_exists($code, $iso3166))
return $iso3166[$code]; // If entry found return the full name
else
return 'Unknown'; // Else return unknown
}
}

View file

@ -32,7 +32,8 @@ class Users {
'lastdate' => 0,
'lastunamechange' => 0,
'birthday' => '',
'profile_data' => '[]'
'country' => 'EU',
'profile_data' => ''
];
// Empty rank template
@ -41,7 +42,8 @@ class Users {
'rankname' => 'Non-existent Rank',
'multi' => 0,
'colour' => '#444',
'description' => 'A hardcoded dummy rank for fallback.'
'description' => 'A hardcoded dummy rank for fallback.',
'is_premium' => 0
];
// Check if a user is logged in
@ -69,6 +71,16 @@ class Users {
}
// Update last online
Database::update('users', [
[
'lastdate' => time()
],
[
'id' => [Session::$userId, '=']
]
]);
// Redirect people that need to change their password to the new format
if(self::getUser(Session::$userId)['password_algo'] == 'legacy' && $_SERVER['PHP_SELF'] != '/authenticate.php' && $_SERVER['PHP_SELF'] != '/imageserve.php')
header('Location: /authenticate.php?legacy=true');
@ -235,7 +247,7 @@ class Users {
'lastdate' => 0,
'lastunamechange' => time(),
'country' => Main::getCountryCode(),
'profile_data' => '[]'
'profile_data' => ''
]);
// Get userid of the new user
@ -435,7 +447,7 @@ class Users {
return [0, 'USER_NOT_EXIST'];
// Check if a user is activated
if($user['rank_main'])
if(!in_array(1, json_decode($user['ranks'], true)) || !in_array(0, json_decode($user['ranks'], true)) || $user['rank_main'] > 1)
return [0, 'USER_ALREADY_ACTIVE'];
// Send activation e-mail
@ -453,7 +465,7 @@ class Users {
$user = Database::fetch('users', false, ['id' => [$uid, '=']]);
// User is already activated or doesn't even exist
if(!count($user) > 1 || !in_array(1, json_decode($user['ranks'], true)) || !in_array(0, json_decode($user['ranks'], true)) || $user['rank_main'] > 1)
if(count($user) < 2 || (!in_array(1, json_decode($user['ranks'], true)) || !in_array(0, json_decode($user['ranks'], true))) || $user['rank_main'] > 1)
return false;
// Generate activation key
@ -642,6 +654,125 @@ class Users {
}
// Get user's profile fields
public static function getUserProfileData($id) {
// Get profile fields
$profileFields = Database::fetch('profilefields');
// If there's nothing just return null
if(!count($profileFields))
return null;
// Get the profile data JSON from the specified user's profile
$profileData = Database::fetch('users', false, ['id' => [$id, '=']]);
// Once again if nothing was returned just return null
if(count($profileData) < 2 || $profileData['profile_data'] == null || !count(json_decode($profileData['profile_data'], true)))
return null;
// Decode the profile_data json
$profileData = json_decode($profileData['profile_data'], true);
// Create output array
$profile = [];
// Check if profile fields aren't fake
foreach($profileFields as $field) {
// Completely strip all special characters from the field name
$fieldName = Main::cleanString($field['name'], true, true);
// Check if the user has the current field set otherwise continue
if(!array_key_exists($fieldName, $profileData))
continue;
// Assign field to output with value
$profile[$fieldName] = array();
$profile[$fieldName]['name'] = $field['name'];
$profile[$fieldName]['value'] = $profileData[$fieldName];
$profile[$fieldName]['islink'] = $field['islink'];
// If the field is set to be a link add a value for that as well
if($field['islink'])
$profile[$fieldName]['link'] = str_replace('{{ VAL }}', $profileData[$fieldName], $field['linkformat']);
// Check if we have additional options as well
if($field['additional'] != null) {
// Decode the json of the additional stuff
$additional = json_decode($field['additional'], true);
// Go over all additional forms
foreach($additional as $subName => $subField) {
// Check if the user has the current field set otherwise continue
if(!array_key_exists($subName, $profileData))
continue;
// Assign field to output with value
$profile[$fieldName][$subName] = $profileData[$subName];
}
}
}
// Return appropiate profile data
return $profile;
}
// Check if a user is online
public static function checkUserOnline($id) {
// Get user
$user = self::getUser($id);
// Return false if the user doesn't exist because a user that doesn't exist can't be online
if(empty($user))
return false;
// Return true if the user was online in the last 5 minutes
return ($user['lastdate'] > (time() - 500));
}
// Get all online users
public static function checkAllOnline() {
// Assign time - 500 to a variable
$time = time() - 500;
// Get all online users in the past 5 minutes
$getAll = Database::fetch('users', true, ['lastdate' => [$time, '>']]);
// Return all the online users
return $getAll;
}
// Check if user has Tenshi
public static function checkUserTenshi($id) {
// Get user's ranks
$ranks = json_decode(self::getUser($id)['ranks'], true);
// Check premium flag
foreach($ranks as $rank) {
// If premium rank was found return true
if(self::getRank($rank)['is_premium'])
return true;
}
// Else return false
return false;
}
// Get user data by id
public static function getUser($id) {

View file

@ -23,3 +23,4 @@ $sakuraConf['urls']['manage'] = 'manage.flashii.net'; // Moderator panel url
// Errata
$sakuraConf['etc']['cfhosts'] = ROOT .'_sakura/config/cloudflare.hosts'; // Cloudflare IP subnets file
$sakuraConf['etc']['whoisservers'] = ROOT .'_sakura/config/whois.json'; // JSON with Whois servers
$sakuraConf['etc']['iso3166'] = ROOT .'_sakura/config/iso3166.json'; // JSON with country codes

250
_sakura/config/iso3166.json Normal file
View file

@ -0,0 +1,250 @@
{
"_CONTRIB": "List of ISO 3166-1 alpha-2 country codes by Flashwave http://flash.moe",
"AD": "Andorra",
"AE": "United Arab Emirates",
"AF": "Afghanistan",
"AG": "Antigua and Barbuda",
"AI": "Anguilla",
"AL": "Albania",
"AM": "Armenia",
"AO": "Angola",
"AQ": "Antarctica",
"AR": "Argentina",
"AS": "American Samoa",
"AT": "Austria",
"AU": "Australia",
"AW": "Aruba",
"AX": "Åland Islands",
"AZ": "Azerbaijan",
"BA": "Bosnia and Herzegovina",
"BB": "Barbados",
"BD": "Bangladesh",
"BE": "Belgium",
"BF": "Burkina Faso",
"BG": "Bulgaria",
"BH": "Bahrain",
"BI": "Burundi",
"BJ": "Benin",
"BL": "Saint Barthélemy",
"BM": "Bermuda",
"BN": "Brunei Darussalam",
"BO": "Bolivia, Plurinational State of",
"BQ": "Bonaire, Sint Eustatius and Saba",
"BR": "Brazil",
"BS": "Bahamas",
"BT": "Bhutan",
"BV": "Bouvet Island",
"BW": "Botswana",
"BY": "Belarus",
"BZ": "Belize",
"CC": "Cocos (Keeling) Islands",
"CD": "Congo, the Democratic Republic of the",
"CF": "Central African Republic",
"CG": "Congo",
"CH": "Switzerland",
"CI": "Côte d'Ivoire",
"CK": "Cook Islands",
"CL": "Chile",
"CM": "Cameroon",
"CN": "China",
"CO": "Colombia",
"CR": "Costa Rica",
"CU": "Cuba",
"CV": "Cabo Verde",
"CW": "Curaçao",
"CX": "Christmas Island",
"CY": "Cyprus",
"CZ": "Czech Republic",
"DE": "Germany",
"DJ": "Djibouti",
"DK": "Denmark",
"DM": "Dominica",
"DO": "Dominican Republic",
"DZ": "Algeria",
"EC": "Ecuador",
"EE": "Estonia",
"EG": "Egypt",
"EH": "Western Sahara",
"ER": "Eritrea",
"ES": "Spain",
"ET": "Ethiopia",
"FI": "Finland",
"FJ": "Fiji",
"FK": "Falkland Islands (Malvinas)",
"FM": "Micronesia, Federated States of",
"FO": "Faroe Islands",
"FR": "France",
"GA": "Gabon",
"GB": "United Kingdom",
"GD": "Grenada",
"GE": "Georgia",
"GF": "French Guiana",
"GG": "Guernsey",
"GH": "Ghana",
"GI": "Gibraltar",
"GL": "Greenland",
"GM": "Gambia",
"GN": "Guinea",
"GP": "Guadeloupe",
"GQ": "Equatorial Guinea",
"GR": "Greece",
"GS": "South Georgia and the South Sandwich Islands",
"GT": "Guatemala",
"GU": "Guam",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HK": "Hong Kong",
"HM": "Heard Island and McDonald Islands",
"HN": "Honduras",
"HR": "Croatia",
"HT": "Haiti",
"HU": "Hungary",
"ID": "Indonesia",
"IE": "Ireland",
"IL": "Israel",
"IM": "Isle of Man",
"IN": "India",
"IO": "British Indian Ocean Territory",
"IQ": "Iraq",
"IR": "Iran, Islamic Republic of",
"IS": "Iceland",
"IT": "Italy",
"JE": "Jersey",
"JM": "Jamaica",
"JO": "Jordan",
"JP": "Japan",
"KE": "Kenya",
"KG": "Kyrgyzstan",
"KH": "Cambodia",
"KI": "Kiribati",
"KM": "Comoros",
"KN": "Saint Kitts and Nevis",
"KP": "Korea, Democratic People's Republic of",
"KR": "Korea, Republic of",
"KW": "Kuwait",
"KY": "Cayman Islands",
"KZ": "Kazakhstan",
"LA": "Lao People's Democratic Republic",
"LB": "Lebanon",
"LC": "Saint Lucia",
"LI": "Liechtenstein",
"LK": "Sri Lanka",
"LR": "Liberia",
"LS": "Lesotho",
"LT": "Lithuania",
"LU": "Luxembourg",
"LV": "Latvia",
"LY": "Libya",
"MA": "Morocco",
"MC": "Monaco",
"MD": "Moldova, Republic of",
"ME": "Montenegro",
"MF": "Saint Martin",
"MG": "Madagascar",
"MH": "Marshall Islands",
"MK": "Macedonia, the former Yugoslav Republic of",
"ML": "Mali",
"MM": "Myanmar",
"MN": "Mongolia",
"MO": "Macao",
"MP": "Northern Mariana Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MS": "Montserrat",
"MT": "Malta",
"MU": "Mauritius",
"MV": "Maldives",
"MW": "Malawi",
"MX": "Mexico",
"MY": "Malaysia",
"MZ": "Mozambique",
"NA": "Namibia",
"NC": "New Caledonia",
"NE": "Niger",
"NF": "Norfolk Island",
"NG": "Nigeria",
"NI": "Nicaragua",
"NL": "The Netherlands",
"NO": "Norway",
"NP": "Nepal",
"NR": "Nauru",
"NU": "Niue",
"NZ": "New Zealand",
"OM": "Oman",
"PA": "Panama",
"PE": "Peru",
"PF": "French Polynesia",
"PG": "Papua New Guinea",
"PH": "Philippines",
"PK": "Pakistan",
"PL": "Poland",
"PM": "Saint Pierre and Miquelon",
"PN": "Pitcairn",
"PR": "Puerto Rico",
"PS": "Palestine, State of",
"PT": "Portugal",
"PW": "Palau",
"PY": "Paraguay",
"QA": "Qatar",
"RE": "Réunion",
"RO": "Romania",
"RS": "Serbia",
"RU": "Russian Federation",
"RW": "Rwanda",
"SA": "Saudi Arabia",
"SB": "Solomon Islands",
"SC": "Seychelles",
"SD": "Sudan",
"SE": "Sweden",
"SG": "Singapore",
"SH": "Saint Helena, Ascension and Tristan da Cunha",
"SI": "Slovenia",
"SJ": "Svalbard and Jan Mayen",
"SK": "Slovakia",
"SL": "Sierra Leone",
"SM": "San Marino",
"SN": "Senegal",
"SO": "Somalia",
"SR": "Suriname",
"SS": "South Sudan",
"ST": "Sao Tome and Principe",
"SV": "El Salvador",
"SX": "Sint Maarten",
"SY": "Syrian Arab Republic",
"SZ": "Swaziland",
"TC": "Turks and Caicos Islands",
"TD": "Chad",
"TF": "French Southern Territories",
"TG": "Togo",
"TH": "Thailand",
"TK": "Tokelau",
"TL": "Timor-Leste",
"TM": "Turkmenistan",
"TN": "Tunisia",
"TO": "Tonga",
"TR": "Turkey",
"TT": "Trinidad and Tobago",
"TV": "Tuvalu",
"TW": "Taiwan, Province of China",
"TZ": "Tanzania, United Republic of",
"UA": "Ukraine",
"UG": "Uganda",
"UM": "United States Minor Outlying Islands",
"US": "United States",
"UY": "Uruguay",
"UZ": "Uzbekistan",
"VA": "Holy See (Vatican City State)",
"VC": "Saint Vincent and the Grenadines",
"VE": "Venezuela, Bolivarian Republic of",
"VG": "Virgin Islands, British",
"VI": "Virgin Islands, U.S.",
"VN": "Viet Nam",
"VU": "Vanuatu",
"WF": "Wallis and Futuna",
"WS": "Samoa",
"YE": "Yemen",
"YT": "Mayotte",
"ZA": "South Africa",
"ZM": "Zambia",
"ZW": "Zimbabwe"
}

View file

@ -8,10 +8,10 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20150426');
define('SAKURA_VLABEL', 'Cyan');
define('SAKURA_VERSION', '20150427');
define('SAKURA_VLABEL', 'Heliotrope');
define('SAKURA_VTYPE', 'Development');
define('SAKURA_COLOUR', '#4EC9B0');
define('SAKURA_COLOUR', '#DF73FF');
// Define Sakura Path
define('ROOT', str_replace(basename(__DIR__), '', dirname(__FILE__)));

View file

@ -11,11 +11,11 @@
<meta http-equiv="refresh" content="3; URL={{ page.redirect }}" />
{% endif %}
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="//{{ sakura.urls.content }}/global.css?s={{ php.time }}" />
<link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css?s={{ php.time }}" />
<link rel="stylesheet" type="text/css" href="//{{ sakura.urls.content }}/global.css" />
<link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css" />
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
<!-- JS -->
<script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js?s={{ php.time }}"></script>
<script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script>
<script type="text/javascript">
{% if not user.checklogin and not sakura.lockauth %}
@ -91,13 +91,12 @@
var form = document.getElementById(i);
var submit = form.querySelector('[type="submit"]');
// TODO: Make hitting the enter key submit forms
//form.setAttribute('onkeypress', '');
submit.setAttribute('href', 'javascript:void(0);');
submit.setAttribute('onclick', 'submitPost(\''+ i +'\', true, \''+ forms[i] +'\');');
submit.setAttribute('type', 'button');
form.setAttribute('onkeydown', 'formEnterCatch(event, \''+ submit.id +'\');');
var createInput = document.createElement('input');
createInput.setAttribute('name', 'ajax');
createInput.setAttribute('value', 'true');
@ -148,7 +147,7 @@
</div>
<div id="contentwrapper">
{% if not user.checklogin %}
<form method="post" action="/authenticate" class="hidden" id="headerLoginForm">
<form method="post" action="/authenticate" class="hidden" id="headerLoginForm" onkeydown="formEnterCatch(event, 'headerLoginButton');">
<input type="hidden" name="redirect" value="{{ sakura.currentpage }}" />
<input type="hidden" name="session" value="{{ php.sessionid }}" />
<input type="hidden" name="time" value="{{ php.time }}" />

View file

@ -26,6 +26,15 @@
<b><a href="/u/{{ stats.newestUser.id }}" class="default">{{ stats.newestUser.username }}</a></b> is the newest user,
it has been <b>{{ stats.lastRegDate }}</b> since the last user registered and
there are <b>{{ stats.chatOnline }}</b> in chat right now.
<div class="head">Online Users</div>
{% if stats.onlineUsers %}
All active users in the past 5 minutes:<br />
{% for amount,onlineUser in stats.onlineUsers %}
<a href="/u/{{ onlineUser.id }}" style="font-weight: bold;" class="default">{{ onlineUser.username }}</a>{% if amount != (stats.onlineUsers|length - 1) %}, {% endif %}
{% endfor %}
{% else %}
There were no online users in the past 5 minutes.
{% endif %}
</div>
<div class="content-left content-column">
<div class="head">News <a href="/news.xml" class="fa fa-rss news-rss default"></a></div>

View file

@ -5,7 +5,7 @@
There are a few possible reasons for this:
<ul style="padding-left: 40px;">
<li>They changed their username.</li>
<li>They may have been abyss'd.</li>
<li>They may have been <a href="/faq#abyss" class="default">abyss'd</a>.</li>
<li>You made a typo.</li>
<li>They never existed.</li>
</ul>
@ -14,12 +14,38 @@
<div class="content profile">
<div class="{% if profile.profpage|length > 1 %}content-right {% endif %}content-column">
<div style="text-align: center;">
<img src="/a/{{ profile.user.id }}" alt="{{ profile.user.username }}'s Avatar" class="default-avatar-setting" />
<br /><span style="font-size: .8em;">{{ profile.user.usertitle }}</span>
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px #888; padding: 0 0 10px;">{{ profile.user.username }}</h1>
<img src="/a/{{ profile.user.id }}" alt="{{ profile.user.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.online %}484{% else %}844{% endif %};" />
<br /><span style="font-size: .8em;">{{ profile.ranktitle }}</span>
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px #888; padding: 0 0 2px;">{{ profile.user.username }}</h1>
{% if profile.istenshi %}<img src="//{{ sakura.urls.content }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="//{{ sakura.urls.content }}/images/flags/{% if profile.user.country|lower == 'eu' %}europeanunion{% else %}{{ profile.user.country|lower }}{% endif %}.png" alt="{{ profile.user.country }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country }}</span>
<hr class="default" />
<b>Joined</b> {{ profile.user.regdate|date("l Y-m-d H:i") }}<br />
<b>Last Seen on</b> {{ profile.user.lastdate|date("l Y-m-d H:i") }}
<b>Joined</b> {{ profile.user.regdate|date("l Y-m-d H:i T") }}<br />
<b>Last Seen on</b> {{ profile.user.lastdate|date("l Y-m-d H:i T") }}
{% if profile.data is not null %}
<hr class="default" />
<table style="width: 100%;">
{% for name,field in profile.data %}
<tr>
<td style="text-align: left; font-weight: bold;">
{{ field.name }}
</td>
<td style="text-align: right;">
{% if name == 'youtube' %}
<a href="https://youtube.com/{% if field.youtubetype == 1 %}channel{% else %}user{% endif %}/{{ field.value }}" class="default">{{ field.value }}</a>
{% else %}
{% if field.islink %}
<a href="{{ field.link }}" class="default">
{% endif %}
{{ field.value }}
{% if field.islink %}
</a>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
<hr class="default" />
<b>Account Standing</b>
<h2 style="color: green; text-shadow: 0 0 7px #888; margin-top: 0;">Good</h2>

View file

@ -277,6 +277,25 @@ function generateForm(formId, formAttr, formData, appendTo) {
}
// Enter substitute
function formEnterCatch(key, id) {
// 13 == Enter
if(key.which == 13) {
// Submit the form
document.getElementById(id).click();
// Return true if yeah
return true;
}
// Return false if not
return false;
}
// Submitting a form using an AJAX POST request
function submitPost(formId, busyView, msg) {

View file

@ -1 +0,0 @@
/* Flashii.net Style Codename "Yuuno" */ function cookieData(e,t,a){switch(e){case"get":return(result=new RegExp("(^|; )"+encodeURIComponent(t)+"=([^;]*)").exec(document.cookie))?result[2]:"";case"set":return void(document.cookie=t+"="+a);default:return}}function mobileMenu(e){var t=document.getElementById("navMenuSite"),a=document.getElementById("navMenuUser"),n=document.getElementById("mobileNavToggle");e?(t.className=t.className+" menu-hid",a.className=a.className+" menu-hid",n.innerHTML="Close Menu",n.setAttribute("onclick","mobileMenu(false);")):(t.className=t.className.replace(" menu-hid",""),a.className=a.className.replace(" menu-hid",""),n.innerHTML="Open Menu",n.setAttribute("onclick","mobileMenu(true);"))}function epochTime(){var e=Date.now();return e/=1e3,Math.floor(e)}function donatePage(e){var t=document.getElementsByClassName("featureBoxDesc");{if(e){var a=document.getElementById(e).children[1];return a.className.search("donateOpened")>0?(a.className=a.className.replace(" donateOpened",""),void(a.className=a.className+" donateClosed")):(a.className=a.className.replace(" donateClosed",""),void(a.className=a.className+" donateOpened"))}for(var n=0;n<t.length;n++)t[n].className=t[n].className+" donateClosed"}}function switch_text(e){var t=document.getElementById("recaptcha_response_field");"audio"==e?t.setAttribute("placeholder","Enter the words you hear"):"image"==e?t.setAttribute("placeholder","Enter the words above"):t.setAttribute("placeholder","undefined rolls undefined and gets undefined")}window.onscroll=function(){var e=document.getElementById("gotop");this.pageYOffset<112?e.getAttribute("class").indexOf("hidden")<0&&e.setAttribute("class",e.getAttribute("class")+" hidden"):this.pageYOffset>112&&e.setAttribute("class",e.getAttribute("class").replace(" hidden",""))};var RecaptchaOptions={theme:"custom",custom_theme_widget:"recaptcha_widget"};

BIN
content/images/tenshi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

View file

@ -315,7 +315,7 @@ $renderData['page'] = [
$renderData['auth'] = [
'redirect' => (
isset($_REQUEST['chat']) ?
Configuration::getLocalConfig('urls', 'chat') :
'//'. Configuration::getLocalConfig('urls', 'chat') :
(
isset($_SERVER['HTTP_REFERER']) ?
$_SERVER['HTTP_REFERER'] :

View file

@ -100,7 +100,7 @@ foreach($changelog as $build => $buildData) {
}
// Get special template file
$tpl = file_get_contents(ROOT .'_sakura/templates/versionInfo.tpl');
$tpl = file_get_contents(ROOT .'_sakura/templates/changeLog.tpl');
// Parse tags
$tpl = str_replace('{{ version }}', SAKURA_VERSION, $tpl);

View file

@ -19,7 +19,8 @@ $renderData['stats'] = [
'userCount' => ($userCount = count($users = Users::getAllUsers(false))) .' user'. ($userCount == 1 ? '' : 's'),
'newestUser' => max($users),
'lastRegDate' => ($lastRegDate = date_diff(date_create(date('Y-m-d', max($users)['regdate'])), date_create(date('Y-m-d')))->format('%a')) .' day'. ($lastRegDate == 1 ? '' : 's'),
'chatOnline' => ($chatOnline = 0) .' user'. ($chatOnline == 1 ? '' : 's')
'chatOnline' => ($chatOnline = 0) .' user'. ($chatOnline == 1 ? '' : 's'),
'onlineUsers' => Users::checkAllOnline()
];
// Print page contents

View file

@ -10,7 +10,41 @@ namespace Sakura;
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php';
// Catch old profile API and return error
if(isset($_REQUEST['data']))
die(json_encode(['error' => true]));
if(isset($_REQUEST['data'])) {
var_dump(@$_REQUEST);
header('Content-Type: text/plain; charset=utf-8');
header('Access-Control-Allow-Origin: *');
print json_encode(['error' => true]);
exit;
}
// Get user data
if(isset($_GET['u'])) {
$renderData['profile'] = [
'notset' => false,
'user' => ($_PROFILE_USER_DATA = Users::getUser($_GET['u'])),
'rank' => ($_PROFILE_RANK_DATA = Users::getRank($_PROFILE_USER_DATA['rank_main'])),
'colour' => ($_PROFILE_USER_DATA['name_colour'] == null ? $_PROFILE_RANK_DATA['colour'] : $_PROFILE_USER_DATA['name_colour']),
'ranktitle' => ($_PROFILE_USER_DATA['usertitle'] == null ? $_PROFILE_RANK_DATA['title'] : $_PROFILE_USER_DATA['usertitle']),
'country' => Main::getCountryName($_PROFILE_USER_DATA['country']),
'istenshi' => Users::checkUserTenshi($_PROFILE_USER_DATA['id']),
'online' => Users::checkUserOnline($_PROFILE_USER_DATA['id']),
'profpage' => Main::mdParse(base64_decode($_PROFILE_USER_DATA['profile_md'])),
'data' => Users::getUserProfileData($_PROFILE_USER_DATA['id'])
];
$renderData['page']['title'] = ($renderData['profile']['user']['id'] < 1 ? 'User not found!' : 'Profile of '. $renderData['profile']['user']['username']);
} else {
$renderData['profile']['notset'] = true;
$renderData['page']['title'] = 'User not found!';
}
// Print page contents
print Templates::render('main/profile.tpl', $renderData);