Compare commits

...

66 Commits

Author SHA1 Message Date
e90b9cc9c4 Release new version 1.24.1 2020-10-17 12:53:00 +02:00
ede3d7938d Add language meta info and minor restructuring of code 2020-10-17 11:58:39 +02:00
8df28af021 Use $T for translation instead of verwriting $I directly 2020-10-15 22:28:01 +02:00
c3e316d412 Various minor optimizations 2020-10-15 20:46:04 +02:00
919876480d Merge pull request #81 from cypherbits/remove-request-use
For dangerous and only-POST routes check if it is POST request.
2020-10-15 17:13:48 +02:00
4e6cc8d1ab Merge pull request #86 from DanWin/DanWin-funding
Create FUNDING.yml
2020-10-15 17:12:32 +02:00
3dd5de099e Create FUNDING.yml 2020-10-15 17:12:17 +02:00
c71e17103f Fix chrome flashing white on frame reload 2020-10-15 09:43:06 +02:00
8d84e45c3c Add promise not to use any features 2020-10-15 09:42:29 +02:00
d37fc14483 Updated copyright 2020-10-15 08:26:47 +02:00
815d9f203e Improved CSP rules 2020-10-14 13:38:30 +02:00
cca830d9db Fixed syntax error 2020-09-20 21:50:37 +02:00
de04614155 Merge pull request #77 from cypherbits/work1
Little fixes
2020-09-15 20:59:20 +02:00
025709508b Fix guest room bypass #73 2020-09-15 19:37:45 +02:00
34fce5f7ab Merge pull request #75 from cypherbits/master
Fix link filters, image embeds, and redirects.
2020-09-15 18:57:01 +02:00
b7ff7c9eb7 For dangerous and only-POST routes check if it is POST request. 2020-08-05 19:15:37 +02:00
b1c7242752 Little fixes 2020-08-02 17:54:47 +02:00
51fb54e0aa Oops... 2020-08-01 22:40:42 +02:00
e5e3b478dc Fix link filters, image embeds, and redirects. 2020-08-01 21:14:39 +02:00
463d66e11e Include Turikish translation 2020-08-01 20:48:57 +02:00
ed4908b7c7 Merge pull request #70 from creuzwagen/patch-1
Create lang_tr.php
2020-08-01 20:47:41 +02:00
f8fa78f278 Update lang_tr.php
Fully completed
2020-07-15 17:49:57 +03:00
7109b5bd80 Update lang_tr.php 2020-07-14 01:18:44 +03:00
1abedd1f10 Update lang_tr.php 2020-07-14 00:30:15 +03:00
c9699362a0 Create lang_tr.php 2020-07-13 13:53:52 +00:00
cc6d36e7ce Merge pull request #66 from cypherbits/php-version-check
If encryption is enabled, check the PHP version is at least 7.2
2020-06-11 10:39:14 +02:00
217bd9b08a Merge pull request #67 from whalehub/patch-1
Fix indentation in chat.php
2020-06-11 10:36:37 +02:00
972f1a62c1 Fix indentation in chat.php 2020-05-17 14:14:44 +02:00
9ab4622b67 If encryption is enabled, check the PHP version is at least 7.2 2020-05-11 18:24:25 +02:00
62f335d220 Merge branch 'master' of https://github.com/DanWin/le-chat-php 2020-05-11 18:18:03 +02:00
43a6adfa1c Fix undefined index notice 2020-05-07 21:47:49 +02:00
e137eb81ac Updated readme 2020-05-07 21:06:16 +02:00
035cfa6aa4 Harden all cookies 2020-05-07 20:50:20 +02:00
e9a1d61027 Allow data URI for img and media in CSP 2020-05-07 20:38:17 +02:00
a4d2484e24 Merge pull request #63 from cypherbits/fix-security-header
Fix Content-Security-Policy header.
2020-05-07 20:29:27 +02:00
ac46e658bd Merge pull request #64 from cypherbits/faster-encryption-load
If admin defined keys with the right length, do not compute the keys.
2020-05-07 20:28:35 +02:00
9c5e879d7d Merge pull request #62 from cypherbits/fix-session-xss
Fix XSS in session variables.
2020-05-07 20:28:10 +02:00
b7ff54f8d1 Merge branch 'fix-security-header' 2020-05-03 17:42:29 +02:00
5aeca202ca fix 2020-05-03 17:41:56 +02:00
6189120795 Merge branches 'faster-encryption-load', 'fix-security-header' and 'fix-session-xss' 2020-05-03 17:31:10 +02:00
c2cd0258f1 If admin defined keys with the right length, do not compute the keys. 2020-05-03 15:18:41 +02:00
0f97ddd573 Fix Content-Security-Policy header. 2020-05-03 15:08:30 +02:00
81b8b78df0 Fix XSS in session variables. 2020-05-03 11:13:52 +02:00
0f3a04b4de Merge pull request #61 from cypherbits/safe-cookies
Session cookies security hardening.
2020-05-03 10:33:00 +02:00
581aede13f Session cookies security hardening. 2020-05-02 21:53:19 +02:00
e149c9f97d Fix reflected XSS vulnerability 2020-05-02 19:42:34 +02:00
1887d42a78 Merge pull request #58 from cypherbits/new-encryption
New generation AES256-GCM encryption by libsodium. PHP >= 7.2 needed
2020-05-02 18:32:50 +02:00
95fd504249 Merge pull request #60 from cypherbits/header_security
Add more security headers
2020-05-02 18:28:44 +02:00
c728d6d447 Merge pull request #59 from cypherbits/link_privacy
Add chat link privacy with noreferrer and noopener
2020-05-02 18:27:57 +02:00
95c1faf1d9 Correctly calculate frameset hight for non-upload enabled users 2020-05-02 18:23:35 +02:00
c5e55e8bc0 add more security headers 2020-05-02 18:11:35 +02:00
1cdf6cbf55 add chat link privacy with noreferrer and noopener 2020-05-02 17:25:09 +02:00
7adf9732ef fix... 2020-05-02 13:53:17 +02:00
f0659466c1 openssl to libsodium 2020-05-02 13:30:29 +02:00
0963acafcf New generation AES256-GCM encryption by libsodium. PHP >= 7.3 needed. 2020-05-02 12:16:36 +02:00
d58fdeee8b Added example CSS that moves the chatters list to the right 2020-04-12 12:45:39 +02:00
e0d6fe5d91 Merge pull request #57 from infoabcd/master
Full Chinese translation
2020-04-11 11:21:38 +02:00
f605137313 Add files via upload 2020-04-11 08:09:12 +08:00
03f9a86515 Allow making file upload member-only and added required tag to captcha input 2020-02-29 14:26:48 +01:00
cfd54b09be Add filtermodkick setting to db if missing 2019-02-24 13:17:01 +01:00
16b81337b1 Merge pull request #52 from virtualghetto/filtermodkick-fix
fix filtermodkick setting
2019-02-24 13:08:47 +01:00
2cd5d18511 Merge pull request #50 from virtualghetto/next-gen-hotlink
Next-Gen Onion Hotlink
2019-02-24 13:02:41 +01:00
0ae827450a Merge pull request #51 from virtualghetto/restore-enc-notes
Restore encrypted notes
2019-02-24 12:59:47 +01:00
5589999b0f fix filtermodkick setting
filtermodkick should be defined in the settings array instead of reg.
2019-02-16 18:42:56 +00:00
4d0b828879 Restore encrypted notes
send_backup() decrypts the notes if MSGENCRYPTED is enabled.
So, re-encrypt the notes on restore.
2019-02-03 15:45:18 +00:00
268328f82c Next-Gen Onion Hotlink 2018-11-07 15:50:51 +00:00
19 changed files with 863 additions and 411 deletions

5
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,5 @@
# These are supported funding model platforms
github: DanWin
liberapay: DanWin1210
custom: "https://www.paypal.me/danwin1210"

View File

@ -1,3 +1,20 @@
Version 1.24.1 - Oct. 17, 2020
Add Turkish translation
Security hardening
Fixed chrome flashing frames white on reload
Version 1.24 - May. 2, 2020
Allow making file upload member-only
Added required tag to captcha input
Add Chinese translation
Security hardening
Fixed chrome flashing frames white on reload
Version 1.23.7 - Feb. 24, 2019
Support V3 hidden services
Fixed filtermodkick setting
fixed restore_backup not encrypting notes
Version 1.23.6 - Apr. 22, 2018
Added Czech, Italian and Ukrainian translation
Updated Russian translation

11
README
View File

@ -1,7 +1,7 @@
GENERAL INFORMATION:
This is a PHP Chat based on LE CHAT v.1.14. An up-to-date copy of this script can be downloaded at https://github.com/DanWin/le-chat-php
The original perl LE CHAT script by Lucky Eddie can be downloaded at http://4fvfamdpoulu2nms.onion/lechat/ or via a tor2web proxy like https://4fvfamdpoulu2nms.onion.to/lechat/ if you don't have TOR installed.
The original perl LE CHAT script by Lucky Eddie can be downloaded at http://4fvfamdpoulu2nms.onion/lechat/ or via a tor2web proxy like https://4fvfamdpoulu2nms.onion.to/lechat/ if you don't have Tor installed.
If you add your own cool features or have a feature request, please tell me and I will add them, if I like them.
Please also let me know about any bugs you find in the code, so I can fix them.
Now a piece of information about the origin of the name "LE CHAT" copied from the original script:
@ -10,7 +10,7 @@ It may even be the French word for "the" if you prefer. Translated from French t
FEATURES:
Optimized for TOR
Optimized for Tor
No JavaScript needed
Cookies supported, but not needed
Captcha
@ -42,7 +42,7 @@ Optionally, you can install:
- the json extension for save/restore
- a memcached server and the memcached extension and change the configuaration to use memcached. This will lessen the database load a bit.
- a MySQL or PostgreSQL server to use as an external database instead of SQLite
- the openssl extension for encryption of messages and notes in the database
- the libsodium extension for encryption of messages and notes in the database (bundled with PHP >= 7.2)
When you have everything installed and use MySQL or PostgreSQL, you'll have to create a database and a user for the chat.
Then edit the configuration at the bottom of the script to reflect the appropriate database settings and to modify the chat settings the way you like them.
Then copy the script to your web-server directory and call the script in your browser with a parameter like this:
@ -77,6 +77,5 @@ If you never used regex before, check out this starting guide to begin with regu
LIVE DEMO:
If you want to see the script in action, you can visit my TOR hidden service http://tt3j2x4k5ycaa5zt.onion/chat.php or via a tor2web proxy like https://danwin1210.me/chat.php if you don't have TOR installed.
Considering this is a hidden service, you should be prepared for the worst case, as people tend to do illegal activities in the TOR network. I'm not online 24/7 so it might not be possible to remove such content right away.
If you should see illegal content, don't panic. Use the contact form on my site to notify me and clean your browser cache afterwards.
If you want to see the script in action, you can visit my Tor hidden service http://danschat356lctri3zavzh6fbxg2a7lo6z3etgkctzzpspewu7zdsaqd.onion/chat.php or via a tor2web proxy like https://chat.danwin1210.me/chat.php if you don't have Tor installed.
Considering this is a hidden service, you should be prepared for the worst case, as people tend to do illegal activities in the Tor network.

View File

@ -2,7 +2,7 @@ General Information:
--------------------
This is a PHP Chat based on LE CHAT v.1.14. An up-to-date copy of this script can be downloaded at https://github.com/DanWin/le-chat-php
The original perl LE CHAT script by Lucky Eddie can be downloaded at [his site](http://4fvfamdpoulu2nms.onion/lechat/) or via a tor2web proxy like [this one](https://4fvfamdpoulu2nms.onion.to/lechat/) if you don't have TOR installed.
The original perl LE CHAT script by Lucky Eddie can be downloaded at [his site](http://4fvfamdpoulu2nms.onion/lechat/) or via a tor2web proxy like [this one](https://4fvfamdpoulu2nms.onion.to/lechat/) if you don't have Tor installed.
If you add your own cool features or have a feature request, please tell me and I will add them, if I like them.
Please also let me know about any bugs you find in the code, so I can fix them.
Now a piece of information about the origin of the name "LE CHAT" copied from the original script:
@ -12,7 +12,7 @@ It may even be the French word for "the" if you prefer. Translated from French t
Features:
---------
* Optimized for TOR
* Optimized for Tor
* No JavaScript needed
* Cookies supported, but not needed
* Captcha
@ -45,7 +45,7 @@ Optionally, you can install:
- the json extension for save/restore
- a memcached server and the memcached extension and change the configuaration to use memcached. This will lessen the database load a bit.
- a MySQL or PostgreSQL server to use as an external database instead of SQLite
- the openssl extension for encryption of messages and notes in the database
- the libsodium extension (PHP >= 7.2) for encryption of messages and notes in the database
When you have everything installed and use MySQL or PostgreSQL, you'll have to create a database and a user for the chat.
Then edit the configuration at the bottom of the script to reflect the appropriate database settings and to modify the chat settings the way you like them.
Then copy the script to your web-server directory and call the script in your browser with a parameter like this:
@ -59,7 +59,7 @@ Translating:
Copy lang_en.php and rename it to lang_YOUR_LANGCODE.php
Then edit the file and translate the messages into your language and change $I to $T at the top.
If you ever use a ' character, you have to escape it by using \' instead or the script will fail.
If you ever use a `'` character, you have to escape it by using `\'` instead or the script will fail.
When you are done, you have to edit the chat script, to include your translation. Simply add a line with
'lang_code' =>'Language name',
to the $L array in the load_lang() function at the bottom, similar to what I did for the German translation.
@ -72,17 +72,16 @@ Regex:
Yes, the chat supports regular expression filtering of messages. As regex tends to be difficult for most people, I decided to give it an extra section here.
Regex is very powerful and can be used to filter messages that contain certain expressions and replace them with something else.
It can be used e.g. to turn BB Code into html, so it is possible to use BB Code in the chat to format messages.
To do this, use this Regex-Match '\[(u|b)\](.*?)\[\/\1\]' and this Regex-Replace '<$1>$2</$1>' and your text will be '[b]bold[/b]' or '[u]underlined[/u]'.
You can also use smilies by using this Regex-Match '(?-i::(cry|eek|lol|sad|smile|surprised|wink):)' and this Regex-Replace '<img src="/pictures/$1.gif" alt=":$1:">'
And now if you enter ':smile:' an image with the smiley will be loaded from your server at '/pictures/smile.gif'.
The following should be escaped by putting '\' in front of it, if you are trying to match one of these characters '/ \ ^ . $ | ( ) [ ] * + ? { } ,'.
I used '/' as delimiter, so you will have to escape that, too. The only options I used is 'i' to make the regex case insensitive.
To do this, use this Regex-Match `\[(u|b)\](.*?)\[\/\1\]` and this Regex-Replace `<$1>$2</$1>` and your text will be `[b]bold[/b]` or `[u]underlined[/u]`.
You can also use smilies by using this Regex-Match `(?-i::(cry|eek|lol|sad|smile|surprised|wink):)` and this Regex-Replace `<img src="/pictures/$1.gif" alt=":$1:">`
And now if you enter `:smile:` an image with the smiley will be loaded from your server at `/pictures/smile.gif`.
The following should be escaped by putting `\` in front of it, if you are trying to match one of these characters `/ \ ^ . $ | ( ) [ ] * + ? { } ,`.
I used `/` as delimiter, so you will have to escape that, too. The only options I used is `i` to make the regex case insensitive.
If you want to test your regex, before applying you can use [this site](http://www.phpliveregex.com/) and enter your Regex and Replacement there and click on preg_replace.
If you never used regex before, check out [this starting guide](http://docs.activestate.com/komodo/4.4/regex-intro.html) to begin with regular expressions.
Live demo:
----------
If you want to see the script in action, you can visit my [TOR hidden service](http://tt3j2x4k5ycaa5zt.onion/chat.php) or via a tor2web proxy like [this one](https://danwin1210.me/chat.php) if you don't have TOR installed.
Considering this is a hidden service, you should be prepared for the worst case, as people tend to do illegal activities in the TOR network. I'm not online 24/7 so it might not be possible to remove such content right away.
If you should see illegal content, don't panic. Use the contact form on my site to notify me and clean your browser cache afterwards. I will remove the content as soon as possible.
If you want to see the script in action, you can visit my [Tor hidden service](http://danschat356lctri3zavzh6fbxg2a7lo6z3etgkctzzpspewu7zdsaqd.onion/chat.php) or via a tor2web proxy like [this one](https://chat.danwin1210.me/chat.php) if you don't have Tor installed.
Considering this is a hidden service, you should be prepared for the worst case, as people tend to do illegal activities in the Tor network.

300
chat.php
View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Main program
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,19 +32,20 @@
* 9 - Private messages
*/
send_headers();
// initialize and load variables/configuration
load_config();
$I=[];// Translations
$L=[];// Languages
$U=[];// This user data
$db;// Database connection
$memcached;// Memcached connection
$language;// user selected language
load_config();
$db = null;// Database connection
$memcached = null;// Memcached connection
$language = LANG;// user selected language
$styles = []; //css styles
// set session variable to cookie if cookies are enabled
if(!isset($_REQUEST['session']) && isset($_COOKIE[COOKIENAME])){
$_REQUEST['session']=$_COOKIE[COOKIENAME];
}
$_REQUEST['session'] = preg_replace('/[^0-9a-zA-Z]/', '', $_REQUEST['session'] ?? '');
load_lang();
check_db();
cron();
@ -77,7 +78,7 @@ function route(){
send_post(validate_input());
}
send_post();
}elseif($_REQUEST['action']==='login'){
}elseif($_REQUEST['action']==='login' && isPOST()){
check_login();
send_frameset();
}elseif($_REQUEST['action']==='controls'){
@ -86,7 +87,7 @@ function route(){
}elseif($_REQUEST['action']==='greeting'){
check_session();
send_greeting();
}elseif($_REQUEST['action']==='delete'){
}elseif($_REQUEST['action']==='delete' && isPOST()){
check_session();
if($_REQUEST['what']==='all'){
if(isset($_REQUEST['confirm'])){
@ -98,7 +99,7 @@ function route(){
del_last_message();
}
send_post();
}elseif($_REQUEST['action']==='profile'){
}elseif($_REQUEST['action']==='profile' && isPOST()){
check_session();
$arg='';
if(!isset($_REQUEST['do'])){
@ -112,13 +113,13 @@ function route(){
}
}
send_profile($arg);
}elseif($_REQUEST['action']==='logout'){
}elseif($_REQUEST['action']==='logout' && isPOST()){
kill_session();
send_logout();
}elseif($_REQUEST['action']==='colours'){
check_session();
send_colours();
}elseif($_REQUEST['action']==='notes'){
}elseif($_REQUEST['action']==='notes' && isPOST()){
check_session();
if(isset($_REQUEST['do']) && $_REQUEST['do']==='admin' && $U['status']>6){
send_notes(0);
@ -132,7 +133,7 @@ function route(){
}elseif($_REQUEST['action']==='help'){
check_session();
send_help();
}elseif($_REQUEST['action']==='inbox'){
}elseif($_REQUEST['action']==='inbox' && isPOST()){
check_session();
if(isset($_REQUEST['do'])){
clean_inbox_selected();
@ -140,10 +141,10 @@ function route(){
send_inbox();
}elseif($_REQUEST['action']==='download'){
send_download();
}elseif($_REQUEST['action']==='admin'){
}elseif($_REQUEST['action']==='admin' && isPOST()){
check_session();
send_admin(route_admin());
}elseif($_REQUEST['action']==='setup'){
}elseif($_REQUEST['action']==='setup' && isPOST()){
route_setup();
}else{
send_login();
@ -186,7 +187,7 @@ function route_admin(){
if(isset($_REQUEST['kick']) && isset($_REQUEST['nick'])){
kick_chatter([$_REQUEST['nick']], '', false);
}elseif(isset($_REQUEST['logout']) && isset($_REQUEST['nick'])){
logout_chatter([$_REQUEST['nick']], '', false);
logout_chatter([$_REQUEST['nick']]);
}
send_sessions();
}elseif($_REQUEST['do']==='register'){
@ -222,10 +223,10 @@ function route_setup(){
if(!valid_admin()){
send_alogin();
}
$C['bool_settings']=['suguests', 'imgembed', 'timestamps', 'trackip', 'memkick', 'forceredirect', 'incognito', 'sendmail', 'modfallback', 'disablepm', 'eninbox', 'enablegreeting', 'sortupdown', 'hidechatters', 'enfileupload', 'personalnotes', 'filtermodkick'];
$C['bool_settings']=['suguests', 'imgembed', 'timestamps', 'trackip', 'memkick', 'forceredirect', 'incognito', 'sendmail', 'modfallback', 'disablepm', 'eninbox', 'enablegreeting', 'sortupdown', 'hidechatters', 'personalnotes', 'filtermodkick'];
$C['colour_settings']=['colbg', 'coltxt'];
$C['msg_settings']=['msgenter', 'msgexit', 'msgmemreg', 'msgsureg', 'msgkick', 'msgmultikick', 'msgallkick', 'msgclean', 'msgsendall', 'msgsendmem', 'msgsendmod', 'msgsendadm', 'msgsendprv', 'msgattache'];
$C['number_settings']=['memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes', 'maxuploadsize'];
$C['number_settings']=['memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes', 'maxuploadsize', 'enfileupload'];
$C['textarea_settings']=['rulestxt', 'css', 'disabletext'];
$C['text_settings']=['dateformat', 'captchachars', 'redirect', 'chatname', 'mailsender', 'mailreceiver', 'nickregex', 'passregex', 'externalcss'];
$C['settings']=array_merge(['guestaccess', 'englobalpass', 'globalpass', 'captcha', 'dismemcaptcha', 'topic', 'guestreg', 'defaulttz'], $C['bool_settings'], $C['colour_settings'], $C['msg_settings'], $C['number_settings'], $C['textarea_settings'], $C['text_settings']); // All settings in the database
@ -248,35 +249,33 @@ function route_setup(){
}
// html output subs
function print_stylesheet($init=false){
global $U;
//default css
echo '<style type="text/css">';
echo 'body{background-color:#000000;color:#FFFFFF;font-size:14px;text-align:center;} ';
echo 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} #messages{word-wrap:break-word;} ';
echo 'input,select,textarea{color:#FFFFFF;background-color:#000000;} .messages a img{width:15%} .messages a:hover img{width:35%} ';
echo '.error{color:#FF0033;text-align:left;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} ';
echo '.setup table table,.admin table table,.profile table table{width:100%;text-align:left} ';
echo '.alogin table,.init table,.destroy_chat table,.delete_account table,.sessions table,.filter table,.linkfilter table,.notes table,.approve_waiting table,.del_confirm table,.profile table,.admin table,.backup table,.setup table{margin-left:auto;margin-right:auto;} ';
echo '.setup table table table,.admin table table table,.profile table table table{border-spacing:0px;margin-left:auto;margin-right:unset;width:unset;} ';
echo '.setup table table td,.backup #restoresubmit,.backup #backupsubmit,.admin table table td,.profile table table td,.login td+td,.alogin td+td{text-align:right;} ';
echo '.init td,.backup #restorecheck td,.admin #clean td,.admin #regnew td,.session td,.messages,.inbox,.approve_waiting td,.choose_messages,.greeting,.help,.login td,.alogin td{text-align:left;} ';
echo '.messages #chatters{max-height:100px;overflow-y:auto;} .messages #chatters a{text-decoration-line:none;} .messages #chatters table{border-spacing:0px;} ';
echo '.messages #chatters th,.messages #chatters td,.post #firstline{vertical-align:top;} ';
echo '.approve_waiting #action td:only-child,.help #backcredit,.login td:only-child,.alogin td:only-child,.init td:only-child{text-align:center;} .sessions td,.sessions th,.approve_waiting td,.approve_waiting th{padding: 5px;} ';
echo '.sessions td td{padding: 1px;} .messages #bottom_link{position:fixed;top:0.5em;right:0.5em;} .messages #top_link{position:fixed;bottom:0.5em;right:0.5em;} ';
echo '.post table,.controls table,.login table{border-spacing:0px;margin-left:auto;margin-right:auto;} .login table{border:2px solid;} .controls{overflow-y:none;} ';
echo '#manualrefresh{display:block;position:fixed;text-align:center;left:25%;width:50%;top:-200%;animation:timeout_messages ';
function prepare_stylesheets($init = false){
global $U, $db, $styles;
$styles['fatal_error'] = 'body{background-color:#000000;color:#FF0033}';
$styles['default'] = 'body,frame{background-color:#000000;color:#FFFFFF;font-size:14px;text-align:center} ';
$styles['default'] .= 'a:visited{color:#B33CB4} a:active{color:#FF0033} a:link{color:#0000FF} #messages{word-wrap:break-word} ';
$styles['default'] .= 'input,select,textarea{color:#FFFFFF;background-color:#000000} .messages a img{width:15%} .messages a:hover img{width:35%} ';
$styles['default'] .= '.error{color:#FF0033;text-align:left} .delbutton{background-color:#660000} .backbutton{background-color:#004400} #exitbutton{background-color:#AA0000} ';
$styles['default'] .= '.setup table table,.admin table table,.profile table table{width:100%;text-align:left} ';
$styles['default'] .= '.alogin table,.init table,.destroy_chat table,.delete_account table,.sessions table,.filter table,.linkfilter table,.notes table,.approve_waiting table,.del_confirm table,.profile table,.admin table,.backup table,.setup table{margin-left:auto;margin-right:auto} ';
$styles['default'] .= '.setup table table table,.admin table table table,.profile table table table{border-spacing:0px;margin-left:auto;margin-right:unset;width:unset} ';
$styles['default'] .= '.setup table table td,.backup #restoresubmit,.backup #backupsubmit,.admin table table td,.profile table table td,.login td+td,.alogin td+td{text-align:right} ';
$styles['default'] .= '.init td,.backup #restorecheck td,.admin #clean td,.admin #regnew td,.session td,.messages,.inbox,.approve_waiting td,.choose_messages,.greeting,.help,.login td,.alogin td{text-align:left} ';
$styles['default'] .= '.messages #chatters{max-height:100px;overflow-y:auto} .messages #chatters a{text-decoration-line:none} .messages #chatters table{border-spacing:0px} ';
$styles['default'] .= '.messages #chatters th,.messages #chatters td,.post #firstline{vertical-align:top} ';
$styles['default'] .= '.approve_waiting #action td:only-child,.help #backcredit,.login td:only-child,.alogin td:only-child,.init td:only-child{text-align:center} .sessions td,.sessions th,.approve_waiting td,.approve_waiting th{padding: 5px} ';
$styles['default'] .= '.sessions td td{padding: 1px} .messages #bottom_link{position:fixed;top:0.5em;right:0.5em} .messages #top_link{position:fixed;bottom:0.5em;right:0.5em} ';
$styles['default'] .= '.post table,.controls table,.login table{border-spacing:0px;margin-left:auto;margin-right:auto} .login table{border:2px solid} .controls{overflow-y:none} ';
$styles['default'] .= '#manualrefresh{display:block;position:fixed;text-align:center;left:25%;width:50%;top:-200%;animation:timeout_messages ';
if(isset($U['refresh'])){
echo $U['refresh']+20;
$styles['default'] .= $U['refresh']+20;
}else{
echo '160';
$styles['default'] .='160';
}
echo 's forwards;z-index:2;background-color:#500000;border:2px solid #ff0000;} ';
echo '@keyframes timeout_messages{0%{top:-200%;} 99%{top:-200%;} 100%{top:0%;}} ';
echo '.notes textarea{height:80vh;width:80%;}';
echo '</style>';
if($init){
$styles['default'] .= 's forwards;z-index:2;background-color:#500000;border:2px solid #ff0000} ';
$styles['default'] .= '@keyframes timeout_messages{0%{top:-200%} 99%{top:-200%} 100%{top:0%}} ';
$styles['default'] .= '.notes textarea{height:80vh;width:80%}';
if($init || ! $db instanceof PDO){
return;
}
$css=get_setting('css');
@ -286,8 +285,18 @@ function print_stylesheet($init=false){
}else{
$colbg=get_setting('colbg');
}
$styles['custom'] = preg_replace("/(\r?\n|\r\n?)/u", '', "body,frame{background-color:#$colbg;color:#$coltxt} $css");
}
function print_stylesheet($init = false){
global $styles;
//default css
echo "<style type=\"text/css\">$styles[default]</style>";
if($init){
return;
}
//overwrite with custom css
echo "<style type=\"text/css\">body{background-color:#$colbg;color:#$coltxt;} $css</style>";
echo "<style type=\"text/css\">$styles[custom]</style>";
}
function print_end(){
@ -296,11 +305,11 @@ function print_end(){
}
function credit(){
return '<small><br><br><a target="_blank" href="https://github.com/DanWin/le-chat-php">LE CHAT-PHP - ' . VERSION . '</a></small>';
return '<small><br><br><a target="_blank" href="https://github.com/DanWin/le-chat-php" rel="noopener">LE CHAT-PHP - ' . VERSION . '</a></small>';
}
function meta_html(){
return '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0"><meta http-equiv="expires" content="0"><meta name="referrer" content="no-referrer">';
return '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="referrer" content="no-referrer">';
}
function form($action, $do=''){
@ -340,17 +349,16 @@ function thr(){
}
function print_start($class='', $ref=0, $url=''){
global $I;
global $I, $language;
prepare_stylesheets($class === 'init');
send_headers();
if(!empty($url)){
$url=str_replace('&amp;', '&', $url);// Don't escape "&" in URLs here, it breaks some (older) browsers and js refresh!
header("Refresh: $ref; URL=$url");
}
echo '<!DOCTYPE html><html><head>'.meta_html();
echo '<!DOCTYPE html><html lang="'.$language.'"><head>'.meta_html();
if(!empty($url)){
echo "<meta http-equiv=\"Refresh\" content=\"$ref; URL=$url\">";
$ref+=5;//only use js if browser refresh stopped working
$ref*=1000;//js uses milliseconds
echo "<script type=\"text/javascript\">setTimeout(function(){window.location.replace(\"$url\");}, $ref);</script>";
}
if($class==='init'){
echo "<title>$I[init]</title>";
@ -368,7 +376,7 @@ function print_start($class='', $ref=0, $url=''){
function send_redirect($url){
global $I;
$url=htmlspecialchars_decode(rawurldecode($url));
$url=trim(htmlspecialchars_decode(rawurldecode($url)));
preg_match('~^(.*)://~u', $url, $match);
$url=preg_replace('~^(.*)://~u', '', $url);
$escaped=htmlspecialchars($url);
@ -380,7 +388,11 @@ function send_redirect($url){
if(!isset($match[0])){
$match[0]='';
}
echo "<p>$I[nonhttp] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>";
if(preg_match('~^(javascript|blob|data):~', $url)){
echo "<p>$I[dangerousnonhttp] $match[0]$escaped</p>";
} else {
echo "<p>$I[nonhttp] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>";
}
echo "<p>$I[httpredir] <a href=\"http://$escaped\">http://$escaped</a>.</p>";
}
print_end();
@ -388,7 +400,7 @@ function send_redirect($url){
function send_access_denied(){
global $I, $U;
header('HTTP/1.1 403 Forbidden');
http_response_code(403);
print_start('access_denied');
echo "<h1>$I[accessdenied]</h1>".sprintf($I['loggedinas'], style_this(htmlspecialchars($U['nickname']), $U['style'])).'<br>';
echo form('logout');
@ -499,7 +511,7 @@ function send_captcha(){
imagegif($im);
imagedestroy($im);
echo base64_encode(ob_get_clean()).'">';
echo '</td><td>'.hidden('challenge', $randid).'<input type="text" name="captcha" size="15" autocomplete="off"></td></tr>';
echo '</td><td>'.hidden('challenge', $randid).'<input type="text" name="captcha" size="15" autocomplete="off" required></td></tr>';
}
function send_setup($C){
@ -767,6 +779,9 @@ function restore_backup($C){
}elseif($note['type']==='staff'){
$note['type']=1;
}
if(MSGENCRYPTED){
$note['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($note['text'], '', AES_IV, ENCRYPTKEY));
}
$stmt->execute([$note['type'], $note['lastedited'], $note['editedby'], $note['text']]);
}
}
@ -801,7 +816,7 @@ function send_backup($C){
$result=$db->query('SELECT * FROM ' . PREFIX . "notes;");
while($note=$result->fetch(PDO::FETCH_ASSOC)){
if(MSGENCRYPTED){
$note['text']=openssl_decrypt($note['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$note['text']=sodium_crypto_aead_aes256gcm_decrypt(base64_decode($note['text']), null, AES_IV, ENCRYPTKEY);
}
$code['notes'][]=$note;
}
@ -1384,7 +1399,9 @@ function send_linkfilter($arg=''){
function send_frameset(){
global $I, $U, $db, $language;
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"><html><head>'.meta_html();
prepare_stylesheets();
send_headers();
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"><html lang="'.$language.'"><head>'.meta_html();
echo '<title>'.get_setting('chatname').'</title>';
print_stylesheet();
echo '</head>';
@ -1412,7 +1429,7 @@ function send_frameset(){
}else{
$bottom='';
}
if(($U['status']>=5 || ($U['status']>2 && get_count_mods()==0)) && get_setting('enfileupload')){
if(($U['status']>=5 || ($U['status']>2 && get_count_mods()==0)) && get_setting('enfileupload')>0 && get_setting('enfileupload')<=$U['status']){
$postheight=120;
}else{
$postheight=100;
@ -1536,7 +1553,7 @@ function send_notes($type){
}
if(isset($_REQUEST['text'])){
if(MSGENCRYPTED){
$_REQUEST['text']=openssl_encrypt($_REQUEST['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$_REQUEST['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($_REQUEST['text'], '', AES_IV, ENCRYPTKEY));
}
$time=time();
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'notes (type, lastedited, editedby, text) VALUES (?, ?, ?, ?);');
@ -1570,7 +1587,7 @@ function send_notes($type){
$note['text']='';
}
if(MSGENCRYPTED){
$note['text']=openssl_decrypt($note['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$note['text']=sodium_crypto_aead_aes256gcm_decrypt(base64_decode($note['text']), null, AES_IV, ENCRYPTKEY);
}
echo "</p>".form('notes');
echo "$hiddendo<textarea name=\"text\">".htmlspecialchars($note['text']).'</textarea><br>';
@ -1763,7 +1780,7 @@ function send_post($rejected=''){
}
}
echo '</select></td>';
if(get_setting('enfileupload')){
if(get_setting('enfileupload')>0 && get_setting('enfileupload')<=$U['status']){
if(!$disablepm && ($U['status']>=5 || ($U['status']>=3 && get_count_mods()==0 && get_setting('memkick')))){
echo '</tr></table><table><tr id="secondline">';
}
@ -1852,7 +1869,7 @@ function send_profile($arg=''){
}
echo "<tr><td><table id=\"ignore\"><tr><th>$I[ignore]</th><td>";
echo "<select name=\"ignore\" size=\"1\"><option value=\"\">$I[choose]</option>";
$stmt=$db->prepare('SELECT poster, style FROM ' . PREFIX . 'messages INNER JOIN (SELECT nickname, style FROM ' . PREFIX . 'sessions UNION SELECT nickname, style FROM ' . PREFIX . 'members) AS t ON (' . PREFIX . 'messages.poster=t.nickname) WHERE poster!=? AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) GROUP BY poster ORDER BY LOWER(poster);');
$stmt=$db->prepare('SELECT poster, style FROM ' . PREFIX . 'messages INNER JOIN (SELECT nickname, style FROM ' . PREFIX . 'sessions UNION SELECT nickname, style FROM ' . PREFIX . 'members) AS t ON (' . PREFIX . 'messages.poster=t.nickname) WHERE poster!=? AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) GROUP BY poster ORDER BY LOWER(poster);');
$stmt->execute([$U['nickname'], $U['nickname']]);
while($nick=$stmt->fetch(PDO::FETCH_NUM)){
echo '<option value="'.htmlspecialchars($nick[0])."\" style=\"$nick[1]\">".htmlspecialchars($nick[0]).'</option>';
@ -2014,16 +2031,17 @@ function send_download(){
$stmt=$db->prepare('SELECT filename, type, data FROM ' . PREFIX . 'files WHERE hash=?;');
$stmt->execute([$_REQUEST['id']]);
if($data=$stmt->fetch(PDO::FETCH_ASSOC)){
send_headers();
header("Content-Type: $data[type]");
header("Content-Disposition: filename=\"$data[filename]\"");
header('Pragma: no-cache');
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0, private');
header('Expires: 0');
header("Content-Security-Policy: default-src 'none'");
echo base64_decode($data['data']);
}else{
http_response_code(404);
send_error($I['filenotfound']);
}
}else{
http_response_code(404);
send_error($I['filenotfound']);
}
}
@ -2122,10 +2140,12 @@ function send_error($err){
}
function send_fatal_error($err){
global $I;
echo '<!DOCTYPE html><html><head>'.meta_html();
global $I, $language, $styles;
prepare_stylesheets();
send_headers();
echo '<!DOCTYPE html><html lang="'.$language.'"><head>'.meta_html();
echo "<title>$I[fatalerror]</title>";
echo "<style type=\"text/css\">body{background-color:#000000;color:#FF0033;}</style>";
echo "<style type=\"text/css\">$styles[fatal_error]</style>";
echo '</head><body>';
echo "<h2>$I[fatalerror]: $err</h2>";
print_end();
@ -2204,8 +2224,8 @@ function create_session($setup, $nickname, $password){
}
if($ga===0){
send_error($I['noguests']);
}elseif($ga===3){
$U['entry']=0;
}elseif(in_array($ga, [2, 3], true)){
$U['entry'] = 0;
}
if(get_setting('englobalpass')!=0 && isset($_REQUEST['globalpass']) && $_REQUEST['globalpass']!=get_setting('globalpass')){
send_error($I['wrongglobalpass']);
@ -2221,6 +2241,7 @@ function check_captcha($challenge, $captcha_code){
if(empty($challenge)){
send_error($I['wrongcaptcha']);
}
$code = '';
if(MEMCACHED){
if(!$code=$memcached->get(DBNAME . '-' . PREFIX . "captcha-$_REQUEST[challenge]")){
send_error($I['captchaexpire']);
@ -2245,6 +2266,27 @@ function check_captcha($challenge, $captcha_code){
}
}
function is_definitely_ssl() {
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
return true;
}
if (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) {
return true;
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ('https' === $_SERVER['HTTP_X_FORWARDED_PROTO'])) {
return true;
}
return false;
}
function set_secure_cookie($name, $value){
if (version_compare(PHP_VERSION, '7.3.0') >= 0) {
setcookie($name, $value, ['expires' => 0, 'path' => '/', 'domain' => '', 'secure' => is_definitely_ssl(), 'httponly' => true, 'samesite' => 'Strict']);
}else{
setcookie($name, $value, 0, '/', '', is_definitely_ssl(), true);
}
}
function write_new_session($password){
global $I, $U, $db;
$stmt=$db->prepare('SELECT * FROM ' . PREFIX . 'sessions WHERE nickname=?;');
@ -2254,7 +2296,7 @@ function write_new_session($password){
if(password_verify($password, $temp['passhash'])){
$U=$temp;
check_kicked();
setcookie(COOKIENAME, $U['session']);
set_secure_cookie(COOKIENAME, $U['session']);
}else{
send_error("$I[userloggedin]<br>$I[wrongpass]");
}
@ -2281,7 +2323,7 @@ function write_new_session($password){
}
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'sessions (session, nickname, status, refresh, style, lastpost, passhash, useragent, bgcolour, entry, timestamps, embed, incognito, ip, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
$stmt->execute([$U['session'], $U['nickname'], $U['status'], $U['refresh'], $U['style'], $U['lastpost'], $U['passhash'], $useragent, $U['bgcolour'], $U['entry'], $U['timestamps'], $U['embed'], $U['incognito'], $ip, $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['nocache_old']]);
setcookie(COOKIENAME, $U['session']);
set_secure_cookie(COOKIENAME, $U['session']);
if($U['status']>=3 && !$U['incognito']){
add_system_message(sprintf(get_setting('msgenter'), style_this(htmlspecialchars($U['nickname']), $U['style'])));
}
@ -2318,7 +2360,7 @@ function approve_session(){
}
function check_login(){
global $I, $U, $db;
global $I, $U;
$ga=(int) get_setting('guestaccess');
if(isset($_REQUEST['session'])){
parse_sessions();
@ -2349,9 +2391,7 @@ function check_login(){
}
}
if($U['status']==1){
if($ga===2 || $ga===3){
$stmt=$db->prepare('UPDATE ' . PREFIX . 'sessions SET entry=0 WHERE session=?;');
$stmt->execute([$U['session']]);
if(in_array($ga, [2, 3], true)){
send_waiting_room();
}
}
@ -2884,7 +2924,6 @@ function validate_input(){
//ignored
return;
}
$tmp=false;
$stmt=$db->prepare('SELECT s.style, 0 AS inbox FROM ' . PREFIX . 'sessions AS s LEFT JOIN ' . PREFIX . 'members AS m ON (m.nickname=s.nickname) WHERE s.nickname=? AND (s.incognito=0 OR (m.eninbox!=0 AND m.eninbox<=?));');
$stmt->execute([$_REQUEST['sendto'], $U['status']]);
if(!$tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
@ -2907,7 +2946,7 @@ function validate_input(){
$message=apply_filter($message, $poststatus, $U['nickname']);
$message=create_hotlinks($message);
$message=apply_linkfilter($message);
if(isset($_FILES['file']) && get_setting('enfileupload')){
if(isset($_FILES['file']) && get_setting('enfileupload')>0 && get_setting('enfileupload')<=$U['status']){
if($_FILES['file']['error']===UPLOAD_ERR_OK && $_FILES['file']['size']<=(1024*get_setting('maxuploadsize'))){
$hash=sha1_file($_FILES['file']['tmp_name']);
$name=htmlspecialchars($_FILES['file']['name']);
@ -2929,13 +2968,13 @@ function validate_input(){
'text' =>"<span class=\"usermsg\">$displaysend".style_this($message, $U['style']).'</span>'
];
if(MSGENCRYPTED){
$newmessage['text']=openssl_encrypt($newmessage['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$newmessage['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($newmessage['text'], '', AES_IV, ENCRYPTKEY));
}
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'inbox (postdate, postid, poster, recipient, text) VALUES(?, ?, ?, ?, ?)');
$stmt->execute([$newmessage['postdate'], $id[0], $newmessage['poster'], $newmessage['recipient'], $newmessage['text']]);
}
if(isset($hash) && $id){
if(!empty($_FILES['file']['type']) && preg_match('~^[a-z0-9/\-\.\+]*$~i', $_FILES['file']['type'])){
if(!empty($_FILES['file']['type']) && preg_match('~^[a-z0-9/\-.+]*$~i', $_FILES['file']['type'])){
$type=$_FILES['file']['type'];
}else{
$type='application/octet-stream';
@ -2975,17 +3014,17 @@ function apply_filter($message, $poststatus, $nickname){
function apply_linkfilter($message){
$filters=get_linkfilters();
foreach($filters as $filter){
$message=preg_replace_callback("/<a href=\"([^\"]+)\" target=\"_blank\">(.*?(?=<\/a>))<\/a>/iu",
$message=preg_replace_callback("/<a href=\"([^\"]+)\" target=\"_blank\" rel=\"noreferrer noopener\">(.*?(?=<\/a>))<\/a>/iu",
function ($matched) use(&$filter){
return "<a href=\"$matched[1]\" target=\"_blank\">".preg_replace("/$filter[match]/iu", $filter['replace'], $matched[2]).'</a>';
return "<a href=\"$matched[1]\" target=\"_blank\" rel=\"noreferrer noopener\">".preg_replace("/$filter[match]/iu", $filter['replace'], $matched[2]).'</a>';
}
, $message);
}
$redirect=get_setting('redirect');
if(get_setting('imgembed')){
$message=preg_replace_callback('/\[img\]\s?<a href="([^"]+)" target="_blank">(.*?(?=<\/a>))<\/a>/iu',
$message=preg_replace_callback('/\[img]\s?<a href="([^"]+)" target="_blank" rel="noreferrer noopener">(.*?(?=<\/a>))<\/a>/iu',
function ($matched){
return str_ireplace('[/img]', '', "<br><a href=\"$matched[1]\" target=\"_blank\"><img src=\"$matched[1]\"></a><br>");
return str_ireplace('[/img]', '', "<br><a href=\"$matched[1]\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"$matched[1]\"></a><br>");
}
, $message);
}
@ -2993,17 +3032,17 @@ function apply_linkfilter($message){
$redirect="$_SERVER[SCRIPT_NAME]?action=redirect&amp;url=";
}
if(get_setting('forceredirect')){
$message=preg_replace_callback('/<a href="([^"]+)" target="_blank">(.*?(?=<\/a>))<\/a>/u',
$message=preg_replace_callback('/<a href="([^"]+)" target="_blank" rel="noreferrer noopener">(.*?(?=<\/a>))<\/a>/u',
function ($matched) use($redirect){
return "<a href=\"$redirect".rawurlencode($matched[1])."\" target=\"_blank\">$matched[2]</a>";
return "<a href=\"$redirect".rawurlencode($matched[1])."\" target=\"_blank\" rel=\"noreferrer noopener\">$matched[2]</a>";
}
, $message);
}elseif(preg_match_all('/<a href="([^"]+)" target="_blank">(.*?(?=<\/a>))<\/a>/u', $message, $matches)){
}elseif(preg_match_all('/<a href="([^"]+)" target="_blank" rel="noreferrer noopener">(.*?(?=<\/a>))<\/a>/u', $message, $matches)){
foreach($matches[1] as $match){
if(!preg_match('~^http(s)?://~u', $match)){
$message=preg_replace_callback('/<a href="('.preg_quote($match, '/').')\" target=\"_blank\">(.*?(?=<\/a>))<\/a>/u',
$message=preg_replace_callback('/<a href="('.preg_quote($match, '/').')\" target=\"_blank\" rel=\"noreferrer noopener\">(.*?(?=<\/a>))<\/a>/u',
function ($matched) use($redirect){
return "<a href=\"$redirect".rawurlencode($matched[1])."\" target=\"_blank\">$matched[2]</a>";
return "<a href=\"$redirect".rawurlencode($matched[1])."\" target=\"_blank\" rel=\"noreferrer noopener\">$matched[2]</a>";
}
, $message);
}
@ -3021,15 +3060,15 @@ function create_hotlinks($message){
$message=preg_replace('~((?:[^\s<>]*:[^\s<>]*@)?[a-z0-9\-]+(?:\.[a-z0-9\-]+)+:\d+)(?![^<>]*>)~iu', "<<$1>>", $message); // server:port given
$message=preg_replace('~([^\s<>]*:[^\s<>]*@[a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?::\d+)?)(?![^<>]*>)~iu', "<<$1>>", $message); // au:th@server given
// 3. likely servers without any hints but not filenames like *.rar zip exe etc.
$message=preg_replace('~((?:[a-z0-9\-]+\.)*[a-z2-7]{16}\.onion)(?![^<>]*>)~iu', "<<$1>>", $message);// *.onion
$message=preg_replace('~([a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?:\.(?!rar|zip|exe|gz|7z|bat|doc)[a-z]{2,}))(?=[^a-z0-9\-\.]|$)(?![^<>]*>)~iu', "<<$1>>", $message);// xxx.yyy.zzz
$message=preg_replace('~((?:[a-z0-9\-]+\.)*(?:[a-z2-7]{55}d|[a-z2-7]{16})\.onion)(?![^<>]*>)~iu', "<<$1>>", $message);// *.onion
$message=preg_replace('~([a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?:\.(?!rar|zip|exe|gz|7z|bat|doc)[a-z]{2,}))(?=[^a-z0-9\-.]|$)(?![^<>]*>)~iu', "<<$1>>", $message);// xxx.yyy.zzz
// Convert every <<....>> into proper links:
$message=preg_replace_callback('/<<([^<>]+)>>/u',
function ($matches){
if(strpos($matches[1], '://')===false){
return "<a href=\"http://$matches[1]\" target=\"_blank\">$matches[1]</a>";
return "<a href=\"http://$matches[1]\" target=\"_blank\" rel=\"noreferrer noopener\">$matches[1]</a>";
}else{
return "<a href=\"$matches[1]\" target=\"_blank\">$matches[1]</a>";
return "<a href=\"$matches[1]\" target=\"_blank\" rel=\"noreferrer noopener\">$matches[1]</a>";
}
}
, $message);
@ -3037,7 +3076,7 @@ function create_hotlinks($message){
}
function apply_mention($message){
return preg_replace_callback('/\@([^\s]+)/iu', function ($matched){
return preg_replace_callback('/@([^\s]+)/iu', function ($matched){
global $db;
$nick=htmlspecialchars_decode($matched[1]);
$rest='';
@ -3117,7 +3156,7 @@ function add_system_message($mes){
function write_message($message){
global $db;
if(MSGENCRYPTED){
$message['text']=openssl_encrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY));
}
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'messages (postdate, poststatus, poster, recipient, text, delstatus) VALUES (?, ?, ?, ?, ?, ?);');
$stmt->execute([$message['postdate'], $message['poststatus'], $message['poster'], $message['recipient'], $message['text'], $message['delstatus']]);
@ -3238,7 +3277,7 @@ function print_messages($delstatus=0){
function prepare_message_print(&$message, $removeEmbed){
if(MSGENCRYPTED){
$message['text']=openssl_decrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY);
}
if($removeEmbed){
$message['text']=preg_replace_callback('/<img src="([^"]+)"><\/a>/u',
@ -3252,13 +3291,22 @@ function prepare_message_print(&$message, $removeEmbed){
// this and that
function send_headers(){
global $styles;
header('Content-Type: text/html; charset=UTF-8');
header('Pragma: no-cache');
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0');
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0, private');
header('Expires: 0');
header('Referrer-Policy: no-referrer');
header('Content-Security-Policy: referrer never');
if($_SERVER['REQUEST_METHOD']==='HEAD'){
header("Permissions-Policy: accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; cross-origin-isolated 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; geolocation 'none'; fullscreen 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; screen-wake-lock 'none'; sync-xhr 'none'; usb 'none'; web-share 'none'; xr-spatial-tracking 'none'; clipboard-read 'none'; clipboard-write 'none'; gamepad 'none'; speaker-selection 'none'; conversion-measurement 'none'; focus-without-user-activation 'none'; hid 'none'; idle-detection 'none'; sync-script 'none'; vertical-scroll 'none'; serial 'none'; trust-token-redemption 'none';");
$style_hashes = '';
foreach($styles as $style) {
$style_hashes .= " 'sha256-".base64_encode(hash('sha256', $style, true))."'";
}
header("Content-Security-Policy: base-uri 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src * data:; media-src * data:; style-src 'self' 'unsafe-inline'"); // $style_hashes"); //we can add computed hashes as soon as all inline css is moved to default css
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: sameorigin');
header('X-XSS-Protection: 1; mode=block');
if($_SERVER['REQUEST_METHOD'] === 'HEAD'){
exit; // headers sent, no further processing needed
}
}
@ -3491,7 +3539,7 @@ function destroy_chat($C){
$db->exec('DROP TABLE ' . PREFIX . 'settings;');
if(MEMCACHED){
$memcached->delete(DBNAME . '-' . PREFIX . 'filter');
$memcached->delete(DBANEM . '-' . PREFIX . 'linkfilter');
$memcached->delete(DBNAME . '-' . PREFIX . 'linkfilter');
foreach($C['settings'] as $setting){
$memcached->delete(DBNAME . '-' . PREFIX . "settings-$setting");
}
@ -3637,6 +3685,7 @@ function init_chat(){
['maxuploadsize', '1024'],
['nextcron', '0'],
['personalnotes', '1'],
['filtermodkick', '0'],
];
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (?, ?);');
foreach($settings as $pair){
@ -3658,7 +3707,6 @@ function init_chat(){
'eninbox' =>0,
'sortupdown' =>0,
'hidechatters' =>0,
'filtermodkick' =>1,
];
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, timestamps, style, embed, incognito, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
$stmt->execute([$reg['nickname'], $reg['passhash'], $reg['status'], $reg['refresh'], $reg['bgcolour'], $reg['timestamps'], $reg['style'], $reg['embed'], $reg['incognito'], $reg['nocache'], $reg['tz'], $reg['eninbox'], $reg['sortupdown'], $reg['hidechatters'], $reg['nocache_old']]);
@ -3965,9 +4013,6 @@ function update_db(){
$db->exec('CREATE INDEX ' . PREFIX . 'notes_type ON ' . PREFIX . 'notes(type);');
$db->exec('CREATE INDEX ' . PREFIX . 'notes_editedby ON ' . PREFIX . 'notes(editedby);');
}
if($dbversion<40){
$db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('filtermodkick', '1');");
}
if($dbversion<41){
$db->exec('DROP TABLE ' . PREFIX . 'sessions;');
$db->exec('CREATE TABLE ' . PREFIX . "sessions (id $primary, session char(32) NOT NULL UNIQUE, nickname varchar(50) NOT NULL UNIQUE, status smallint NOT NULL, refresh smallint NOT NULL, style varchar(255) NOT NULL, lastpost integer NOT NULL, passhash varchar(255) NOT NULL, postid char(6) NOT NULL DEFAULT '000000', useragent varchar(255) NOT NULL, kickmessage varchar(255) DEFAULT '', bgcolour char(6) NOT NULL, entry integer NOT NULL, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, ip varchar(45) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$memengine$charset;");
@ -3994,18 +4039,21 @@ function update_db(){
$db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);');
$db->exec('ALTER TABLE ' . PREFIX . 'inbox ADD FOREIGN KEY (recipient) REFERENCES ' . PREFIX . 'members(nickname) ON DELETE CASCADE ON UPDATE CASCADE;');
}
if($dbversion<42){
$db->exec('INSERT IGNORE INTO ' . PREFIX . "settings (setting, value) VALUES ('filtermodkick', '1');");
}
update_setting('dbversion', DBVERSION);
if($msgencrypted!==MSGENCRYPTED){
if(!extension_loaded('openssl')){
send_fatal_error($I['opensslextrequired']);
if(!extension_loaded('sodium')){
send_fatal_error($I['sodiumextrequired']);
}
$result=$db->query('SELECT id, text FROM ' . PREFIX . 'messages;');
$stmt=$db->prepare('UPDATE ' . PREFIX . 'messages SET text=? WHERE id=?;');
while($message=$result->fetch(PDO::FETCH_ASSOC)){
if(MSGENCRYPTED){
$message['text']=openssl_encrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY));
}else{
$message['text']=openssl_decrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY);
}
$stmt->execute([$message['text'], $message['id']]);
}
@ -4013,9 +4061,9 @@ function update_db(){
$stmt=$db->prepare('UPDATE ' . PREFIX . 'notes SET text=? WHERE id=?;');
while($message=$result->fetch(PDO::FETCH_ASSOC)){
if(MSGENCRYPTED){
$message['text']=openssl_encrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY));
}else{
$message['text']=openssl_decrypt($message['text'], 'aes-256-cbc', ENCRYPTKEY, 0, '1234567890123456');
$message['text']=sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY);
}
$stmt->execute([$message['text'], $message['id']]);
}
@ -4148,19 +4196,20 @@ function load_lang(){
'id' =>'Bahasa Indonesia',
'it' =>'Italiano',
'ru' =>'Русский',
'tr' =>'Türkçe',
'uk' =>'Українська',
'zh_CN' =>'简体中文',
];
if(isset($_REQUEST['lang']) && isset($L[$_REQUEST['lang']])){
$language=$_REQUEST['lang'];
if(!isset($_COOKIE['language']) || $_COOKIE['language']!==$language){
setcookie('language', $language);
set_secure_cookie('language', $language);
}
}elseif(isset($_COOKIE['language']) && isset($L[$_COOKIE['language']])){
$language=$_COOKIE['language'];
}else{
$language=LANG;
setcookie('language', $language);
set_secure_cookie('language', $language);
}
include('lang_en.php'); //always include English
if($language!=='en'){
@ -4172,12 +4221,17 @@ function load_lang(){
}
}
function isPOST(){
return $_SERVER['REQUEST_METHOD'] === 'POST';
}
function load_config(){
mb_internal_encoding('UTF-8');
define('VERSION', '1.23.6'); // Script version
define('DBVERSION', 41); // Database layout version
define('VERSION', '1.24.1'); // Script version
define('DBVERSION', 42); // Database layout version
define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing!
define('ENCRYPTKEY', 'MY_KEY'); // Encryption key for messages
define('ENCRYPTKEY_PASS', 'MY_SECRET_KEY'); // Recommended length: 32. Encryption key for messages
define('AES_IV_PASS', '012345678912'); // Recommended length: 12. AES Encryption IV
define('DBHOST', 'localhost'); // Database host
define('DBUSER', 'www-data'); // Database user
define('DBPASS', 'YOUR_DB_PASS'); // Database password
@ -4195,4 +4249,20 @@ function load_config(){
}
define('COOKIENAME', PREFIX . 'chat_session'); // Cookie name storing the session information
define('LANG', 'en'); // Default language
if (MSGENCRYPTED){
if (version_compare(PHP_VERSION, '7.2.0') < 0) {
die("You need at least PHP >= 7.2.x");
}
//Do not touch: Compute real keys needed by encryption functions
if (strlen(ENCRYPTKEY_PASS) !== SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES){
define('ENCRYPTKEY', substr(hash("sha512/256",ENCRYPTKEY_PASS),0, SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES));
}else{
define('ENCRYPTKEY', ENCRYPTKEY_PASS);
}
if (strlen(AES_IV_PASS) !== SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES){
define('AES_IV', substr(hash("sha512/256",AES_IV_PASS), 0, SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES));
}else{
define('AES_IV', AES_IV_PASS);
}
}
}

View File

@ -0,0 +1,8 @@
.msg {padding: 0.5em 0; border-bottom: 1px solid #363636}
input, select, textarea, button {padding: 0.2em; border: 1px solid #ffffff; border-radius: 0.5em}
#messages small {color: #989898}
#messages {display: block; width: 79%}
.messages #topic {display: block; width: 79%}
.messages #chatters {display: block; float:right; width: 20%; overflow-y: auto; position:fixed; right:0; max-height:100%; bottom:2em; top:2em;}
.messages #chatters td, #chatters tr, #chatters th {display: table-row; width: 100%!important;}
.messages #chatters table a {display: table-row; line-height: 0;}

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Bulgarian translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -310,7 +310,7 @@ $T=[
'nopass' => 'Невалидна парола (поне %d символа), не променям ника',
'gdextrequired' => 'Добавката gd за PHP е необходима за тази функционалност. Моля, първо я инсталирайте.',
'memcachedextrequired' => 'Добавката memcached за PHP е необходима за кеш функционалностите. Моля, първо я инсталирайте или върнете настройките за memcached обратно на false.',
'opensslextrequired' => 'Добавката openssl за PHP е необходима the криптиращата функционалност. Моля, първо я инсталирайте или върнете настройките за криптиране обратно на false.',
'sodiumextrequired' => 'Добавката libsodium за PHP е необходима the криптиращата функционалност. Моля, първо я инсталирайте или върнете настройките за криптиране обратно на false.',
'pdo_mysqlextrequired' => 'Добавката pdo_mysql за PHP е необходима за избрания драйвер за базата данни. Моля, първо я инсталирайте.',
'pdo_pgsqlextrequired' => 'Добавката pdo_pgsql за PHP е необходима за избрания драйвер за базата данни. Моля, първо я инсталирайте.',
'pdo_sqliteextrequired' => 'Добавката pdo_sqlite за PHP е необходима за избрния драйвер за базата данни. Моля, първо я инсталирайте.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Czech translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,7 +19,7 @@
*/
//Native language name: čeština
$I=[
$T=[
'nodb' => 'Chyba databáze!',
'nodbsetup' => 'Žádné připojení k databázi, prosím vytvořte databázi a upravte script pro použití správné databáze se zadaným uživatelským jménem a heslem!',
'changelang' => 'Změnit jazyk:',
@ -310,7 +310,7 @@ $I=[
'nopass' => 'Chybné heslo (Nejméně %d znaků), přezdívka zůstala stejná',
'gdextrequired' => 'Rozšíření PHP gd je pro tuto funkci vyžadováno. Nejprve ho nainstalujte.',
'memcachedextrequired' => 'Pro funkci ukládání do mezipaměti je vyžadováno memcached rozšíření PHP. Nejprve ho nainstalujte, nebo nastavte parametr memcached na hodnotu false.',
'opensslextrequired' => 'Pro funkci šifrování je vyžadováno rozšíření PHP openssl. Nejprve ho nainstalujte nebo nastavte šifrované nastavení zpět na hodnotu false.',
'sodiumextrequired' => 'Pro funkci šifrování je vyžadováno rozšíření PHP libsodium. Nejprve ho nainstalujte nebo nastavte šifrované nastavení zpět na hodnotu false.',
'pdo_mysqlextrequired' => 'Rozšíření pdo_mysql PHP je vyžadováno pro zvolený ovladač databáze. Nejprve ho nainstalujte.',
'pdo_pgsqlextrequired' => 'Pro zvolený databázový ovladač je vyžadováno rozšíření PHP pdo_pgsql. Nejprve ho nainstalujte.',
'pdo_sqliteextrequired' => 'Rozšíření pdo_sqlite PHP je vyžadováno pro zvolený ovladač databáze. Nejprve ho nainstalujte.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - German translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -241,6 +241,7 @@ $T=[
'YellowGreen' => 'Gelbgrün',
'redirectto' => 'Leite weiter zu:',
'nonhttp' => 'Nicht-http Adresse angefordert:',
'dangerousnonhttp' => 'Nicht-http Adresse angefordert. Kopieren Sie diesen Link und fügen ihn ein, falls Sie wirklich sicher sind.:',
'httpredir' => 'Wenn sie nicht funktioniert, probiere diese:',
'actions' => 'Aktionen',
'sesip' => 'IP-Adresse',
@ -310,7 +311,7 @@ $T=[
'nopass' => 'Ungültiges Passwort (Mindestens %d Zeichen), Nickname nicht geändert',
'gdextrequired' => 'Für diese Funktion wird die gd Erweiterung von PHP benötigt. Bitte installieren Sie diese zuerst.',
'memcachedextrequired' => 'Die memcached Erweiterung von PHP wird benötigt, um die Cache-Funktion zu benutzen. Bitte installieren Sie diese zuerst oder setzen Sie die memcached Einstellung zurück auf false.',
'opensslextrequired' => 'Die openssl Erweiterung von PHP wird benötigt, um die Verschlüsselungs-Funktion zu benutzen. Bitte installieren Sie diese zuerst oder setzen Sie die encrypted Einstellung zurück auf false.',
'sodiumextrequired' => 'Die libsodium Erweiterung von PHP wird benötigt, um die Verschlüsselungs-Funktion zu benutzen. Bitte installieren Sie diese zuerst oder setzen Sie die encrypted Einstellung zurück auf false.',
'pdo_mysqlextrequired' => 'Die pdo_mysql Erweiterung von PHP wird für den ausgewählten Datenbanktreiber benötigt. Bitte installieren Sie diese zuerst.',
'pdo_pgsqlextrequired' => 'Die pdo_pgsql Erweiterung von PHP wird für den ausgewählten Datenbanktreiber benötigt. Bitte installieren Sie diese zuerst.',
'pdo_sqliteextrequired' => 'Die pdo_sqlite Erweiterung von PHP wird für den ausgewählten Datenbanktreiber benötigt. Bitte installieren Sie diese zuerst.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - English translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -241,6 +241,7 @@ $I=[
'YellowGreen' => 'Yellow green',
'redirectto' => 'Redirecting to:',
'nonhttp' => 'Non-http link requested:',
'dangerousnonhttp' => 'Dangerous non-http link requested, copy paste this link if you are really sure:',
'httpredir' => 'If it\'s not working, try this one:',
'actions' => 'Actions',
'sesip' => 'IP-Address',
@ -310,7 +311,7 @@ $I=[
'nopass' => 'Invalid password (At least %d characters), not changing nickname',
'gdextrequired' => 'The gd extension of PHP is required for this feature. Please install it first.',
'memcachedextrequired' => 'The memcached extension of PHP is required for the caching feature. Please install it first or set the memcached setting back to false.',
'opensslextrequired' => 'The openssl extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'sodiumextrequired' => 'The libsodium extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'pdo_mysqlextrequired' => 'The pdo_mysql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_pgsqlextrequired' => 'The pdo_pgsql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_sqliteextrequired' => 'The pdo_sqlite extension of PHP is required for the selected database driver. Please install it first.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Spanish translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -310,7 +310,7 @@ $T=[
'nopass' => 'Constraseña incorrecta (al menos %d caracteres), no se cambia apodo',
'gdextrequired' => 'La extensión gd de PHP es requerida para esto. Instálela primero.',
'memcachedextrequired' => 'La extensión memcached de PHP es requerida para esto. Instalela primero o configure memcached en false.',
'opensslextrequired' => 'La extensión openssl de PHP es necesaria para la encriptación. Instálela o configure la encriptación en false.',
'sodiumextrequired' => 'La extensión libsodium de PHP es necesaria para la encriptación. Instálela o configure la encriptación en false.',
'pdo_mysqlextrequired' => 'La extensión pdo_mysql de PHP es necesaria para la database driver seleccionada. Instálelo primero.',
'pdo_pgsqlextrequired' => ' La extensión pdo_pgsql de PHP es necesaria para la database driver seleccionada. Instálelo primero.',
'pdo_sqliteextrequired' => ' La extensión pdo_sqlite de PHP es necesaria para la database driver seleccionada. Instálelo primero.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - French translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Indonesian translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Italian translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -310,7 +310,7 @@ $T=[
'nopass' => 'Password sbagliata (Almeno %d simboli), senza cambiare nome',
'gdextrequired' => 'The gd extension of PHP is required for this feature. Please install it first.',
'memcachedextrequired' => 'The memcached extension of PHP is required for the caching feature. Please install it first or set the memcached setting back to false.',
'opensslextrequired' => 'The openssl extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'sodiumextrequired' => 'The libsodium extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'pdo_mysqlextrequired' => 'The pdo_mysql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_pgsqlextrequired' => 'The pdo_pgsql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_sqliteextrequired' => 'The pdo_sqlite extension of PHP is required for the selected database driver. Please install it first.',

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Russian translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -310,7 +310,7 @@ $T=[
'nopass' => 'Некорректный пароль (Хотя бы %d символов), не меняя имени',
'gdextrequired' => 'gd расширение для PHP требуетса для етой функции. Пожалуйста установите его сначала...',
'memcachedextrequired' => 'The memcached extension of PHP is required for the caching feature. Please install it first or set the memcached setting back to false.',
'opensslextrequired' => 'The openssl extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'sodiumextrequired' => 'The libsodium extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'pdo_mysqlextrequired' => 'Pdo_mysql расширение для PHP требуетса для драйверов базы данных. Пожалуйста установите его сначала..',
'pdo_pgsqlextrequired' => 'Pdo_pgsql расширение для PHP требуетса для драйверов базы данных. Пожалуйста установите его сначала..',
'pdo_sqliteextrequired' => 'Pdo_sqlite расширение для PHP требуетса для драйверов базы данных. Пожалуйста установите его сначала.',

371
lang_tr.php Normal file
View File

@ -0,0 +1,371 @@
<?php
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - English translation
*
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//Native language name: Türkçe
$T=[
'nodb' => 'Veritabanına bağlantı yok!',
'nodbsetup' => 'Veritabanına bağlantı yok, lütfen bir veritabanı oluşturun ve doğru veritabanını kullanmak için script\'i verilen kullanıcı adı ve şifre ile düzenleyin!',
'changelang' => 'Dili değiştir:',
'expire' => 'Geçersiz/tarihi geçmiş oturum',
'kicked' => 'Atıldınız!',
'invalnick' => 'Geçersiz kullanıcı adı (En fazla %1$d harf ve normal ifade "%2$s" ile eşleşmeli)',
'invalpass' => 'Geçersiz şifre (En az %1$d harf ve normal ifade "%2$s" ile eşleşmeli)',
'noconfirm' => 'Şifreler birbirleriyle eşleşmiyor!',
'incorregex' => 'Yanlış normal ifade!',
'bottom' => 'Alt',
'top' => 'Üst',
'choose' => '(seç)',
'setup' => 'Sohbet kurulumu',
'init' => 'İlk kurulum',
'sulogin' => 'Superadmin Girişi',
'sunick' => 'Superadmin Kullanıcı adı:',
'supass' => 'Superadmin Şifre:',
'suconfirm' => 'Şifreyi doğrula:',
'susuccess' => 'Başarılı bir şekilde kayıt olundu!',
'initbtn' => 'Sohbeti Başlat',
'initdbexist' => 'Veritabanı tabloları zaten bulunuyor! Devam etmek için, tabloları manuel olarak silmeniz lazım.',
'initsuexist' => 'Bir Superadmin zaten bulunuyor!',
'initgosetup' => 'Kurulum sayfasına git',
'captcha' => 'Captcha',
'enabled' => 'Etkinleştirildi',
'onlyguests' => 'Sadece konuklar için',
'disabled' => 'Devre dışı',
'simple' => 'Basit',
'moderate' => 'Orta',
'extreme' => 'Aşırı',
'nick' => 'Kullanıcı adı:',
'pass' => 'Şifre:',
'globalloginpass' => 'Global şifre:',
'login' => 'Giriş',
'dbupdate' => 'Veritabanı başarıyla güncellendi!',
'sysmessages' => 'Sistem iletileri',
'msgenter' => 'Giriş',
'msgexit' => 'Ayrılınıyor',
'msgmemreg' => 'Üye kaydedildi',
'msgsureg' => 'Başvuru kaydedildi',
'msgkick' => 'Atıldı',
'msgmultikick' => 'Toplu atıldı',
'msgallkick' => 'Hepsi atıldı',
'msgclean' => 'Oda temizlendi',
'dateformat' => '<a target="_blank" href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">Tarih biçimlendirme</a>',
'admfunc' => 'Yönetici işlemleri',
'allguests' => 'Tüm konuklar',
'cleanmsgs' => 'İletileri temizle',
'room' => 'Tüm oda',
'selection' => 'Seçim',
'cleannick' => 'Şu kullanıcı adını:',
'clean' => 'Temizle',
'kickchat' => 'Kullanıcıyı at (%d dakika)',
'kickreason' => 'Atılma nedeni:',
'kickpurge' => 'İletileri temizle',
'kick' => 'At',
'logoutinact' => 'İnaktif kişiyi oturumdan çıkar',
'logout' => ıkış yap',
'sessions' => 'Aktif oturumlara bak',
'view' => 'Görüntüle',
'filter' => 'Filtrele',
'guestacc' => 'Konuk erişimini değiştir',
'guestallow' => 'İzin ver',
'guestwait' => 'Bekleme odasına izin ver',
'adminallow' => 'Moderatör onayı gerekiyor',
'guestdisallow' => 'Sadece üyeler',
'addsuguest' => 'Başvuru kayıt et',
'register' => 'Kayıt ol',
'admmembers' => 'Üyeler',
'memdel' => 'Veritabanından sil',
'memdeny' => 'Erişimi reddet (!)',
'memsuguest' => 'Set to applicant (G)',
'memreg' => 'Normal üye yap',
'memmod' => 'Moderatör yap (Ü)',
'memsumod' => 'Süpermod yap (SM)',
'memadm' => 'Yönetici yap (Y)',
'change' => 'Değiştir',
'regguest' => 'Misafir kaydet',
'regmem' => 'Yeni Üye kaydet',
'sessact' => 'Aktif Oturumlar',
'sessnick' => 'Kullanıcı adı',
'sesstimeout' => 'Zaman aşımı',
'sessua' => 'User-Agent',
'fid' => 'ID Filtrele:',
'match' => 'Eşleş',
'replace' => 'Değiştir',
'allowpm' => 'Allow in PM',
'regex' => 'Regex',
'apply' => 'Uygula',
'newfilter' => 'Yeni filtre:',
'add' => 'Ekle',
'noframes' => 'Bu sohbet <b>çerçeveleri</b> kullanıyor. Please enable frames in your browser or use a suitable one!',
'delselmes' => 'Seçili iletileri sil',
'staffnotes' => 'Yetkili notları',
'adminnotes' => 'Yönetici notları',
'notessaved' => 'Notlar kaydedildi!',
'lastedited' => 'Son düzenleme %1$s tarafından %2$s tarihinde',
'savenotes' => 'Notları kaydet',
'waitingroom' => 'Bekleme odası',
'waittext' => 'Hoş geldiniz %1$s, girişiniz geciktirildi, sohbete %2$d saniye içinde erişebilirsiniz.',
'admwaittext' => 'Hoş geldiniz %1$s, girişiniz geciktirildi, sohbete bir moderatör girmenize izin verirse erişebilirsiniz.',
'waitreload' => 'Eğer sayfa %d saniye içinde yenilenmiyorsa, elinizle yenilemek için alttaki düğmeyi kullanın!',
'reload' => 'Yenile',
'rules' => 'Kurallar',
'talkto' => 'Şuna gönder',
'toall' => 'Tüm kullanıcılar',
'tomem' => 'Sadece üyeler',
'tostaff' => 'Sadece yetkililer',
'toadmin' => 'Sadece yönetici',
'alsopurge' => 'Ayrıca iletileri temizle',
'dellast' => 'Son iletiyi sil',
'delall' => 'Tüm iletileri sil',
'switchsingle' => 'Tek-satıra geç',
'switchmulti' => 'Çoklu-satıra geç',
'help' => 'Yardım',
'helpguest' => 'Tüm işlemler anlaşılabilir olmalı, sadece düğmeleri kullanın. Profilinizde yenileme aralığını ve yazı rengini değiştirebilir, aynı zamanda üyeleri göz ardı edebilirsiniz.<br><u>Not:</u> Bu bir sohbet, eğer konuşmayı bırakırsanız, bir süre sonra otomatik olarak oturumdan atılırsınız.',
'helpembed' => 'Eğer iletinize bir görsel eklemek istiyorsanız, basit bir şekilde görsel URL\'sinin önüne [img] koyun. Örnek: [img]http://example.com/images/file.jpg yazmak iletinizdeki görseli ekler.',
'helpmem' => 'Üyeler: Profilinizde biraz daha seçenek var. Yazı tipini ayarlayabilir, şifrenizi istediğiniz zaman değiştirebilir ve tabii ki hesabınızı silebilirsiniz.',
'helpmod' => 'Moderatörler: En alttaki Yönetici düğmesine dikkat edin. Odayı temizleyebileceğiniz, kişileri atabileceğiniz, aktif oturumları görebileceğiniz ve konuk erişimini kapatabileceğiniz bir sayfa gelecektir.',
'helpadm' => 'Yöneticiler: Konukları kaydedebilir, üyeleri düzenleyebilir ve yeni kullanıcı adları kaydedebilirsiniz.',
'profile' => 'Profiliniz',
'ignore' => 'Görmezden gel',
'unignore' => 'Görmezden gelmeyi bırak',
'refreshrate' => 'Yenileme aralığı (5-150 saniye)',
'fontcolour' => 'Yazı tipi rengi',
'viewexample' => 'Örnekleri görüntüle',
'bgcolour' => 'Arkaplan rengi',
'fontface' => 'Yazıtipi yüzü',
'roomdefault' => 'Oda Varsayılanı',
'bold' => 'Kalın',
'italic' => 'İtalik',
'small' => 'Küçük',
'fontexample' => 'Seçtiğin yazı tipi için örnek',
'timestamps' => 'Zaman damgalarını göster',
'embed' => 'Gömülü görseller',
'incognito' => 'Incognito modu',
'changenick' => 'Kullanıcı adını değiştir',
'changepass' => 'Şifreyi değiştir',
'oldpass' => 'Eski şifre:',
'newpass' => 'Yeni şifre:',
'confirmpass' => 'Yeni şifreyi doğrula:',
'savechanges' => 'Değişiklikleri kaydet',
'reloadpb' => 'Posta Kutusunu Yenile',
'reloadmsgs' => 'İletileri yenile',
'chgprofile' => 'Profil',
'adminbtn' => 'Yönetici',
'admnotes' => 'Yönetici Notları',
'notes' => 'Notlar',
'clone' => 'Klonla',
'randh' => 'Kurallar & Yardım',
'exit' => 'Sohbetten çık',
'bye' => 'Görüşürüz %s, en yakın zamanda yine uğra!',
'colourtable' => 'Renk tablosu',
'backtoprofile' => 'Profiline geri dön',
'copy' => 'Kopyala:',
'choosecol' => 'Konuklar, bir renk seçin:',
'randomcol' => 'Rastgele renk',
'enter' => 'Sohbete gir',
'error' => 'Hata',
'members' => 'Üyeler',
'guests' => 'Konuklar',
'approveguests' => '%d tane onaylanacak konuk',
'allowchecked' => 'Kontrol edilenlere izin ver',
'allowall' => 'Hepsine izin ver',
'denychecked' => 'Kontrol edilenleri reddet',
'denyall' => 'Hepsini reddet',
'denymessage' => 'Reddedilene ileti gönder:',
'butallowdeny' => 'Gönder',
'waitempty' => 'Onaylanacak daha fazla giriş isteği yok.',
'wrongcaptcha' => 'Yanlış captcha',
'captchaexpire' => 'Captcha zaten kullanılmış veya zamanıılmış.',
'noguests' => 'Üzgünüm, şu anlık sadece üyeler!',
'curchat' => 'Şu anda odada %d kişi var:',
'cantreg' => '%s kayıt edilemiyor',
'alreadyreged' => '%s zaten kayıtlı.',
'successreg' => '%s kayıt oldu.',
'cantchgstat' => '%s\'ın statüsü değiştirilemiyor!',
'succdel' => '%s başarılı bir şekilde veritabanından silindi.',
'succchg' => '%s\'ın statüsü başarıyla değiştirildi.',
'wrongpass' => 'Yanlış şifre!',
'wrongglobalpass' => 'Yanlış global şifre!',
'succprofile' => 'Profiliniz başarıyla kaydedildi.',
'backtologin' => 'Giriş ekranına geri dön.',
'backtochat' => 'Sohbete geri dön.',
'Beige' => 'Bej',
'Black' => 'Kahverengi',
'Blue' => 'Mavi',
'BlueViolet' => 'Mavi mor',
'Brown' => 'Kahverengi',
'Cyan' => 'Camgöbeği',
'DarkBlue' => 'Koyu mavi',
'DarkGreen' => 'Koyu yeşil',
'DarkRed' => 'Koyu red',
'DarkViolet' => 'Koyu mor',
'DeepSkyBlue' => 'Gökyüzü mavisi',
'Gold' => 'Altın',
'Grey' => 'Gri',
'Green' => 'Yeşil',
'HotPink' => 'Sıcak pembe',
'Indigo' => 'Indigo',
'LightBlue' => 'Açık mavi',
'LightGreen' => 'Açık yeşil',
'LimeGreen' => 'Limon yeşili',
'Magenta' => 'Magenta',
'Olive' => 'Zeytin',
'Orange' => 'Turuncu',
'OrangeRed' => 'Turuncu kırmızı',
'Purple' => 'Mor',
'Red' => 'Kırmızı',
'RoyalBlue' => 'Kraliyet mavisi',
'SeaGreen' => 'Deniz yeşili',
'Sienna' => 'Sienna',
'Silver' => 'Gümüş',
'Tan' => 'Tan',
'Teal' => 'Teal',
'Violet' => 'Mor',
'White' => 'Beyaz',
'Yellow' => 'Sarı',
'YellowGreen' => 'Sarı yeşil',
'redirectto' => 'Şuna yönlendiriliyor:',
'nonhttp' => 'HTTP olmayan bağlantı istenildi:',
'dangerousnonhttp' => 'Tehlikeli HTTP olmayan bağlantı istenildi, eğer eminseniz bu bağlantıyı kopyalayıp yapıştırın:',
'httpredir' => 'Eğer çalışmıyorsa, bunu deneyin:',
'actions' => 'Eylemler',
'sesip' => 'IP Adresi',
'css' => 'CSS Stili',
'memberexpire' => 'Üye zaman aşımı (dakika)',
'guestexpire' => 'Konuk zaman aşımı (dakika)',
'kickpenalty' => 'Atım cezası (dakika)',
'entrywait' => 'Bekleme odası zamanı (saniye)',
'captchatime' => 'Captcha zaman aşımı (saniye)',
'messageexpire' => 'İleti zaman aşımı (dakika)',
'messagelimit' => 'İleti sınırı (herkese açık)',
'maxmessage' => 'Maksimum ileti uzunluğu',
'confirm' => 'Emin misiniz?',
'yes' => 'Evet',
'no' => 'Hayır',
'colbg' => 'Arkaplan rengi',
'coltxt' => 'Yazı rengi',
'maxname' => 'Maksimum şifre uzunluğu',
'minpass' => 'Minimum şifre uzunluğu',
'defaultrefresh' => 'Varsayılan mesaj yenileme süresi (saniye)',
'suguests' => 'Başvuru sahiplerini etkinleştir',
'rulestxt' => 'Kurallar (html)',
'imgembed' => 'Gömülü görseller',
'trackip' => 'Oturum IP\'sini göster',
'captchachars' => 'Captcha\'da kullanılan harfler',
'memkick' => 'Eğer herhangi bir moderatör yoksa, üyeler birini atabilir',
'forceredirect' => 'Yönlendirmeye zorla',
'redirect' => 'Özel yönlendirme script\'i',
'backuprestore' => 'Yedekle ve onar',
'backup' => 'Backup',
'restore' => 'Onar',
'settings' => 'Ayarlar',
'linkfilter' => 'Linkfilter',
'chatname' => 'Sohbet ismi',
'destroy' => 'Sohbeti yok et',
'destroyed' => 'Sohbet başarıyla yok edildi',
'topic' => 'Konu',
'passreset' => 'Şifreyi değiştir',
'cantresetpass' => 'Şifre değiştirilemiyor',
'succpassreset' => 'Şifre başarıyla değiştirildi',
'entermsg' => '%s sohbete katıldı.',
'exitmsg' => '%s sohbetten çıktı.',
'memregmsg' => '%s artık bir kayıtlı üye.',
'suregmsg' => '%s artık başvuru sahibi.',
'kickmsg' => '%s atıldı.',
'multikickmsg' => '%s atıldı.',
'allkickmsg' => 'Tüm konuklar atıldı.',
'cleanmsg' => '%s temizlendi.',
'sendallmsg' => '%s - ',
'sendmemmsg' => '[Ü] %s - ',
'sendmodmsg' => '[Yetkili] %s - ',
'sendadmmsg' => '[Yönetici] %s - ',
'sendprvmsg' => '[%1$s to %2$s] - ',
'msgsendall' => 'Herkese gönder',
'msgsendmem' => 'Sadece üyelere gönder',
'msgsendmod' => 'Sadece yetkililere gönder',
'msgsendadm' => 'Sadece yöneticilere gönder',
'msgsendprv' => 'Özel ileti',
'numnotes' => 'Number of notes revisions to keep',
'revisions' => 'Revisions:',
'older' => 'Daha eski',
'newer' => 'Daha yeni',
'accessdenied' => 'Erişin reddedildi',
'loggedinas' => '%s olarak giriş yaptınız ve bu bölüme erişiminiz yok.',
'newnickname' => 'Yeni kullanıcı adı:',
'nicknametaken' => 'Kullanıcı adı zaten alınmış',
'nopass' => 'Geçersiz şifre (En az %d harf), kullanıcı adı değiştirilmiyor',
'gdextrequired' => 'Bu özellik için PHP\'nin gd uzantısı gerekiyor. Lütfen önce onu kurun.',
'memcachedextrequired' => 'Önbelleğe alma özelliği için PHP\'nin memcached uzantısı gerekiyor. Lütfen ilk önce onu kurun veya memcached özelliğini devre dışı bırakın.',
'sodiumextrequired' => 'Şifreleme için PHP\'nin libsodium uzantısı gerekiyor. Lütfen ilk önce onu kurun veya şifreleme özelliğini devre dışı bırakın.',
'pdo_mysqlextrequired' => 'Seçili veritabanı sürücüsü için PHP\'nin pdo_mysql uzantısı gerekiyor. Lütfen ilk önce onu kurun.',
'pdo_pgsqlextrequired' => 'Seçili veritabanı sürücüsü için PHP\'nin pdo_mysql uzantısı gerekiyor. Lütfen ilk önce onu kurun.',
'pdo_sqliteextrequired' => 'Seçili veritabanı sürücüsü için PHP\'nin pdo_sqlite uzantısı gerekiyor. Lütfen ilk önce onu kurun.',
'jsonextrequired' => 'Bu özellik için PHP\'nin json uzantısı gerekiyor. Lütfen ilk önce onu kurun.',
'sendmail' => 'Yeni herkese açık mesajla posta gönder',
'mailsender' => 'Bu adresi kullanarak posta gönder',
'mailreceiver' => 'Bu adrese posta gönder',
'modfallback' => 'Eğer konukları onaylayacak moderatör yoksa, bekleme odasına düş',
'regpass' => 'Kayıt olmak için<br>şifreyi tekrarla',
'guestreg' => 'Konukların kendilerini kayıt etmelerine izin ver',
'asmember' => 'Üye olarak',
'assuguest' => 'Başvuru sahibi olarak',
'fatalerror' => 'Kritik hata',
'prevmatch' => 'Eşleşmeniz aşağıdaki gibiydi',
'matchtoolong' => 'Eşleşmeniz çok uzundu. En fazla 255 harf kullanabilirsiniz. Bölmeyi deneyin.',
'nocache' => 'Otomatik kaydırma (eski tarayıclar veya yukarıdan-aşağıya görüntüleme için).',
'disablepm' => 'Özel mesajları devre dışı bırak',
'disablechat' => 'Sohbeti devre dışı bırak',
'disabletext' => 'Sohbet mesajı devre dışı bıraktı (html)',
'disabledtext' => 'Geçici olarak devre dışı',
'defaulttz' => 'Varsayılan zaman dilimi',
'tz' => 'Zaman dilimi',
'optional' => '(isteğe bağlı)',
'userloggedin' => 'Bu kullanıcı ismine sahip birisi zaten giriş yapmış.',
'regednick' => 'Bu kullanıcı adı kayıtlı bir üyeye ait.',
'eninbox' => 'Çevrimdışı gelen kutusunu etkinleştir',
'inboxmsgs' => 'Gelen kutunuzdaki %d mesajı okuyun',
'offline' => '(çevrimdışı)',
'deleteacc' => 'Hesabı sil',
'eninnone' => 'Hiç kimse için',
'eninall' => 'Herkes için',
'eninmem' => 'Sadece üyeler için',
'eninstaff' => 'Sadece yetkililer için',
'eninadmin' => 'Sadece yöneticiler için',
'nickregex' => 'Kullanıcı adı regex',
'passregex' => 'Şifre regex',
'externalcss' => 'Dış CSS dosyasının bağlantısı',
'greetingmsg' => 'Hoş geldin %s!',
'entryhelp' => 'Eğer çerçeve %d saniye içinde yenilenmiyorsa, tarayıcınızda otomatik yönlendirmeyi (meta refresh) açmanız lazım. Ayrıca web filtresi, yerel proxy aracı veya tarayıcı uzantılarının otomatik yönlendirmeyi engellemediğinden emin olun! Buna örnek olarak "Polipo", "NoScript", vb. verilebilir<br>Geçici bir çözüm olarak (veya sunucu/proxy yenileme hataları olursa) her zaman aşağıdaki düğmeler ile manuel olarak yenileyebilirsiniz.',
'enablegreeting' => 'İletileri göstermeden önce selamlama mesajı göster',
'unban' => 'Yasaklamayı kaldır',
'sortupdown' => 'İletileri yukarıdan aşağıya doğru sırala',
'sortframe' => 'Yeniden düzenle',
'cs' => 'Büyük harf/küçük harf duyarlı',
'hidechatters' => 'Sohbet edenlerin listesini gizle',
'enfileupload' => 'Dosya yüklemelerine izin ver',
'msgattache' => 'Ek',
'filenotfound' => 'Dosya bulunamadı!',
'maxuploadsize' => 'KB olarak en fazla yükleme boyutu',
'maxsize' => 'En fazla %d KB',
'cssupdate' => 'Not: Default CSS is now hardcoded and can be removed from the CSS setting',
'manualrefresh' => 'Manuel yenileme gerekli',
'personalnotes' => 'Kişisel notlar',
'filtermodkick' => 'Moderatörler için atma filtresini etkinleştir',
];

View File

@ -2,7 +2,7 @@
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Ukrainian translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -310,7 +310,7 @@ $T=[
'nopass' => 'Негідний пароль (Хотя б %d символів), не міняя імя',
'gdextrequired' => 'The gd extension of PHP is required for this feature. Please install it first.',
'memcachedextrequired' => 'The memcached extension of PHP is required for the caching feature. Please install it first or set the memcached setting back to false.',
'opensslextrequired' => 'The openssl extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'sodiumextrequired' => 'The libsodium extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'pdo_mysqlextrequired' => 'The pdo_mysql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_pgsqlextrequired' => 'The pdo_pgsql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_sqliteextrequired' => 'The pdo_sqlite extension of PHP is required for the selected database driver. Please install it first.',

View File

@ -8,7 +8,7 @@ $file = "<?php
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - $english translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
* Copyright (C) 2015-2020 Daniel Winzen <daniel@danwin1210.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,23 +1,4 @@
<?php
/*
* LE CHAT-PHP - a PHP Chat based on LE CHAT - Simplified Chinese translation
*
* Copyright (C) 2015-2018 Daniel Winzen <d@winzen4.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//Native language name: 简体中文
$T=[
'nodb' => '没有连接到数据库!',
@ -29,8 +10,8 @@ $T=[
'invalpass' => '无效的密码 (至少包含%1$d个字符并且必须与正则表达式"%2$s"匹配)',
'noconfirm' => '重复密码不匹配!',
'incorregex' => '正则表达式错误!',
'bottom' => 'Bottom',
'top' => '排行',
'bottom' => '底部',
'top' => '顶部',
'choose' => '(选择)',
'setup' => '安装程序',
'init' => '初始化设置',
@ -64,7 +45,7 @@ $T=[
'msgmultikick' => '批量踢出',
'msgallkick' => '全部踢出',
'msgclean' => '房间清理',
'dateformat' => '<a target="_blank" href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">Date formating</a>',
'dateformat' => '<a target="_blank" href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">日期格式</a>',
'admfunc' => '管理员功能',
'allguests' => '全部游客',
'cleanmsgs' => '清理消息',
@ -83,7 +64,7 @@ $T=[
'filter' => '过滤',
'guestacc' => '修改游客访问',
'guestallow' => '允许',
'guestwait' => 'Allow with waitingroom',
'guestwait' => '等候室允许',
'adminallow' => '请求审核人批准',
'guestdisallow' => '只仅正式成员',
'addsuguest' => '注册申请员',
@ -94,7 +75,7 @@ $T=[
'memsuguest' => '申请为申请人 (G)',
'memreg' => '设置为正式成员',
'memmod' => '设置为主持人 (M)',
'memsumod' => 'Set to supermod (SM)',
'memsumod' => '设置为0.5 (SM)',
'memadm' => '设置为管理员 (A)',
'change' => '修改',
'regguest' => '注册游客',
@ -119,246 +100,246 @@ $T=[
'lastedited' => '上次由%1$s编辑 时间为%2$s',
'savenotes' => '保存说明',
'waitingroom' => '等候室',
'waittext' => 'Welcome %1$s, your login has been delayed, you can access the chat in %2$d seconds.',
'admwaittext' => 'Welcome %1$s, your login has been delayed, you can access the chat as soon, as a moderator lets you in.',
'waitreload' => 'If this page doesn\'t refresh every %d seconds, use the button below to reload it manually!',
'reload' => 'Reload',
'rules' => 'Rules',
'talkto' => 'Send to',
'toall' => 'All chatters',
'tomem' => 'Members only',
'tostaff' => 'Staff only',
'toadmin' => 'Admin only',
'alsopurge' => 'Also purge messages',
'dellast' => 'Delete last message',
'delall' => 'Delete all messages',
'switchsingle' => 'Switch to single-line',
'switchmulti' => 'Switch to multi-line',
'help' => 'Help',
'helpguest' => 'All functions should be pretty much self-explaining, just use the buttons. In your profile you can adjust the refresh rate, font colour and your preferred input box size.<br><u>Note:</u> This is a chat, so if you don\'t keep talking, you will be automatically logged out after a while.',
'helpembed' => 'If you want to embed an image in your post, simply put [img] in front of your image URL. Example: [img]http://example.com/images/file.jpg will embed the image in your post.',
'helpmem' => 'Members: You\'ll have some more options in your profile. You can adjust your font face, change your password anytime and of course you can delete your account.',
'helpmod' => 'Moderators: Notice the Admin-button at the bottom. It\'ll bring up a page where you can clean the room, kick chatters, view all active sessions and disable guest access completely if needed.',
'helpadm' => 'Admins: You\'ll be furthermore able to register guests, edit members and register new nicknames.',
'profile' => 'Your Profile',
'ignore' => 'Ignore',
'unignore' => 'Don\'t ignore anymore',
'refreshrate' => 'Refresh rate (5-150 seconds)',
'fontcolour' => 'Font colour',
'viewexample' => 'View examples',
'bgcolour' => 'Background colour',
'fontface' => 'Fontface',
'roomdefault' => 'Room Default',
'bold' => 'Bold',
'italic' => 'Italic',
'fontexample' => 'Example for your chosen font',
'timestamps' => 'Show Timestamps',
'embed' => 'Embed images',
'incognito' => 'Incognito mode',
'changepass' => 'Change Password',
'oldpass' => 'Old password:',
'newpass' => 'New password:',
'confirmpass' => 'Confirm new password:',
'savechanges' => 'Save changes',
'reloadpb' => 'Reload Post Box',
'reloadmsgs' => 'Reload Messages',
'chgprofile' => 'Profile',
'adminbtn' => 'Admin',
'admnotes' => 'Admin Notes',
'notes' => 'Notes',
'clone' => 'Clone',
'randh' => 'Rules & Help',
'exit' => 'Exit Chat',
'bye' => 'Bye %s, visit again soon!',
'colourtable' => 'Colourtable',
'backtoprofile' => 'Back to your Profile',
'copy' => 'Copy:',
'choosecol' => 'Guests, choose a colour:',
'randomcol' => 'Random Colour',
'enter' => 'Enter Chat',
'error' => 'Error',
'members' => 'Members',
'guests' => 'Guests',
'approveguests' => '%d new guests to approve',
'allowchecked' => 'Allow checked',
'allowall' => 'Allow all',
'denychecked' => 'Deny checked',
'denyall' => 'Deny all',
'denymessage' => 'Send message to denied:',
'butallowdeny' => 'Submit',
'waitempty' => 'No more entry requests to approve.',
'wrongcaptcha' => 'Wrong Captcha',
'captchaexpire' => 'Captcha already used or timed out.',
'noguests' => 'Sorry, currently members only!',
'curchat' => 'Currently %d chatter(s) in room:',
'cantreg' => 'Can\'t register %s',
'alreadyreged' => '%s is already registered.',
'successreg' => '%s successfully registered.',
'cantchgstat' => 'Can\'t change status of %s',
'succdel' => '%s successfully deleted from database.',
'succchg' => 'Status of %s successfully changed.',
'wrongpass' => 'Wrong Password!',
'wrongglobalpass' => 'Wrong global Password!',
'succprofile' => 'Your profile has successfully been saved.',
'backtologin' => 'Back to the login page.',
'backtochat' => 'Back to the chat.',
'Beige' => 'Beige',
'Black' => 'Black',
'Blue' => 'Blue',
'BlueViolet' => 'Blue violet',
'Brown' => 'Brown',
'Cyan' => 'Cyan',
'DarkBlue' => 'Dark blue',
'DarkGreen' => 'Dark green',
'DarkRed' => 'Dark red',
'DarkViolet' => 'Dark violet',
'DeepSkyBlue' => 'Sky blue',
'Gold' => 'Gold',
'Grey' => 'Grey',
'Green' => 'Green',
'HotPink' => 'Hot pink',
'Indigo' => 'Indigo',
'LightBlue' => 'Light blue',
'LightGreen' => 'Light green',
'LimeGreen' => 'Lime green',
'Magenta' => 'Magenta',
'Olive' => 'Olive',
'Orange' => 'Orange',
'OrangeRed' => 'Orange red',
'Purple' => 'Purple',
'Red' => 'Red',
'RoyalBlue' => 'Royal blue',
'SeaGreen' => 'Sea green',
'Sienna' => 'Sienna',
'Silver' => 'Silver',
'Tan' => 'Tan',
'Teal' => 'Teal',
'Violet' => 'Violet',
'White' => 'White',
'Yellow' => 'Yellow',
'YellowGreen' => 'Yellow green',
'redirectto' => 'Redirecting to:',
'nonhttp' => 'Non-http link requested:',
'httpredir' => 'If it\'s not working, try this one:',
'actions' => 'Actions',
'sesip' => 'IP-Address',
'css' => 'CSS Style',
'memberexpire' => 'Member timeout (minutes)',
'guestexpire' => 'Guest timeout (minutes)',
'kickpenalty' => 'Kick penalty (minutes)',
'entrywait' => 'Waiting room time (seconds)',
'captchatime' => 'Captcha timeout (seconds)',
'messageexpire' => 'Message timeout (minutes)',
'messagelimit' => 'Message limit (public)',
'maxmessage' => 'Maximal message length',
'confirm' => 'Are you sure?',
'yes' => 'Yes',
'no' => 'No',
'colbg' => 'Background colour',
'coltxt' => 'Text colour',
'maxname' => 'Maximal nickname length',
'minpass' => 'Minimal password length',
'defaultrefresh' => 'Default message reload time (seconds)',
'suguests' => 'Enable applicants',
'rulestxt' => 'Rules (html)',
'imgembed' => 'Embed images',
'trackip' => 'Show session-IP',
'captchachars' => 'Characters used in Captcha',
'memkick' => 'Members can kick, if no moderator is present',
'forceredirect' => 'Force redirection',
'redirect' => 'Custom redirection script',
'backuprestore' => 'Backup and restore',
'backup' => 'Backup',
'restore' => 'Restore',
'settings' => 'Settings',
'linkfilter' => 'Linkfilter',
'chatname' => 'Chat name',
'destroy' => 'Destroy chat',
'destroyed' => 'Successfully destroyed chat',
'topic' => 'Topic',
'passreset' => 'Reset password',
'cantresetpass' => 'Can\'t reset password',
'succpassreset' => 'Successfully reset password',
'entermsg' => '%s entered the chat.',
'exitmsg' => '%s left the chat.',
'memregmsg' => '%s is now a registered member.',
'suregmsg' => '%s is now a registered applicant.',
'kickmsg' => '%s has been kicked.',
'multikickmsg' => '%s have been kicked.',
'allkickmsg' => 'All guests have been kicked.',
'cleanmsg' => '%s has been cleaned.',
'waittext' => '欢迎%1$s, 您的登录信息已被延迟,您可以访问聊天记录%2$d秒.',
'admwaittext' => '欢迎%1$s, 您的登录信息已被延迟,您可以尽快访问聊天内容,因为主持人会让您进入.',
'waitreload' => '如果这个页面没有刷新%d秒, 使用下面的按钮手动重新加载!',
'reload' => '刷新',
'rules' => '规则',
'talkto' => '发送至',
'toall' => '所有的聊天者',
'tomem' => '内部使用',
'tostaff' => '只供职员使用',
'toadmin' => '仅限管理员',
'alsopurge' => '同时清除消息',
'dellast' => '删除上一条消息',
'delall' => '删除所有信息',
'switchsingle' => '切换到单行',
'switchmulti' => '切换到多行',
'help' => '帮助',
'helpguest' => '这里一切解释权归我所有,只需使用按钮。 在您的配置文件中,您可以调整刷新率,字体颜色和首选输入框大小.<br><u>注意:</u> 这是一个聊天室,所以如果你不再说话,你会在一段时间后自动退出.',
'helpembed' => '如果您想在帖子中嵌入图片,只需将[img]放在图片网址前面即可。示例:[img]http://example.com/images/file.jpg会将图片嵌入到您的帖子中.',
'helpmem' => '成员:您的个人资料中还有更多选项。 您可以随时调整字体,更改密码,当然也可以删除您的帐户.',
'helpmod' => '版主:请注意底部。 它将打开一个页面,您可以在其中清理房间,踢聊天,查看所有活动会话并在需要时完全禁用访客访问权限.',
'helpadm' => '管理员:您还可以注册客人,编辑成员并注册新的昵称。',
'profile' => '你的个人资料',
'ignore' => '忽略',
'unignore' => '取消忽略',
'refreshrate' => '刷新时间(5-150)',
'fontcolour' => '字体颜色',
'viewexample' => '查看示例',
'bgcolour' => '背景色',
'fontface' => '字体',
'roomdefault' => '默认房间',
'bold' => '大胆',
'italic' => '斜体',
'fontexample' => '您选择的字体的示例',
'timestamps' => '显示时间戳',
'embed' => '嵌入图像',
'incognito' => '隐身模式',
'changepass' => '更改密码',
'oldpass' => '旧密码:',
'newpass' => '新密码:',
'confirmpass' => '在重复一次新密码:',
'savechanges' => '保存更改',
'reloadpb' => '刷新缓存',
'reloadmsgs' => '刷新一下消息',
'chgprofile' => '个人资料',
'adminbtn' => '管理',
'admnotes' => '管理员公告',
'notes' => '公告',
'clone' => '打开新标签',
'randh' => '条款 & 帮助',
'exit' => '退出聊天室',
'bye' => '再见%s, 欢迎你再此访问!',
'colourtable' => '颜色表',
'backtoprofile' => '回到你的个人资料',
'copy' => '验证码:',
'choosecol' => '客人,选择一种颜色:',
'randomcol' => '随机颜色',
'enter' => '回车',
'error' => '错误',
'members' => '会员',
'guests' => '游客',
'approveguests' => '%d新客人批准',
'allowchecked' => '允许检查',
'allowall' => '允许全部',
'denychecked' => '拒绝检查',
'denyall' => '全部拒绝',
'denymessage' => '发送消息给拒绝:',
'butallowdeny' => '提交',
'waitempty' => '不再需要批准入场申请.',
'wrongcaptcha' => '错误验证码',
'captchaexpire' => '验证码已经使用或超时.',
'noguests' => '对不起,目前仅限会员!',
'curchat' => '目前%d人在房间里聊天:',
'cantreg' => '无法注册%s',
'alreadyreged' => '%s已经注册',
'successreg' => '%s成功注册.',
'cantchgstat' => '无法改变状态%s',
'succdel' => '%s已成功从数据库中删除.',
'succchg' => '%s的状态已更改.',
'wrongpass' => '密码错误!',
'wrongglobalpass' => '错误的全球密码!',
'succprofile' => '您的个人资料已成功保存.',
'backtologin' => '返回登录页面.',
'backtochat' => '回到聊天室.',
'Beige' => '米色',
'Black' => '黑色',
'Blue' => '蓝色',
'BlueViolet' => '紫罗兰色',
'Brown' => '棕色',
'Cyan' => '青色',
'DarkBlue' => '深蓝',
'DarkGreen' => '深绿色',
'DarkRed' => '深红',
'DarkViolet' => '深紫罗兰',
'DeepSkyBlue' => '天蓝色',
'Gold' => '',
'Grey' => '灰色',
'Green' => '绿色',
'HotPink' => '亮粉色',
'Indigo' => '靛青',
'LightBlue' => '浅蓝',
'LightGreen' => '浅绿色',
'LimeGreen' => '柠檬绿',
'Magenta' => '品红',
'Olive' => '橄榄',
'Orange' => '橙子',
'OrangeRed' => '橙红色',
'Purple' => '紫色',
'Red' => '红色',
'RoyalBlue' => '宝蓝色',
'SeaGreen' => '海绿色',
'Sienna' => '黄土',
'Silver' => '银色',
'Tan' => '黄褐色',
'Teal' => '蓝绿色',
'Violet' => '紫色',
'White' => '白色',
'Yellow' => '黄色',
'YellowGreen' => '黄绿色',
'redirectto' => '重定向到:',
'nonhttp' => '请求非http链接:',
'httpredir' => '如果它不起作用,试试这个:',
'actions' => '操作',
'sesip' => 'IP地址',
'css' => 'CSS风格',
'memberexpire' => '会员超时(分钟)',
'guestexpire' => '访客超时(分钟)',
'kickpenalty' => '踢罚(分钟)',
'entrywait' => '等候室时间(秒)',
'captchatime' => '验证码超时(秒)',
'messageexpire' => '消息超时(分钟)',
'messagelimit' => '消息限制(公开)',
'maxmessage' => '最大消息长度',
'confirm' => '你确定吗?',
'yes' => '',
'no' => '',
'colbg' => '背景色',
'coltxt' => '文字颜色',
'maxname' => '最大昵称长度',
'minpass' => '最小密码长度',
'defaultrefresh' => '默认消息重新加载时间(秒)',
'suguests' => '启用申请人',
'rulestxt' => '规则(html',
'imgembed' => '嵌入图像',
'trackip' => '显示会话-IP',
'captchachars' => '验证码中使用的字符',
'memkick' => '如果没有主持人,会员可以踢',
'forceredirect' => '强制重定向',
'redirect' => '自定义重定向脚本',
'backuprestore' => '备份还原',
'backup' => '备用',
'restore' => '恢复',
'settings' => '设置',
'linkfilter' => '链接过滤器',
'chatname' => '聊天名称',
'destroy' => '摧毁聊天',
'destroyed' => '成功破坏了聊天',
'topic' => '话题',
'passreset' => '重设密码',
'cantresetpass' => '无法重置密码',
'succpassreset' => '成功重置密码',
'entermsg' => '%s进入聊天室.',
'exitmsg' => '%s离开了聊天室',
'memregmsg' => '%s现在是注册会员.',
'suregmsg' => '%s现在是注册申请人.',
'kickmsg' => '%s被踢了.',
'multikickmsg' => '%s被踢了.',
'allkickmsg' => '所有客人都被踢了.',
'cleanmsg' => '%s已经清理干净了.',
'sendallmsg' => '%s - ',
'sendmemmsg' => '[M] %s - ',
'sendmodmsg' => '[Staff] %s - ',
'sendadmmsg' => '[Admin] %s - ',
'sendprvmsg' => '[%1$s to %2$s] - ',
'msgsendall' => 'Message to all',
'msgsendmem' => 'Message to members only',
'msgsendmod' => 'Message to staff only',
'msgsendadm' => 'Message to admins only',
'msgsendprv' => 'Private message',
'numnotes' => 'Number of notes revisions to keep',
'revisions' => 'Revisions:',
'older' => 'Older',
'newer' => 'Newer',
'accessdenied' => 'Access denied',
'loggedinas' => 'You are logged in as %s and don\'t have access to this section.',
'newnickname' => 'New nickname:',
'nicknametaken' => 'Nickname is already taken',
'nopass' => 'Invalid password (At least %d characters), not changing nickname',
'gdextrequired' => 'The gd extension of PHP is required for this feature. Please install it first.',
'memcachedextrequired' => 'The memcached extension of PHP is required for the caching feature. Please install it first or set the memcached setting back to false.',
'opensslextrequired' => 'The openssl extension of PHP is required for the encryption feature. Please install it first or set the encrypted setting back to false.',
'pdo_mysqlextrequired' => 'The pdo_mysql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_pgsqlextrequired' => 'The pdo_pgsql extension of PHP is required for the selected database driver. Please install it first.',
'pdo_sqliteextrequired' => 'The pdo_sqlite extension of PHP is required for the selected database driver. Please install it first.',
'jsonextrequired' => 'The json extension of PHP is required for this feature. Please install it first.',
'sendmail' => 'Send mail on new public message',
'mailsender' => 'Send mail using this address',
'mailreceiver' => 'Send mail to this address',
'modfallback' => 'Fallback to waiting room, if no moderator is present to approve guests',
'regpass' => 'Repeat password<br>to register',
'guestreg' => 'Let guests register themselves',
'asmember' => 'As member',
'assuguest' => 'As applicant',
'fatalerror' => 'Fatal error',
'prevmatch' => 'Your match was as follows',
'matchtoolong' => 'Your match was too long. You can use max. 255 characters. Try splitting it up.',
'nocache' => 'Autoscroll (for old browsers or top-to-bottom sort).',
'disablepm' => 'Disable private messages',
'disablechat' => 'Disable chat',
'disabletext' => 'Chat disabled message (html)',
'disabledtext' => 'Temporarily disabled',
'defaulttz' => 'Default time zone',
'tz' => 'Time zone',
'optional' => '(optional)',
'userloggedin' => 'A user with this nickname is already logged in.',
'regednick' => 'This nickname is a registered member.',
'eninbox' => 'Enable offline inbox',
'inboxmsgs' => 'Read %d messages in your inbox',
'offline' => '(offline)',
'deleteacc' => 'Delete account',
'eninnone' => 'For no one',
'eninall' => 'For everyone',
'eninmem' => 'For members only',
'eninstaff' => 'For staff only',
'eninadmin' => 'For admins only',
'nickregex' => 'Nickname regex',
'passregex' => 'Password regex',
'externalcss' => 'Link to external CSS file',
'greetingmsg' => 'Welcome %s!',
'msgsendall' => '给所有人的信息',
'msgsendmem' => '仅向会员发送消息',
'msgsendmod' => '仅向员工发送消息',
'msgsendadm' => '仅向管理员发送消息',
'msgsendprv' => '私人信息',
'numnotes' => '要保留的备注数量',
'revisions' => '修订:',
'older' => '旧的',
'newer' => '较新',
'accessdenied' => '拒绝访问',
'loggedinas' => '您以%s身份登录无法访问此部分',
'newnickname' => '新昵称:',
'nicknametaken' => '昵称已被取消',
'nopass' => '密码无效(至少%d个字符不更改昵称.',
'gdextrequired' => '此功能需要PHP的gd扩展名。 请先安装它。.',
'memcachedextrequired' => '缓存功能需要PHP的memcached扩展。 请先安装它或将memcached设置恢复为false.',
'sodiumextrequired' => '加密功能需要PHP的libsodium扩展。 请先安装它或将加密设置恢复为false.',
'pdo_mysqlextrequired' => '所选数据库驱动程序需要PHP的pdo_mysql扩展名。 请先安装它.',
'pdo_pgsqlextrequired' => '所选数据库驱动程序需要PHP的pdo_pgsql扩展名。 请先安装它。',
'pdo_sqliteextrequired' => '所选数据库驱动程序需要PHP的pdo_sqlite扩展。 请先安装它.',
'jsonextrequired' => '此功能需要PHP的json扩展名。 请先安装它.',
'sendmail' => '发送新公共邮件的邮件',
'mailsender' => '使用此地址发送邮件',
'mailreceiver' => '发送邮件到这个地址',
'modfallback' => '如果没有主持人来批准客人,请回到候诊室',
'regpass' => '重复密码<br>注册',
'guestreg' => '让客人自己注册',
'asmember' => '作为会员',
'assuguest' => '作为申请人',
'fatalerror' => '致命错误',
'prevmatch' => '你的申请如下',
'matchtoolong' => '你的申请太长了。 你可以用max。 255个字符。 尝试拆分它.',
'nocache' => '自动滚动(适用于旧浏览器或从上到下排序).',
'disablepm' => '禁用私人消息',
'disablechat' => '禁用聊天',
'disabletext' => '聊天禁用消息(html',
'disabledtext' => '暂时禁用',
'defaulttz' => '默认时区',
'tz' => '时区',
'optional' => '(可选的)',
'userloggedin' => '具有此昵称的用户已登录.',
'regednick' => '这个昵称是注册会员.',
'eninbox' => '启用离线收件箱',
'inboxmsgs' => '阅读收件箱中的%d条消息',
'offline' => '(离线)',
'deleteacc' => '删除帐户',
'eninnone' => '一个人',
'eninall' => '所以人',
'eninmem' => '仅限会员',
'eninstaff' => '仅限员工',
'eninadmin' => '仅适用于管理员',
'nickregex' => '昵称正则表达式',
'passregex' => '密码正则表达式',
'externalcss' => '链接到外部CSS文件',
'greetingmsg' => '欢迎%s!',
'entryhelp' => 'If this frame does not reload in %d seconds, you\'ll have to enable automatic redirection (meta refresh) in your browser. Also make sure no web filter, local proxy tool or browser plugin is preventing automatic refreshing! This could be for example "Polipo", "NoScript", etc.<br>As a workaround (or in case of server/proxy reload errors) you can always use the buttons at the bottom to refresh manually.',
'enablegreeting' => 'Show a greeting message before showing the messages',
'unban' => 'Unban',
'sortupdown' => 'Sort messages from top to bottom',
'sortframe' => 'Rearrange',
'cs' => 'Case sensitive',
'hidechatters' => 'Hide list of chatters',
'enfileupload' => 'Enable file uploads',
'msgattache' => 'Attachement',
'filenotfound' => 'File not found!',
'maxuploadsize' => 'Maximum upload size in KB',
'enablegreeting' => '在显示消息之前显示问候消息',
'unban' => '取消禁止',
'sortupdown' => '从上到下对消息进行排序',
'sortframe' => '改变方向',
'cs' => '大小写',
'hidechatters' => '隐藏聊天列表',
'enfileupload' => '启用文件上载',
'msgattache' => '附件',
'filenotfound' => '找不到文件!',
'maxuploadsize' => '最大上载大小(KB',
'maxsize' => 'Max %d KB',
'cssupdate' => 'Note: Default CSS is now hardcoded and can be removed from the CSS setting',
'cssupdate' => '注意默认的CSS现在是硬编码的可以从CSS设置中删除。',
];