Project added
57
README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# AnonIB 3D by Alex Krunch
|
||||

|
||||
This project is a prototype for a 3D anonymous imageboard. The goal is to use the video game structure an abstraction layer to minimize censorship. Full project running here: https://3dchan.net
|
||||
|
||||
## Software
|
||||
The project use Angular >6 and PHP > 5. It also use the libraries BabylonJS for the 3D and LazerDB for JSON database.
|
||||
[BabylonJS](https://github.com/BabylonJS/Babylon.js/tree/master/dist)
|
||||
[LazerDB](https://github.com/Greg0/Lazer-Database)
|
||||
|
||||
## Installation
|
||||
**1/ Drag and drop the content at the _/ready2use/_ at the root of your server.**
|
||||
If you want to add AnonIB 3D to a subfolder, you will need to recompile the Angular project using this build command:
|
||||
```bash
|
||||
ng build --prod --base-href=/path-to-subfolder/
|
||||
```
|
||||
|
||||
Add this .htaccess, modify _path-to-sub-folder_, and place it at the root of your sub-folder.
|
||||
```bash
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -l [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^.*$ - [NC,L]
|
||||
RewriteRule ^(srv|user)($|/) - [L]
|
||||
RewriteRule ^(.*) /path-to-sub-folder/index.html [NC,L]
|
||||
```
|
||||
Don't forget to add the content of _/src_php/_ in _/path-to-sub-folder/srv/_
|
||||
|
||||
|
||||
**2/ Add you own custom map list**
|
||||
Go to _/php/MapController.php_ and add and suppress a new line. Use only characters allowed in Url for the board name.
|
||||
```bash
|
||||
array_push($levelToPlace, new Level("newmap", 15, 13, true, true) );
|
||||
```
|
||||
|
||||
**3/Initialize the admin password + the DB**
|
||||
Go to _/srv/php/admin.php_
|
||||
Type the you password in the field
|
||||
Click on Set password
|
||||
To re-init the password go to _/php/password/password.txt_ and erase the file
|
||||
After this erase database + posts and maps if they already exist and click Init the database + Init Map and Posts
|
||||
|
||||
**4/Access to the admin**
|
||||
Go to _/admin_ , type your password and click on New user or Existing user.
|
||||
You know have access to the admin. Click on the Launch the Admin.
|
||||
Posts is to review , delete or ban user.
|
||||
Map is to change map. At the top you got a selector to choose the chan of the map, and at the bottom you got a selector for the type of tile you want to use.
|
||||
|
||||
## Project status
|
||||
I paused the project due to my personal situation. There all you need in the code to activate the image upload, but security flows in it are highly probable.
|
||||
|
||||
## Support
|
||||
For any question or problem contact me by mail (monsieur.krunch@gmail.com) or on Twitter (https://twitter.com/alexkrunch)
|
||||
|
||||
|
||||
## License
|
||||
[MIT](https://choosealicense.com/licenses/mit/)
|
58
ready2use/assets/amaz/amaz.json
Normal file
@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"url":"https://amzn.to/2VUOerv",
|
||||
"picture":"https://i.pinimg.com/originals/6b/7c/fa/6b7cfa7ca8acb25025f5bf7ea0056e92.jpg",
|
||||
"name":"Reçois le livre le très bon \"Sonny 60 years Hells Angels \" chez toi demain!",
|
||||
"desc":"Un super bouquins d'illustration sur les hells angels des années 60!",
|
||||
"chan": "alpha",
|
||||
"loc": "fr"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2YSwn6B",
|
||||
"picture":"./assets/amaz/come_get_it.jpg",
|
||||
"name":"Get this book \"Come and Take It \" by the guy who 3D printed a 🔫, Cody Wilson!",
|
||||
"desc":"Come and Take It",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2K9wu9U",
|
||||
"picture":"https://images-na.ssl-images-amazon.com/images/I/41qdCTNSp8L._SX330_BO1,204,203,200_.jpg",
|
||||
"name":"Get this book \"Radicals \" on crypto anarchism at home tomorow!",
|
||||
"desc":"An awesome book on crypto anarchism",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2EAtkZg",
|
||||
"picture":"./assets/amaz/dark_net.webp",
|
||||
"name":"Get the only good book on the \"Dark Net\" exploring the topic in depth.",
|
||||
"desc":"An awesome book on crypto anarchism",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2QsNIAf",
|
||||
"picture":"./assets/amaz/joker_leto.jpg",
|
||||
"name":"🤡 to LIVE IN A SOCIETY, get this. At your home tomorrow",
|
||||
"desc":"Jared Leto's joker",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2W9L2NZ",
|
||||
"picture":"https://images-na.ssl-images-amazon.com/images/I/61znu9JU9IL._UY445_.jpg",
|
||||
"name":"No GF? Become the GF with this sailor uniform! Get it Tomorow!",
|
||||
"desc":"A very sailor uniform cosplay.",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
},
|
||||
{
|
||||
"url":"https://amzn.to/2QAxzJ7",
|
||||
"picture":"./assets/amaz/joker_nolan.jpg",
|
||||
"name":"🤡 13% of the population but 53% of the crime. By Nendoroid",
|
||||
"desc":"Christopher Nolan's joker",
|
||||
"chan": "alpha",
|
||||
"loc": "us"
|
||||
}
|
||||
]
|
BIN
ready2use/assets/amaz/come_get_it.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
ready2use/assets/amaz/dark_net.webp
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
ready2use/assets/amaz/joker_leto.jpg
Normal file
After Width: | Height: | Size: 181 KiB |
BIN
ready2use/assets/amaz/joker_nolan.jpg
Normal file
After Width: | Height: | Size: 126 KiB |
BIN
ready2use/assets/img/bg_radi_red.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
ready2use/assets/img/bg_radi_red_dark.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
ready2use/assets/img/grid.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
ready2use/assets/img/home_bg.jpeg
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
ready2use/assets/img/home_bg_dark.png
Normal file
After Width: | Height: | Size: 427 KiB |
BIN
ready2use/assets/img/home_bg_dark_lite.png
Normal file
After Width: | Height: | Size: 923 KiB |
BIN
ready2use/assets/img/preview.jpeg
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
ready2use/assets/img/tool_bar_bg.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
139
ready2use/assets/map/alpha.json
Normal file
@ -0,0 +1,139 @@
|
||||
{ "height":14,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 193, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 193, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 194, 1, 1, 221, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
"height":14,
|
||||
"name":"decors1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[
|
||||
{
|
||||
"height":32,
|
||||
"id":1,
|
||||
"name":"playerstart",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":189,
|
||||
"y":144
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":2,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":129,
|
||||
"y":354
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":3,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":384,
|
||||
"y":160
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":4,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":417,
|
||||
"y":160
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[
|
||||
{
|
||||
"height":19,
|
||||
"id":7,
|
||||
"name":"dick",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":21,
|
||||
"x":197,
|
||||
"y":361
|
||||
},
|
||||
{
|
||||
"height":19,
|
||||
"id":8,
|
||||
"name":"sunglasses",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":326,
|
||||
"y":199
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":14,
|
||||
"name":"gates",
|
||||
"objects":[
|
||||
{
|
||||
"height":27,
|
||||
"id":9,
|
||||
"name":"level2",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":30,
|
||||
"x":47,
|
||||
"y":9
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":12,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":18
|
||||
}
|
94
ready2use/assets/map/level2.json
Normal file
@ -0,0 +1,94 @@
|
||||
{ "height":30,
|
||||
"layers":[
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 1, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 221, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
"height":30,
|
||||
"name":"decors1",
|
||||
"opacity":0.300000011920929,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":30,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0],
|
||||
"height":30,
|
||||
"name":"decors2",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":30,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[
|
||||
{
|
||||
"height":32,
|
||||
"id":1,
|
||||
"name":"playerstart",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":398,
|
||||
"y":80
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":2,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":352,
|
||||
"y":670
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":9,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":355,
|
||||
"y":607
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":10,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":30
|
||||
}
|
128
ready2use/assets/map/room1.json
Normal file
@ -0,0 +1,128 @@
|
||||
{ "height":14,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 193, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 193, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 194, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
"height":14,
|
||||
"name":"decors1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[
|
||||
{
|
||||
"height":32,
|
||||
"id":1,
|
||||
"name":"playerstart",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":189,
|
||||
"y":144
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":3,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":384,
|
||||
"y":160
|
||||
},
|
||||
{
|
||||
"height":32,
|
||||
"id":4,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":417,
|
||||
"y":160
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"gates",
|
||||
"objects":[
|
||||
{
|
||||
"height":19,
|
||||
"id":9,
|
||||
"name":"room5",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":20,
|
||||
"x":54,
|
||||
"y":56
|
||||
},
|
||||
{
|
||||
"height":18.5,
|
||||
"id":12,
|
||||
"name":"room2",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":19,
|
||||
"x":55,
|
||||
"y":374
|
||||
},
|
||||
{
|
||||
"height":20.5,
|
||||
"id":13,
|
||||
"name":"room3",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":21,
|
||||
"x":325,
|
||||
"y":196.5
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":17,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":18
|
||||
}
|
106
ready2use/assets/map/room2.json
Normal file
@ -0,0 +1,106 @@
|
||||
{ "height":14,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 66, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 66, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 66, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 194, 2, 2, 66, 66, 66, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 2, 66, 66, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 66, 1, 66, 66, 66, 66, 66, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
"height":14,
|
||||
"name":"decors1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[
|
||||
{
|
||||
"height":22,
|
||||
"id":17,
|
||||
"name":"anon",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":21,
|
||||
"x":279,
|
||||
"y":180
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[
|
||||
{
|
||||
"height":20,
|
||||
"id":18,
|
||||
"name":"Upload Ring",
|
||||
"rotation":0,
|
||||
"type":"ring",
|
||||
"visible":true,
|
||||
"width":21,
|
||||
"x":280,
|
||||
"y":218
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"gates",
|
||||
"objects":[
|
||||
{
|
||||
"height":19,
|
||||
"id":9,
|
||||
"name":"room1",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":23,
|
||||
"x":53,
|
||||
"y":57
|
||||
},
|
||||
{
|
||||
"height":15.5,
|
||||
"id":13,
|
||||
"name":"room3",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":19,
|
||||
"x":501,
|
||||
"y":55.5
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":19,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":18
|
||||
}
|
95
ready2use/assets/map/room3.json
Normal file
@ -0,0 +1,95 @@
|
||||
{ "height":14,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 41, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0],
|
||||
"height":14,
|
||||
"name":"decors1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"gates",
|
||||
"objects":[
|
||||
{
|
||||
"height":18,
|
||||
"id":9,
|
||||
"name":"room1",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":21,
|
||||
"x":42,
|
||||
"y":261
|
||||
},
|
||||
{
|
||||
"height":19.5,
|
||||
"id":13,
|
||||
"name":"room2",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":19,
|
||||
"x":390,
|
||||
"y":382
|
||||
},
|
||||
{
|
||||
"height":19.5,
|
||||
"id":17,
|
||||
"name":"room5",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":20,
|
||||
"x":385,
|
||||
"y":116.5
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":19,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":18
|
||||
}
|
84
ready2use/assets/map/room5.json
Normal file
@ -0,0 +1,84 @@
|
||||
{ "height":14,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 2, 1, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 2, 2, 41, 2, 2, 0, 2, 1, 1, 1, 1, 2, 194, 2, 1, 1, 2, 0, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2],
|
||||
"height":14,
|
||||
"name":"decors1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":18,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"characters",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"objects",
|
||||
"objects":[],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"draworder":"topdown",
|
||||
"height":0,
|
||||
"name":"gates",
|
||||
"objects":[
|
||||
{
|
||||
"height":19,
|
||||
"id":9,
|
||||
"name":"room1",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":20,
|
||||
"x":54,
|
||||
"y":373
|
||||
},
|
||||
{
|
||||
"height":17.5,
|
||||
"id":13,
|
||||
"name":"room3",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":20,
|
||||
"x":482,
|
||||
"y":361
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextobjectid":19,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"left-down",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"..\/..\/..\/tilemap\/tile-set-dungeon.tsx"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"version":1,
|
||||
"width":18
|
||||
}
|
BIN
ready2use/assets/textures/404.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
ready2use/assets/textures/anon_sprite.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
ready2use/assets/textures/anon_sprite_dead.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
ready2use/assets/textures/cardboard_text.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ready2use/assets/textures/concrete_text.jpg
Normal file
After Width: | Height: | Size: 258 KiB |
BIN
ready2use/assets/textures/floor_dalle_text.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
ready2use/assets/textures/grass_text.jpg
Normal file
After Width: | Height: | Size: 372 KiB |
BIN
ready2use/assets/textures/panel_donations_text.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
ready2use/assets/textures/panel_thanks_text.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
ready2use/assets/textures/prota_avatar.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
ready2use/assets/textures/skybox2_nx.jpg
Normal file
After Width: | Height: | Size: 390 KiB |
BIN
ready2use/assets/textures/skybox2_ny.jpg
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
ready2use/assets/textures/skybox2_nz.jpg
Normal file
After Width: | Height: | Size: 420 KiB |
BIN
ready2use/assets/textures/skybox2_px.jpg
Normal file
After Width: | Height: | Size: 408 KiB |
BIN
ready2use/assets/textures/skybox2_py.jpg
Normal file
After Width: | Height: | Size: 432 KiB |
BIN
ready2use/assets/textures/skybox2_pz.jpg
Normal file
After Width: | Height: | Size: 379 KiB |
BIN
ready2use/assets/textures/skybox_nx.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
ready2use/assets/textures/skybox_ny.jpg
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
ready2use/assets/textures/skybox_nz.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
ready2use/assets/textures/skybox_px.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
ready2use/assets/textures/skybox_py.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
ready2use/assets/textures/skybox_pz.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
ready2use/assets/textures/volcanic_text.jpg
Normal file
After Width: | Height: | Size: 283 KiB |
BIN
ready2use/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
24
ready2use/index.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta property="og:image" content="http://snuffchan.com/dungeon/assets/img/preview.jpeg">
|
||||
<title>AnonIB💀3D</title>
|
||||
<meta name="description" content="Snuffchan is the very first anonymous imageboard sharing video game, in 3D, fully running in the web browser, and this without any form of subricption.">
|
||||
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="wrapper">
|
||||
<main>
|
||||
<app-root></app-root>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
|
||||
</html>
|
5369
ready2use/main.js
Normal file
1
ready2use/main.js.map
Normal file
5781
ready2use/polyfills.js
Normal file
1
ready2use/polyfills.js.map
Normal file
154
ready2use/runtime.js
Normal file
@ -0,0 +1,154 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ function webpackJsonpCallback(data) {
|
||||
/******/ var chunkIds = data[0];
|
||||
/******/ var moreModules = data[1];
|
||||
/******/ var executeModules = data[2];
|
||||
/******/
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||
/******/
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // add entry modules from loaded chunk to deferred list
|
||||
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
|
||||
/******/
|
||||
/******/ // run deferred modules when all chunks ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ };
|
||||
/******/ function checkDeferredModules() {
|
||||
/******/ var result;
|
||||
/******/ for(var i = 0; i < deferredModules.length; i++) {
|
||||
/******/ var deferredModule = deferredModules[i];
|
||||
/******/ var fulfilled = true;
|
||||
/******/ for(var j = 1; j < deferredModule.length; j++) {
|
||||
/******/ var depId = deferredModule[j];
|
||||
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
|
||||
/******/ }
|
||||
/******/ if(fulfilled) {
|
||||
/******/ deferredModules.splice(i--, 1);
|
||||
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ return result;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ "runtime": 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ var deferredModules = [];
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||
/******/ jsonpArray = jsonpArray.slice();
|
||||
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||
/******/
|
||||
/******/
|
||||
/******/ // run deferred modules from other chunks
|
||||
/******/ checkDeferredModules();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([]);
|
||||
//# sourceMappingURL=runtime.js.map
|
1
ready2use/runtime.js.map
Normal file
60
ready2use/srv/css/style.css
Normal file
@ -0,0 +1,60 @@
|
||||
.post-ui-message{
|
||||
padding : 10px;
|
||||
margin-bottom : 18px;
|
||||
background: rgb(189, 198, 247);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #a99ec7;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
div {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ascii{
|
||||
display: inline-block;
|
||||
font-family: "Lucida Console", Monaco, monospace;
|
||||
}
|
||||
|
||||
textarea
|
||||
{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post-message {
|
||||
padding : 10px;
|
||||
margin-bottom : 18px;
|
||||
background: rgb(228, 221, 221);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: rgb(131, 123, 123);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.post-torrent-info{
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: small;
|
||||
padding : 8px;
|
||||
color: white;
|
||||
background:rgb(70, 61, 56);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.post-message img {
|
||||
max-width: 650px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.post-message video {
|
||||
max-width: 650px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.post-message audio {
|
||||
max-width: 650px;
|
||||
width: 100%;
|
||||
}
|
6
ready2use/srv/img/.htaccess
Executable file
@ -0,0 +1,6 @@
|
||||
Options +FollowSymlinks
|
||||
RewriteEngine on
|
||||
RewriteRule ^([a-z0-9-_]+).jpeg ?name=$1.jpeg
|
||||
RewriteRule ^([a-z0-9-_]+).jpg ?name=$1.jpg
|
||||
RewriteRule ^([a-z0-9-_]+).gif ?name=$1.gif
|
||||
RewriteRule ^([a-z0-9-_]+).png ?name=$1.png
|
BIN
ready2use/srv/img/breadchan_preview.png
Normal file
After Width: | Height: | Size: 31 KiB |
29
ready2use/srv/img/index.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
//Load the DB
|
||||
require_once "../php/Utils/Constants.php";
|
||||
$uploaddir = '../php/'.Constants::CONST_IMAGE_UPLOAD_FOLDER.'/';
|
||||
|
||||
use Lazer\Classes\Database as Lazer;
|
||||
define('LAZER_DATA_PATH', '../php/'.realpath(dirname(__FILE__)).'/'.Constants::CONST_DB_FOLDER.'/');
|
||||
|
||||
$name = $_GET['name']; // Assuming the file name is in the URL for this example
|
||||
|
||||
$parsed = explode("_",$name);
|
||||
if(count($parsed) != 2) return;
|
||||
|
||||
$mapKey = $parsed[0].'/';
|
||||
$name = $parsed[1];
|
||||
|
||||
$ext = pathinfo($name)['extension'];
|
||||
$mimeType = 'image/'.$ext;
|
||||
|
||||
|
||||
$handle = fopen($uploaddir.$mapKey.$name , "rb");
|
||||
$contents = fread($handle, filesize($uploaddir.$mapKey.$name ));
|
||||
fclose($handle);
|
||||
|
||||
header("content-type: image/".$ext);
|
||||
echo $contents;
|
||||
|
||||
?>
|
30
ready2use/srv/index.html
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title>AnonIB-3D Server</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!--meta property="og:image" content="img/breadchan_preview.png">
|
||||
<meta property="og:description" content="The bittorrent imageboard. Powered by Webtorrent.io"-->
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="css/style.css" >
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!--img src="peerchan_tilte.png"-->
|
||||
<div class="container">
|
||||
|
||||
<div class="py-5 text-center">
|
||||
<h1 class="title">Welcome on AnonIB-3D server-side!</h1>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
1
ready2use/srv/libs/blob-util@latest.js
Normal file
@ -0,0 +1 @@
|
||||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.blobUtil=e()}}(function(){return function e(r,n,t){function o(u,f){if(!n[u]){if(!r[u]){var a="function"==typeof require&&require;if(!f&&a)return a(u,!0);if(i)return i(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var d=n[u]={exports:{}};r[u][0].call(d.exports,function(e){var n=r[u][1][e];return o(n?n:e)},d,d.exports,e,r,n,t)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u<t.length;u++)o(t[u]);return o}({1:[function(e,r,n){"use strict";function t(e,r){return new Promise(function(n,t){var o=new Image;r&&(o.crossOrigin=r),o.onload=function(){n(o)},o.onerror=t,o.src=e})}function o(e){var r=document.createElement("canvas");r.width=e.width,r.height=e.height;var n=r.getContext("2d");return n.drawImage(e,0,0,e.width,e.height,0,0,e.width,e.height),r}function i(e,r){e=e||[],r=r||{},"string"==typeof r&&(r={type:r});try{return new Blob(e,r)}catch(i){if("TypeError"!==i.name)throw i;for(var n="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,t=new n,o=0;o<e.length;o+=1)t.append(e[o]);return t.getBlob(r.type)}}function u(e){return("undefined"!=typeof URL?URL:webkitURL).createObjectURL(e)}function f(e){return("undefined"!=typeof URL?URL:webkitURL).revokeObjectURL(e)}function a(e){return new Promise(function(r,n){var t=new FileReader,o="function"==typeof t.readAsBinaryString;t.onloadend=function(){var e=t.result||"";return o?r(e):void r(w(e))},t.onerror=n,o?t.readAsBinaryString(e):t.readAsArrayBuffer(e)})}function c(e,r){var n=[v(atob(e))];return r?i(n,{type:r}):i(n)}function d(e,r){return c(btoa(e),r)}function l(e){return a(e).then(btoa)}function b(e){var r=e.match(/data:([^;]+)/)[1],n=e.replace(/^[^,]+,/,""),t=v(atob(n));return i([t],{type:r})}function y(e){return l(e).then(function(r){return"data:"+e.type+";base64,"+r})}function B(e,r,n,i){return r=r||"image/png",t(e,n).then(o).then(function(e){return e.toDataURL(r,i)})}function s(e,r,n){return"function"==typeof e.toBlob?new Promise(function(t){e.toBlob(t,r,n)}):Promise.resolve(b(e.toDataURL(r,n)))}function p(e,r,n,i){return r=r||"image/png",t(e,n).then(o).then(function(e){return s(e,r,i)})}function g(e,r){return i([e],r)}function h(e){return new Promise(function(r,n){var t=new FileReader;t.onloadend=function(){var e=t.result||new ArrayBuffer(0);r(e)},t.onerror=n,t.readAsArrayBuffer(e)})}function w(e){for(var r="",n=new Uint8Array(e),t=n.byteLength,o=-1;++o<t;)r+=String.fromCharCode(n[o]);return r}function v(e){for(var r=e.length,n=new ArrayBuffer(r),t=new Uint8Array(n),o=-1;++o<r;)t[o]=e.charCodeAt(o);return n}Object.defineProperty(n,"__esModule",{value:!0}),n.createBlob=i,n.createObjectURL=u,n.revokeObjectURL=f,n.blobToBinaryString=a,n.base64StringToBlob=c,n.binaryStringToBlob=d,n.blobToBase64String=l,n.dataURLToBlob=b,n.blobToDataURL=y,n.imgSrcToDataURL=B,n.canvasToBlob=s,n.imgSrcToBlob=p,n.arrayBufferToBlob=g,n.blobToArrayBuffer=h,n.arrayBufferToBinaryString=w,n.binaryStringToArrayBuffer=v},{}]},{},[1])(1)});
|
1
ready2use/srv/libs/dragdrop.min.js
vendored
Normal file
913
ready2use/srv/libs/jquery.MultiFile.js
Executable file
@ -0,0 +1,913 @@
|
||||
/*
|
||||
### jQuery Multiple File Selection Plugin v2.2.2 - 2016-06-16 ###
|
||||
* Home: http://www.fyneworks.com/jquery/multifile/
|
||||
* Code: https://github.com/fyneworks/multifile
|
||||
*
|
||||
* Licensed under http://en.wikipedia.org/wiki/MIT_License
|
||||
*/
|
||||
/*# AVOID COLLISIONS #*/
|
||||
;
|
||||
if (window.jQuery)(function ($) {
|
||||
"use strict";
|
||||
/*# AVOID COLLISIONS #*/
|
||||
|
||||
// size label function (shows kb and mb where accordingly)
|
||||
function sl(x) {
|
||||
return x > 1048576 ? (x / 1048576).toFixed(1) + 'Mb' : (x==1024?'1Mb': (x / 1024).toFixed(1) + 'Kb' )
|
||||
};
|
||||
// utility function to return an array of
|
||||
function FILE_LIST(x){
|
||||
return ((x.files&&x.files.length) ? x.files : null) || [{
|
||||
name: x.value,
|
||||
size: 0,
|
||||
type: ((x.value || '').match(/[^\.]+$/i) || [''])[0]
|
||||
}];
|
||||
};
|
||||
|
||||
// plugin initialization
|
||||
$.fn.MultiFile = function (options) {
|
||||
if (this.length == 0) return this; // quick fail
|
||||
|
||||
// Handle API methods
|
||||
if (typeof arguments[0] == 'string') {
|
||||
// Perform API methods on individual elements
|
||||
if (this.length > 1) {
|
||||
var args = arguments;
|
||||
return this.each(function () {
|
||||
$.fn.MultiFile.apply($(this), args);
|
||||
});
|
||||
};
|
||||
// Invoke API method handler (and return whatever it wants to return)
|
||||
return $.fn.MultiFile[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
|
||||
};
|
||||
|
||||
// Accept number
|
||||
if (typeof options == 'number') {
|
||||
options = {max: options};
|
||||
};
|
||||
|
||||
// Initialize options for this call
|
||||
var options = $.extend({} /* new object */ ,
|
||||
$.fn.MultiFile.options /* default options */ ,
|
||||
options || {} /* just-in-time options */
|
||||
);
|
||||
|
||||
// Empty Element Fix!!!
|
||||
// this code will automatically intercept native form submissions
|
||||
// and disable empty file elements
|
||||
$('form')
|
||||
.not('MultiFile-intercepted')
|
||||
.addClass('MultiFile-intercepted')
|
||||
.submit($.fn.MultiFile.disableEmpty);
|
||||
|
||||
//### http://plugins.jquery.com/node/1363
|
||||
// utility method to integrate this plugin with others...
|
||||
if ($.fn.MultiFile.options.autoIntercept) {
|
||||
$.fn.MultiFile.intercept($.fn.MultiFile.options.autoIntercept /* array of methods to intercept */ );
|
||||
$.fn.MultiFile.options.autoIntercept = null; /* only run this once */
|
||||
};
|
||||
|
||||
// loop through each matched element
|
||||
this
|
||||
.not('.MultiFile-applied')
|
||||
.addClass('MultiFile-applied')
|
||||
.each(function () {
|
||||
//#####################################################################
|
||||
// MAIN PLUGIN FUNCTIONALITY - START
|
||||
//#####################################################################
|
||||
|
||||
// BUG 1251 FIX: http://plugins.jquery.com/project/comments/add/1251
|
||||
// variable group_count would repeat itself on multiple calls to the plugin.
|
||||
// this would cause a conflict with multiple elements
|
||||
// changes scope of variable to global so id will be unique over n calls
|
||||
window.MultiFile = (window.MultiFile || 0) + 1;
|
||||
var group_count = window.MultiFile;
|
||||
|
||||
// Copy parent attributes - Thanks to Jonas Wagner
|
||||
// we will use this one to create new input elements
|
||||
var MultiFile = {
|
||||
e: this,
|
||||
E: $(this),
|
||||
clone: $(this).clone()
|
||||
};
|
||||
|
||||
//===
|
||||
|
||||
//# USE CONFIGURATION
|
||||
var o = $.extend({},
|
||||
$.fn.MultiFile.options,
|
||||
options || {}, ($.metadata ? MultiFile.E.metadata() : ($.meta ? MultiFile.E.data() : null)) || {}, /* metadata options */ {} /* internals */
|
||||
);
|
||||
// limit number of files that can be selected?
|
||||
if (!(o.max > 0) /*IsNull(MultiFile.max)*/ ) {
|
||||
o.max = MultiFile.E.attr('maxlength');
|
||||
};
|
||||
if (!(o.max > 0) /*IsNull(MultiFile.max)*/ ) {
|
||||
o.max = (String(MultiFile.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
|
||||
if (!(o.max > 0)) o.max = -1;
|
||||
else o.max = String(o.max).match(/[0-9]+/gi)[0];
|
||||
};
|
||||
o.max = new Number(o.max);
|
||||
// limit extensions?
|
||||
o.accept = o.accept || MultiFile.E.attr('accept') || '';
|
||||
if (!o.accept) {
|
||||
o.accept = (MultiFile.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
|
||||
o.accept = new String(o.accept).replace(/^(accept|ext)\-/i, '');
|
||||
};
|
||||
// limit total pay load size
|
||||
o.maxsize = o.maxsize>0?o.maxsize:null || MultiFile.E.data('maxsize') || 0;
|
||||
if (!(o.maxsize > 0) /*IsNull(MultiFile.maxsize)*/ ) {
|
||||
o.maxsize = (String(MultiFile.e.className.match(/\b(maxsize|maxload|size)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
|
||||
if (!(o.maxsize > 0)) o.maxsize = -1;
|
||||
else o.maxsize = String(o.maxsize).match(/[0-9]+/gi)[0];
|
||||
};
|
||||
// limit individual file size
|
||||
o.maxfile = o.maxfile>0?o.maxfile:null || MultiFile.E.data('maxfile') || 0;
|
||||
if (!(o.maxfile > 0) /*IsNull(MultiFile.maxfile)*/ ) {
|
||||
o.maxfile = (String(MultiFile.e.className.match(/\b(maxfile|filemax)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
|
||||
if (!(o.maxfile > 0)) o.maxfile = -1;
|
||||
else o.maxfile = String(o.maxfile).match(/[0-9]+/gi)[0];
|
||||
};
|
||||
|
||||
//===
|
||||
|
||||
// size options are accepted in kylobytes, so multiple them by 1024
|
||||
if(o.maxfile>1) o.maxfile = o.maxfile * 1024;
|
||||
if(o.maxsize>1) o.maxsize = o.maxsize * 1024;
|
||||
|
||||
//===
|
||||
|
||||
// HTML5: enforce multiple selection to be enabled, except when explicitly disabled
|
||||
if (o.multiple !== false) {
|
||||
if (o.max > 1) MultiFile.E.attr('multiple', 'multiple').prop('multiple', true);
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
// APPLY CONFIGURATION
|
||||
$.extend(MultiFile, o || {});
|
||||
MultiFile.STRING = $.extend({}, $.fn.MultiFile.options.STRING, MultiFile.STRING);
|
||||
|
||||
//===
|
||||
|
||||
//#########################################
|
||||
// PRIVATE PROPERTIES/METHODS
|
||||
$.extend(MultiFile, {
|
||||
n: 0, // How many elements are currently selected?
|
||||
slaves: [],
|
||||
files: [],
|
||||
instanceKey: MultiFile.e.id || 'MultiFile' + String(group_count), // Instance Key?
|
||||
generateID: function (z) {
|
||||
return MultiFile.instanceKey + (z > 0 ? '_F' + String(z) : '');
|
||||
},
|
||||
trigger: function (event, element, MultiFile, files) {
|
||||
var rv, handler = MultiFile[event] || MultiFile['on'+event] ;
|
||||
if (handler){
|
||||
files = files || MultiFile.files || FILE_LIST(this);
|
||||
;
|
||||
$.each(files,function(i, file){
|
||||
// execute function in element's context, so 'this' variable is current element
|
||||
rv = handler.apply(MultiFile.wrapper, [element, file.name, MultiFile, file]);
|
||||
});
|
||||
return rv;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
//===
|
||||
|
||||
// Setup dynamic regular expression for extension validation
|
||||
// - thanks to John-Paul Bader: http://smyck.de/2006/08/11/javascript-dynamic-regular-expresions/
|
||||
if (String(MultiFile.accept).length > 1) {
|
||||
MultiFile.accept = MultiFile.accept.replace(/\W+/g, '|').replace(/^\W|\W$/g, '');
|
||||
MultiFile.rxAccept = new RegExp('\\.(' + (MultiFile.accept ? MultiFile.accept : '') + ')$', 'gi');
|
||||
};
|
||||
|
||||
//===
|
||||
|
||||
// Create wrapper to hold our file list
|
||||
MultiFile.wrapID = MultiFile.instanceKey;// + '_wrap'; // Wrapper ID?
|
||||
MultiFile.E.wrap('<div class="MultiFile-wrap" id="' + MultiFile.wrapID + '"></div>');
|
||||
MultiFile.wrapper = $('#' + MultiFile.wrapID + '');
|
||||
|
||||
//===
|
||||
|
||||
// MultiFile MUST have a name - default: file1[], file2[], file3[]
|
||||
MultiFile.e.name = MultiFile.e.name || 'file' + group_count + '[]';
|
||||
|
||||
//===
|
||||
|
||||
if (!MultiFile.list) {
|
||||
// Create a wrapper for the list
|
||||
// * OPERA BUG: NO_MODIFICATION_ALLOWED_ERR ('list' is a read-only property)
|
||||
// this change allows us to keep the files in the order they were selected
|
||||
MultiFile.wrapper.append('<div class="MultiFile-list" id="' + MultiFile.wrapID + '_list"></div>');
|
||||
MultiFile.list = $('#' + MultiFile.wrapID + '_list');
|
||||
};
|
||||
MultiFile.list = $(MultiFile.list);
|
||||
|
||||
//===
|
||||
|
||||
// Bind a new element
|
||||
MultiFile.addSlave = function (slave, slave_count) {
|
||||
//if(window.console) console.log('MultiFile.addSlave',slave_count);
|
||||
|
||||
// Keep track of how many elements have been displayed
|
||||
MultiFile.n++;
|
||||
// Add reference to master element
|
||||
slave.MultiFile = MultiFile;
|
||||
|
||||
// BUG FIX: http://plugins.jquery.com/node/1495
|
||||
// Clear identifying properties from clones
|
||||
slave.id = slave.name = '';
|
||||
|
||||
// Define element's ID and name (upload components need this!)
|
||||
//slave.id = slave.id || MultiFile.generateID(slave_count);
|
||||
slave.id = MultiFile.generateID(slave_count);
|
||||
//FIX for: http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=23
|
||||
//CHANGE v2.2.1 - change ID of all file elements, keep original ID in wrapper
|
||||
|
||||
// 2008-Apr-29: New customizable naming convention (see url below)
|
||||
// http://groups.google.com/group/jquery-dev/browse_frm/thread/765c73e41b34f924#
|
||||
slave.name = String(MultiFile.namePattern
|
||||
/*master name*/
|
||||
.replace(/\$name/gi, $(MultiFile.clone).attr('name'))
|
||||
/*master id */
|
||||
.replace(/\$id/gi, $(MultiFile.clone).attr('id'))
|
||||
/*group count*/
|
||||
.replace(/\$g/gi, group_count) //(group_count>0?group_count:''))
|
||||
/*slave count*/
|
||||
.replace(/\$i/gi, slave_count) //(slave_count>0?slave_count:''))
|
||||
);
|
||||
|
||||
// If we've reached maximum number, disable input slave
|
||||
var disable_slave;
|
||||
if ((MultiFile.max > 0) && ((MultiFile.files.length) > (MultiFile.max))) {
|
||||
slave.disabled = true;
|
||||
disable_slave = true;
|
||||
};
|
||||
|
||||
// Remember most recent slave
|
||||
MultiFile.current = slave;
|
||||
|
||||
// We'll use jQuery from now on
|
||||
slave = $(slave);
|
||||
|
||||
// Clear value
|
||||
slave.val('').attr('value', '')[0].value = '';
|
||||
|
||||
// Stop plugin initializing on slaves
|
||||
slave.addClass('MultiFile-applied');
|
||||
|
||||
// Triggered when a file is selected
|
||||
slave.change(function (a, b, c) {
|
||||
//if(window.console) console.log('MultiFile.slave.change',slave_count);
|
||||
//if(window.console) console.log('MultiFile.slave.change',this.files);
|
||||
|
||||
// Lose focus to stop IE7 firing onchange again
|
||||
$(this).blur();
|
||||
|
||||
//# NEW 2014-04-14 - accept multiple file selection, HTML5
|
||||
var e = this,
|
||||
prevs = MultiFile.files || [],
|
||||
files = this.files || [{
|
||||
name: this.value,
|
||||
size: 0,
|
||||
type: ((this.value || '').match(/[^\.]+$/i) || [''])[0]
|
||||
}],
|
||||
newfs = [],
|
||||
newfs_size = 0,
|
||||
total_size = MultiFile.total_size || 0/*,
|
||||
html5_multi_mode = this.files && $(this).attr('multiple')*/
|
||||
;
|
||||
|
||||
// recap
|
||||
//console.log('START '+ prevs.length + ' files @ '+ sl(total_size) +'.', prevs);
|
||||
|
||||
//# Retrive value of selected file from element
|
||||
var ERROR = []; //, v = String(this.value || '');
|
||||
|
||||
// make a normal array
|
||||
$.each(files, function (i, file) {
|
||||
newfs[newfs.length] = file;
|
||||
});
|
||||
|
||||
//# Trigger Event! onFileSelect
|
||||
MultiFile.trigger('FileSelect', this, MultiFile, newfs);
|
||||
//# End Event!
|
||||
|
||||
// validate individual files
|
||||
$.each(files, function (i, file) {
|
||||
|
||||
// pop local variables out of array/file object
|
||||
var v = file.name.replace(/^C:\\fakepath\\/gi,''),
|
||||
s = file.size,
|
||||
p = function(z){
|
||||
return z
|
||||
.replace('$ext', String(v.match(/[^\.]+$/i) || ''))
|
||||
.replace('$file', v.match(/[^\/\\]+$/gi))
|
||||
.replace('$size', sl(s) + ' > ' + sl(MultiFile.maxfile))
|
||||
}
|
||||
;
|
||||
|
||||
// check extension
|
||||
if (MultiFile.accept && v && !v.match(MultiFile.rxAccept)) {
|
||||
ERROR[ERROR.length] = p(MultiFile.STRING.denied);
|
||||
MultiFile.trigger('FileInvalid', this, MultiFile, [file]);
|
||||
};
|
||||
|
||||
// Disallow duplicates
|
||||
$(MultiFile.wrapper).find('input[type=file]').not(e).each(function(){
|
||||
// go through each file in each slave
|
||||
$.each(FILE_LIST(this), function (i, file) {
|
||||
if(file.name){
|
||||
//console.log('MultiFile.debug> Duplicate?', file.name, v);
|
||||
var x = (file.name || '').replace(/^C:\\fakepath\\/gi,'');
|
||||
if ( v == x || v == x.substr(x.length - v.length)) {
|
||||
ERROR[ERROR.length] = p(MultiFile.STRING.duplicate);
|
||||
MultiFile.trigger('FileDuplicate', e, MultiFile, [file]);
|
||||
};
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// limit the max size of individual files selected
|
||||
if (MultiFile.maxfile>0 && s>0 && s>MultiFile.maxfile) {
|
||||
ERROR[ERROR.length] = p(MultiFile.STRING.toobig);
|
||||
MultiFile.trigger('FileTooBig', this, MultiFile, [file]);
|
||||
};
|
||||
|
||||
// check extension
|
||||
var customError = MultiFile.trigger('FileValidate', this, MultiFile, [file]);
|
||||
if(customError && customError!=''){
|
||||
ERROR[ERROR.length] = p(customError);
|
||||
};
|
||||
|
||||
// add up size of files selected
|
||||
newfs_size += file.size;
|
||||
|
||||
});
|
||||
|
||||
// add up total for all files selected (existing and new)
|
||||
total_size += newfs_size;
|
||||
|
||||
// put some useful information in the file array
|
||||
newfs.size = newfs_size;
|
||||
newfs.total = total_size;
|
||||
newfs.total_length = newfs.length + prevs.length;
|
||||
|
||||
// limit the number of files selected
|
||||
if (MultiFile.max>0 && prevs.length + files.length > MultiFile.max) {
|
||||
ERROR[ERROR.length] = MultiFile.STRING.toomany.replace('$max', MultiFile.max);
|
||||
MultiFile.trigger('FileTooMany', this, MultiFile, newfs);
|
||||
};
|
||||
|
||||
// limit the max size of files selected
|
||||
if (MultiFile.maxsize > 0 && total_size > MultiFile.maxsize) {
|
||||
ERROR[ERROR.length] = MultiFile.STRING.toomuch.replace('$size', sl(total_size) + ' > ' + sl(MultiFile.maxsize));
|
||||
MultiFile.trigger('FileTooMuch', this, MultiFile, newfs);
|
||||
};
|
||||
|
||||
// Create a new file input element
|
||||
var newEle = $(MultiFile.clone).clone(); // Copy parent attributes - Thanks to Jonas Wagner
|
||||
//# Let's remember which input we've generated so
|
||||
// we can disable the empty ones before submission
|
||||
// See: http://plugins.jquery.com/node/1495
|
||||
newEle.addClass('MultiFile');
|
||||
|
||||
// Handle error
|
||||
if (ERROR.length > 0) {
|
||||
|
||||
// Handle error
|
||||
MultiFile.error(ERROR.join('\n\n'));
|
||||
|
||||
// 2007-06-24: BUG FIX - Thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com>
|
||||
// Ditch the trouble maker and add a fresh new element
|
||||
MultiFile.n--;
|
||||
MultiFile.addSlave(newEle[0], slave_count);
|
||||
slave.parent().prepend(newEle);
|
||||
slave.remove();
|
||||
return false;
|
||||
|
||||
}
|
||||
else { // if no errors have been found
|
||||
|
||||
// remember total size
|
||||
MultiFile.total_size = total_size;
|
||||
|
||||
// merge arrays
|
||||
files = prevs.concat(newfs);
|
||||
|
||||
// put some useful information in the file array
|
||||
files.size = total_size;
|
||||
files.size_label = sl(total_size);
|
||||
|
||||
// recap
|
||||
//console.log('NOW '+ files.length + ' files @ '+ sl(total_size) +'.', files);
|
||||
|
||||
// remember files
|
||||
MultiFile.files = files;
|
||||
|
||||
// Hide this element (NB: display:none is evil!)
|
||||
$(this).css({
|
||||
position: 'absolute',
|
||||
top: '-3000px'
|
||||
});
|
||||
|
||||
// Add new element to the form
|
||||
slave.after(newEle);
|
||||
|
||||
// Bind functionality
|
||||
MultiFile.addSlave(newEle[0], slave_count + 1);
|
||||
|
||||
// Update list
|
||||
MultiFile.addToList(this, slave_count, newfs);
|
||||
|
||||
//# Trigger Event! afterFileSelect
|
||||
MultiFile.trigger('afterFileSelect', this, MultiFile, newfs);
|
||||
//# End Event!
|
||||
|
||||
}; // no errors detected
|
||||
|
||||
}); // slave.change()
|
||||
|
||||
// point to wrapper
|
||||
$(slave).data('MultiFile-wrap', MultiFile.wrapper);
|
||||
|
||||
// store contorl's settings and file info in wrapper
|
||||
$(MultiFile.wrapper).data('MultiFile',MultiFile);
|
||||
|
||||
// disable?
|
||||
if(disable_slave) $(slave).attr('disabled','disabled').prop('disabled',true);
|
||||
|
||||
}; // MultiFile.addSlave
|
||||
// Bind a new element
|
||||
|
||||
|
||||
// Add a new file to the list
|
||||
MultiFile.addToList = function (slave, slave_count, files) {
|
||||
//if(window.console) console.log('MultiFile.addToList',slave_count);
|
||||
|
||||
//# Trigger Event! onFileAppend
|
||||
MultiFile.trigger('FileAppend', slave, MultiFile, files);
|
||||
//# End Event!
|
||||
|
||||
var names = $('<span/>');
|
||||
$.each(files, function (i, file) {
|
||||
var v = String(file.name || '' ).replace(/[&<>'"]/g, function(c) { return '&#'+c.charCodeAt()+';'; }),
|
||||
S = MultiFile.STRING,
|
||||
n = S.label || S.file || S.name,
|
||||
t = S.title || S.tooltip || S.selected,
|
||||
p = file.type.substr(0,6) == 'image/' ? '<img class="MultiFile-preview" style="'+ MultiFile.previewCss+'"/>' : '',
|
||||
label = $(
|
||||
(
|
||||
'<span class="MultiFile-label" title="' + t + '">'+
|
||||
'<span class="MultiFile-title">'+ n +'</span>'+
|
||||
(MultiFile.preview || $(slave).is('.with-preview') ? p : '' )+
|
||||
'</span>'
|
||||
)
|
||||
.replace(/\$(file|name)/gi, (v.match(/[^\/\\]+$/gi)||[v])[0])
|
||||
.replace(/\$(ext|extension|type)/gi, (v.match(/[^\.]+$/gi)||[''])[0])
|
||||
.replace(/\$(size)/gi, sl(file.size || 0))
|
||||
.replace(/\$(preview)/gi, p)
|
||||
.replace(/\$(i)/gi, i)
|
||||
);
|
||||
|
||||
// now supports preview via locale string.
|
||||
// just add an <img class='MultiFile-preview'/> anywhere within the "file" string
|
||||
label.find('img.MultiFile-preview').each(function(){
|
||||
var t = this;
|
||||
var oFReader = new FileReader();
|
||||
oFReader.readAsDataURL(file);
|
||||
oFReader.onload = function (oFREvent) {
|
||||
t.src = oFREvent.target.result;
|
||||
};
|
||||
});
|
||||
|
||||
// append file label to list
|
||||
if(i>0) names.append(', ');
|
||||
names.append(label);
|
||||
|
||||
var v = String(file.name || '' );
|
||||
names[names.length] =
|
||||
(
|
||||
'<span class="MultiFile-title" title="' + MultiFile.STRING.selected + '">'
|
||||
+ MultiFile.STRING.file +
|
||||
'</span>'
|
||||
)
|
||||
.replace(/\$(file|name)/gi, (v.match(/[^\/\\]+$/gi)||[v])[0])
|
||||
.replace(/\$(ext|extension|type)/gi, (v.match(/[^\.]+$/gi)||[''])[0])
|
||||
.replace(/\$(size)/gi, sl(file.size || 0))
|
||||
.replace(/\$(i)/gi, i)
|
||||
;
|
||||
});
|
||||
|
||||
//$.each(files, function (i, file) {
|
||||
// Create label elements
|
||||
var
|
||||
r = $('<div class="MultiFile-label"></div>'),
|
||||
b = $('<a class="MultiFile-remove" href="#' + MultiFile.wrapID + '">' + MultiFile.STRING.remove + '</a>')
|
||||
|
||||
// ********
|
||||
// TODO:
|
||||
// refactor this as a single event listener on the control's
|
||||
// wrapper for better performance and cleaner code
|
||||
// ********
|
||||
.click(function () {
|
||||
|
||||
// get list of files being removed
|
||||
var files_being_removed = FILE_LIST(slave);
|
||||
|
||||
//# Trigger Event! onFileRemove
|
||||
MultiFile.trigger('FileRemove', slave, MultiFile, files_being_removed);
|
||||
//# End Event!
|
||||
|
||||
MultiFile.n--;
|
||||
MultiFile.current.disabled = false;
|
||||
|
||||
// remove the relevant <input type="file"/> element
|
||||
$(slave).remove();
|
||||
|
||||
// remove the relevant label
|
||||
$(this).parent().remove();
|
||||
|
||||
// Show most current element again (move into view) and clear selection
|
||||
$(MultiFile.current).css({
|
||||
position: '',
|
||||
top: ''
|
||||
});
|
||||
$(MultiFile.current).reset().val('').attr('value', '')[0].value = '';
|
||||
|
||||
// point to currently visible element (always true, not necessary)
|
||||
//MultiFile.current = MultiFile.wrapper.find('[type=file]:visible');
|
||||
|
||||
// rebuild array with the files that are left.
|
||||
var files_remaining = [], remain_size = 0;
|
||||
// go through each slave
|
||||
$(MultiFile.wrapper).find('input[type=file]').each(function(){
|
||||
// go through each file in each slave
|
||||
$.each(FILE_LIST(this), function (i, file) {
|
||||
if(file.name){
|
||||
//console.log('MultiFile.debug> FileRemove> remaining file', file.size, file);
|
||||
// fresh file array
|
||||
files_remaining[files_remaining.length] = file;
|
||||
// fresh size count
|
||||
remain_size += file.size;
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// update MultiFile object
|
||||
MultiFile.files = files_remaining;
|
||||
MultiFile.total_size = remain_size;
|
||||
MultiFile.size_label = sl(remain_size);
|
||||
|
||||
// update current control's reference to MultiFile object
|
||||
$(MultiFile.wrapper).data('MultiFile', MultiFile);
|
||||
|
||||
//# Trigger Event! afterFileRemove
|
||||
MultiFile.trigger('afterFileRemove', slave, MultiFile, files_being_removed);
|
||||
//# End Event!
|
||||
|
||||
//# Trigger Event! onFileChange
|
||||
MultiFile.trigger('FileChange', MultiFile.current, MultiFile, files_remaining);
|
||||
//# End Event!
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// Insert label
|
||||
MultiFile.list.append(
|
||||
r.append(b, ' ', names)
|
||||
);
|
||||
|
||||
//}); // each file?
|
||||
|
||||
//# Trigger Event! afterFileAppend
|
||||
MultiFile.trigger('afterFileAppend', slave, MultiFile, files);
|
||||
//# End Event!
|
||||
|
||||
//# Trigger Event! onFileChange
|
||||
MultiFile.trigger('FileChange', slave, MultiFile, MultiFile.files);
|
||||
//# End Event!
|
||||
|
||||
}; // MultiFile.addToList
|
||||
// Add element to selected files list
|
||||
|
||||
|
||||
// Bind functionality to the first element
|
||||
if (!MultiFile.MultiFile) MultiFile.addSlave(MultiFile.e, 0);
|
||||
|
||||
// Increment control count
|
||||
//MultiFile.I++; // using window.MultiFile
|
||||
MultiFile.n++;
|
||||
|
||||
// deprecated: contorl's data now stored in wrapper because it is never removed.
|
||||
// improved performance and lower memory comsumption
|
||||
// Save control to element
|
||||
//MultiFile.E.data('MultiFile', MultiFile);
|
||||
|
||||
|
||||
//#####################################################################
|
||||
// MAIN PLUGIN FUNCTIONALITY - END
|
||||
//#####################################################################
|
||||
}); // each element
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
### Core functionality and API ###
|
||||
*/
|
||||
$.extend($.fn.MultiFile, {
|
||||
|
||||
|
||||
/**
|
||||
* This method exposes the all the control's data
|
||||
*
|
||||
* Returns an object with various settings and properties of the selected files
|
||||
* for this particular instance of the control. stored in the control's wrapper
|
||||
*
|
||||
* @name data
|
||||
* @type Object
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $('#selector').MultiFile('data');
|
||||
*/
|
||||
data: function () {
|
||||
|
||||
// analyse this element
|
||||
var e = $(this), b = e.is('.MultiFile-wrap');
|
||||
|
||||
// get control wrapper
|
||||
var wp = b ? e : e.data('MultiFile-wrap');
|
||||
if(!wp || !wp.length)
|
||||
return !console.error('Could not find MultiFile control wrapper');
|
||||
|
||||
// get control data from wrapper
|
||||
var mf = wp.data('MultiFile');
|
||||
if(!mf)
|
||||
return !console.error('Could not find MultiFile data in wrapper');
|
||||
|
||||
// return data
|
||||
return mf || {};
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method removes all selected files
|
||||
*
|
||||
* Returns a jQuery collection of all affected elements.
|
||||
*
|
||||
* @name reset
|
||||
* @type jQuery
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $.fn.MultiFile.reset();
|
||||
*/
|
||||
reset: function () {
|
||||
var mf = this.MultiFile('data');
|
||||
if (mf) $(mf.list).find('a.MultiFile-remove').click();
|
||||
return $(this);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method exposes the array of selected files
|
||||
*
|
||||
* Returns an array of file objects
|
||||
*
|
||||
* @name files
|
||||
* @type Array
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $('#selector').MultiFile('files');
|
||||
*/
|
||||
files: function () {
|
||||
var mf = this.MultiFile('data');
|
||||
if(!mf) return !console.log('MultiFile plugin not initialized');
|
||||
return mf.files || [];
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method exposes the plugin's sum of the sizes of all files selected
|
||||
*
|
||||
* Returns size (in bytes) of files selected
|
||||
*
|
||||
* @name size
|
||||
* @type Number
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $('#selector').MultiFile('size');
|
||||
*/
|
||||
size: function () {
|
||||
var mf = this.MultiFile('data');
|
||||
if(!mf) return !console.log('MultiFile plugin not initialized');
|
||||
return mf.total_size || 0;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method exposes the plugin's tally of how many files have been selected
|
||||
*
|
||||
* Returns number (a count) of files selected
|
||||
*
|
||||
* @name count
|
||||
* @type Number
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $('#selector').MultiFile('size');
|
||||
*/
|
||||
count: function () {
|
||||
var mf = this.MultiFile('data');
|
||||
if(!mf) return !console.log('MultiFile plugin not initialized');
|
||||
return mf.files ? mf.files.length || 0 : 0;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This utility makes it easy to disable all 'empty' file elements in the document before submitting a form.
|
||||
* It marks the affected elements so they can be easily re-enabled after the form submission or validation.
|
||||
*
|
||||
* Returns a jQuery collection of all affected elements.
|
||||
*
|
||||
* @name disableEmpty
|
||||
* @type jQuery
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $.fn.MultiFile.disableEmpty();
|
||||
* @param String class (optional) A string specifying a class to be applied to all affected elements - Default: 'mfD'.
|
||||
*/
|
||||
disableEmpty: function (klass) {
|
||||
klass = (typeof (klass) == 'string' ? klass : '') || 'mfD';
|
||||
var o = [];
|
||||
$('input:file.MultiFile').each(function () {
|
||||
if ($(this).val() == '') o[o.length] = this;
|
||||
});
|
||||
|
||||
// automatically re-enable for novice users
|
||||
window.clearTimeout($.fn.MultiFile.reEnableTimeout);
|
||||
$.fn.MultiFile.reEnableTimeout = window.setTimeout($.fn.MultiFile.reEnableEmpty, 500);
|
||||
|
||||
return $(o).each(function () {
|
||||
this.disabled = true
|
||||
}).addClass(klass);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method re-enables 'empty' file elements that were disabled (and marked) with the $.fn.MultiFile.disableEmpty method.
|
||||
*
|
||||
* Returns a jQuery collection of all affected elements.
|
||||
*
|
||||
* @name reEnableEmpty
|
||||
* @type jQuery
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $.fn.MultiFile.reEnableEmpty();
|
||||
* @param String klass (optional) A string specifying the class that was used to mark affected elements - Default: 'mfD'.
|
||||
*/
|
||||
reEnableEmpty: function (klass) {
|
||||
klass = (typeof (klass) == 'string' ? klass : '') || 'mfD';
|
||||
return $('input:file.' + klass).removeClass(klass).each(function () {
|
||||
this.disabled = false
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* This method will intercept other jQuery plugins and disable empty file input elements prior to form submission
|
||||
*
|
||||
|
||||
* @name intercept
|
||||
* @cat Plugins/MultiFile
|
||||
* @author Diego A. (http://www.fyneworks.com/)
|
||||
*
|
||||
* @example $.fn.MultiFile.intercept();
|
||||
* @param Array methods (optional) Array of method names to be intercepted
|
||||
*/
|
||||
intercepted: {},
|
||||
intercept: function (methods, context, args) {
|
||||
var method, value;
|
||||
args = args || [];
|
||||
if (args.constructor.toString().indexOf("Array") < 0) args = [args];
|
||||
if (typeof (methods) == 'function') {
|
||||
$.fn.MultiFile.disableEmpty();
|
||||
value = methods.apply(context || window, args);
|
||||
//SEE-http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
|
||||
setTimeout(function () {
|
||||
$.fn.MultiFile.reEnableEmpty()
|
||||
}, 1000);
|
||||
return value;
|
||||
};
|
||||
if (methods.constructor.toString().indexOf("Array") < 0) methods = [methods];
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
method = methods[i] + ''; // make sure that we have a STRING
|
||||
if (method)(function (method) { // make sure that method is ISOLATED for the interception
|
||||
$.fn.MultiFile.intercepted[method] = $.fn[method] || function () {};
|
||||
$.fn[method] = function () {
|
||||
$.fn.MultiFile.disableEmpty();
|
||||
value = $.fn.MultiFile.intercepted[method].apply(this, arguments);
|
||||
//SEE http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
|
||||
setTimeout(function () {
|
||||
$.fn.MultiFile.reEnableEmpty()
|
||||
}, 1000);
|
||||
return value;
|
||||
}; // interception
|
||||
})(method); // MAKE SURE THAT method IS ISOLATED for the interception
|
||||
}; // for each method
|
||||
} // $.fn.MultiFile.intercept
|
||||
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
### Default Settings ###
|
||||
eg.: You can override default control like this:
|
||||
$.fn.MultiFile.options.accept = 'gif|jpg';
|
||||
*/
|
||||
$.fn.MultiFile.options = { //$.extend($.fn.MultiFile, { options: {
|
||||
accept: '', // accepted file extensions
|
||||
max: -1, // maximum number of selectable files
|
||||
maxfile: -1, // maximum size of a single file
|
||||
maxsize: -1, // maximum size of entire payload
|
||||
|
||||
// name to use for newly created elements
|
||||
namePattern: '$name', // same name by default (which creates an array)
|
||||
/*master name*/ // use $name
|
||||
/*master id */ // use $id
|
||||
/*group count*/ // use $g
|
||||
/*slave count*/ // use $i
|
||||
/*other */ // use any combination of he above, eg.: $name_file$i
|
||||
|
||||
// previews
|
||||
preview: false,
|
||||
previewCss: 'max-height:100px; max-width:100px;',
|
||||
|
||||
// STRING: collection lets you show messages in different languages
|
||||
STRING: {
|
||||
remove: 'x',
|
||||
denied: 'You cannot select a $ext file.\nTry again...',
|
||||
file: '$file',
|
||||
selected: 'File selected: $file',
|
||||
duplicate: 'This file has already been selected:\n$file',
|
||||
toomuch: 'The files selected exceed the maximum size permited ($size)',
|
||||
toomany: 'Too many files selected (max: $max)',
|
||||
toobig: '$file is too big (max $size)'
|
||||
},
|
||||
|
||||
// name of methods that should be automcatically intercepted so the plugin can disable
|
||||
// extra file elements that are empty before execution and automatically re-enable them afterwards
|
||||
autoIntercept: ['submit', 'ajaxSubmit', 'ajaxForm', 'validate', 'valid' /* array of methods to intercept */ ],
|
||||
|
||||
// error handling function
|
||||
error: function (s) {
|
||||
|
||||
if(typeof console != 'undefined') console.log(s);
|
||||
|
||||
// TODO: add various dialog handlers here?
|
||||
alert(s);
|
||||
}
|
||||
}; //} });
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
### Additional Methods ###
|
||||
Required functionality outside the plugin's scope
|
||||
*/
|
||||
|
||||
// Native input reset method - because this alone doesn't always work: $(element).val('').attr('value', '')[0].value = '';
|
||||
$.fn.reset = $.fn.reset || function () {
|
||||
return this.each(function () {
|
||||
try {
|
||||
this.reset();
|
||||
} catch (e) {}
|
||||
});
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
### Default implementation ###
|
||||
The plugin will attach itself to file inputs
|
||||
with the class 'multi' when the page loads
|
||||
*/
|
||||
$(function () {
|
||||
//$("input:file.multi").MultiFile();
|
||||
$("input[type=file].multi").MultiFile();
|
||||
});
|
||||
|
||||
|
||||
/*# AVOID COLLISIONS #*/
|
||||
})(jQuery);
|
||||
/*# AVOID COLLISIONS #*/
|
614
ready2use/srv/libs/qrcode.js
Executable file
@ -0,0 +1,614 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* - Using the 'QRCode for Javascript library'
|
||||
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
|
||||
* - this library has no dependencies.
|
||||
*
|
||||
* @author davidshimjs
|
||||
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
|
||||
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
|
||||
*/
|
||||
var QRCode;
|
||||
|
||||
(function () {
|
||||
//---------------------------------------------------------------------
|
||||
// QRCode for JavaScript
|
||||
//
|
||||
// Copyright (c) 2009 Kazuhiko Arase
|
||||
//
|
||||
// URL: http://www.d-project.com/
|
||||
//
|
||||
// Licensed under the MIT license:
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// The word "QR Code" is registered trademark of
|
||||
// DENSO WAVE INCORPORATED
|
||||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
function QR8bitByte(data) {
|
||||
this.mode = QRMode.MODE_8BIT_BYTE;
|
||||
this.data = data;
|
||||
this.parsedData = [];
|
||||
|
||||
// Added to support UTF-8 Characters
|
||||
for (var i = 0, l = this.data.length; i < l; i++) {
|
||||
var byteArray = [];
|
||||
var code = this.data.charCodeAt(i);
|
||||
|
||||
if (code > 0x10000) {
|
||||
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
|
||||
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
|
||||
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[3] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x800) {
|
||||
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
|
||||
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[2] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x80) {
|
||||
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
|
||||
byteArray[1] = 0x80 | (code & 0x3F);
|
||||
} else {
|
||||
byteArray[0] = code;
|
||||
}
|
||||
|
||||
this.parsedData.push(byteArray);
|
||||
}
|
||||
|
||||
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
|
||||
|
||||
if (this.parsedData.length != this.data.length) {
|
||||
this.parsedData.unshift(191);
|
||||
this.parsedData.unshift(187);
|
||||
this.parsedData.unshift(239);
|
||||
}
|
||||
}
|
||||
|
||||
QR8bitByte.prototype = {
|
||||
getLength: function (buffer) {
|
||||
return this.parsedData.length;
|
||||
},
|
||||
write: function (buffer) {
|
||||
for (var i = 0, l = this.parsedData.length; i < l; i++) {
|
||||
buffer.put(this.parsedData[i], 8);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function QRCodeModel(typeNumber, errorCorrectLevel) {
|
||||
this.typeNumber = typeNumber;
|
||||
this.errorCorrectLevel = errorCorrectLevel;
|
||||
this.modules = null;
|
||||
this.moduleCount = 0;
|
||||
this.dataCache = null;
|
||||
this.dataList = [];
|
||||
}
|
||||
|
||||
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
|
||||
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
|
||||
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
|
||||
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
|
||||
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
|
||||
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
|
||||
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
|
||||
this.modules[r][6]=(r%2==0);}
|
||||
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
|
||||
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
|
||||
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
|
||||
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
|
||||
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
|
||||
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
|
||||
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
|
||||
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
|
||||
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
|
||||
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
|
||||
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
|
||||
+buffer.getLengthInBits()
|
||||
+">"
|
||||
+totalDataCount*8
|
||||
+")");}
|
||||
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
|
||||
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
|
||||
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD1,8);}
|
||||
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
|
||||
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
|
||||
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
|
||||
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
|
||||
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
|
||||
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
|
||||
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
|
||||
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
|
||||
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
|
||||
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
|
||||
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
|
||||
if(r==0&&c==0){continue;}
|
||||
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
|
||||
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
|
||||
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
|
||||
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
|
||||
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
|
||||
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
|
||||
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
|
||||
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
|
||||
while(n>=256){n-=255;}
|
||||
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
|
||||
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
|
||||
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
|
||||
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
|
||||
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
|
||||
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
|
||||
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
|
||||
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
|
||||
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
|
||||
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
|
||||
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
|
||||
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
|
||||
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
|
||||
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
|
||||
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
|
||||
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
|
||||
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
|
||||
|
||||
function _isSupportCanvas() {
|
||||
return typeof CanvasRenderingContext2D != "undefined";
|
||||
}
|
||||
|
||||
// android 2.x doesn't support Data-URI spec
|
||||
function _getAndroid() {
|
||||
var android = false;
|
||||
var sAgent = navigator.userAgent;
|
||||
|
||||
if (/android/i.test(sAgent)) { // android
|
||||
android = true;
|
||||
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
|
||||
|
||||
if (aMat && aMat[1]) {
|
||||
android = parseFloat(aMat[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return android;
|
||||
}
|
||||
|
||||
var svgDrawer = (function() {
|
||||
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
|
||||
this.clear();
|
||||
|
||||
function makeSVG(tag, attrs) {
|
||||
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
|
||||
for (var k in attrs)
|
||||
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
|
||||
return el;
|
||||
}
|
||||
|
||||
var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
|
||||
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||
_el.appendChild(svg);
|
||||
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
if (oQRCode.isDark(row, col)) {
|
||||
var child = makeSVG("use", {"x": String(col), "y": String(row)});
|
||||
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
|
||||
svg.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Drawing.prototype.clear = function () {
|
||||
while (this._el.hasChildNodes())
|
||||
this._el.removeChild(this._el.lastChild);
|
||||
};
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
|
||||
|
||||
// Drawing in DOM by using Table tag
|
||||
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
aHTML.push('<tr>');
|
||||
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
|
||||
}
|
||||
|
||||
aHTML.push('</tr>');
|
||||
}
|
||||
|
||||
aHTML.push('</table>');
|
||||
_el.innerHTML = aHTML.join('');
|
||||
|
||||
// Fix the margin values as real size.
|
||||
var elTable = _el.childNodes[0];
|
||||
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
|
||||
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
|
||||
|
||||
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
|
||||
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._el.innerHTML = '';
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})() : (function () { // Drawing in Canvas
|
||||
function _onMakeImage() {
|
||||
this._elImage.src = this._elCanvas.toDataURL("image/png");
|
||||
this._elImage.style.display = "block";
|
||||
this._elCanvas.style.display = "none";
|
||||
}
|
||||
|
||||
// Android 2.1 bug workaround
|
||||
// http://code.google.com/p/android/issues/detail?id=5141
|
||||
if (this._android && this._android <= 2.1) {
|
||||
var factor = 1 / window.devicePixelRatio;
|
||||
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
|
||||
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
||||
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
|
||||
for (var i = arguments.length - 1; i >= 1; i--) {
|
||||
arguments[i] = arguments[i] * factor;
|
||||
}
|
||||
} else if (typeof dw == "undefined") {
|
||||
arguments[1] *= factor;
|
||||
arguments[2] *= factor;
|
||||
arguments[3] *= factor;
|
||||
arguments[4] *= factor;
|
||||
}
|
||||
|
||||
drawImage.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user's browser supports Data URI or not
|
||||
*
|
||||
* @private
|
||||
* @param {Function} fSuccess Occurs if it supports Data URI
|
||||
* @param {Function} fFail Occurs if it doesn't support Data URI
|
||||
*/
|
||||
function _safeSetDataURI(fSuccess, fFail) {
|
||||
var self = this;
|
||||
self._fFail = fFail;
|
||||
self._fSuccess = fSuccess;
|
||||
|
||||
// Check it just once
|
||||
if (self._bSupportDataURI === null) {
|
||||
var el = document.createElement("img");
|
||||
var fOnError = function() {
|
||||
self._bSupportDataURI = false;
|
||||
|
||||
if (self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
var fOnSuccess = function() {
|
||||
self._bSupportDataURI = true;
|
||||
|
||||
if (self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
el.onabort = fOnError;
|
||||
el.onerror = fOnError;
|
||||
el.onload = fOnSuccess;
|
||||
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
|
||||
return;
|
||||
} else if (self._bSupportDataURI === true && self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
} else if (self._bSupportDataURI === false && self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing QRCode by using canvas
|
||||
*
|
||||
* @constructor
|
||||
* @param {HTMLElement} el
|
||||
* @param {Object} htOption QRCode Options
|
||||
*/
|
||||
var Drawing = function (el, htOption) {
|
||||
this._bIsPainted = false;
|
||||
this._android = _getAndroid();
|
||||
|
||||
this._htOption = htOption;
|
||||
this._elCanvas = document.createElement("canvas");
|
||||
this._elCanvas.width = htOption.width;
|
||||
this._elCanvas.height = htOption.height;
|
||||
el.appendChild(this._elCanvas);
|
||||
this._el = el;
|
||||
this._oContext = this._elCanvas.getContext("2d");
|
||||
this._bIsPainted = false;
|
||||
this._elImage = document.createElement("img");
|
||||
this._elImage.alt = "Scan me!";
|
||||
this._elImage.style.display = "none";
|
||||
this._el.appendChild(this._elImage);
|
||||
this._bSupportDataURI = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _elImage = this._elImage;
|
||||
var _oContext = this._oContext;
|
||||
var _htOption = this._htOption;
|
||||
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = _htOption.width / nCount;
|
||||
var nHeight = _htOption.height / nCount;
|
||||
var nRoundedWidth = Math.round(nWidth);
|
||||
var nRoundedHeight = Math.round(nHeight);
|
||||
|
||||
_elImage.style.display = "none";
|
||||
this.clear();
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
var bIsDark = oQRCode.isDark(row, col);
|
||||
var nLeft = col * nWidth;
|
||||
var nTop = row * nHeight;
|
||||
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.lineWidth = 1;
|
||||
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
|
||||
|
||||
// 안티 앨리어싱 방지 처리
|
||||
_oContext.strokeRect(
|
||||
Math.floor(nLeft) + 0.5,
|
||||
Math.floor(nTop) + 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
|
||||
_oContext.strokeRect(
|
||||
Math.ceil(nLeft) - 0.5,
|
||||
Math.ceil(nTop) - 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this._bIsPainted = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the image from Canvas if the browser supports Data URI.
|
||||
*/
|
||||
Drawing.prototype.makeImage = function () {
|
||||
if (this._bIsPainted) {
|
||||
_safeSetDataURI.call(this, _onMakeImage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return whether the QRCode is painted or not
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
Drawing.prototype.isPainted = function () {
|
||||
return this._bIsPainted;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
|
||||
this._bIsPainted = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Number} nNumber
|
||||
*/
|
||||
Drawing.prototype.round = function (nNumber) {
|
||||
if (!nNumber) {
|
||||
return nNumber;
|
||||
}
|
||||
|
||||
return Math.floor(nNumber * 1000) / 1000;
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the type by string length
|
||||
*
|
||||
* @private
|
||||
* @param {String} sText
|
||||
* @param {Number} nCorrectLevel
|
||||
* @return {Number} type
|
||||
*/
|
||||
function _getTypeNumber(sText, nCorrectLevel) {
|
||||
var nType = 1;
|
||||
var length = _getUTF8Length(sText);
|
||||
|
||||
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
|
||||
var nLimit = 0;
|
||||
|
||||
switch (nCorrectLevel) {
|
||||
case QRErrorCorrectLevel.L :
|
||||
nLimit = QRCodeLimitLength[i][0];
|
||||
break;
|
||||
case QRErrorCorrectLevel.M :
|
||||
nLimit = QRCodeLimitLength[i][1];
|
||||
break;
|
||||
case QRErrorCorrectLevel.Q :
|
||||
nLimit = QRCodeLimitLength[i][2];
|
||||
break;
|
||||
case QRErrorCorrectLevel.H :
|
||||
nLimit = QRCodeLimitLength[i][3];
|
||||
break;
|
||||
}
|
||||
|
||||
if (length <= nLimit) {
|
||||
break;
|
||||
} else {
|
||||
nType++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nType > QRCodeLimitLength.length) {
|
||||
throw new Error("Too long data");
|
||||
}
|
||||
|
||||
return nType;
|
||||
}
|
||||
|
||||
function _getUTF8Length(sText) {
|
||||
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
|
||||
return replacedText.length + (replacedText.length != sText ? 3 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @class QRCode
|
||||
* @constructor
|
||||
* @example
|
||||
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
|
||||
*
|
||||
* @example
|
||||
* var oQRCode = new QRCode("test", {
|
||||
* text : "http://naver.com",
|
||||
* width : 128,
|
||||
* height : 128
|
||||
* });
|
||||
*
|
||||
* oQRCode.clear(); // Clear the QRCode.
|
||||
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
|
||||
*
|
||||
* @param {HTMLElement|String} el target element or 'id' attribute of element.
|
||||
* @param {Object|String} vOption
|
||||
* @param {String} vOption.text QRCode link data
|
||||
* @param {Number} [vOption.width=256]
|
||||
* @param {Number} [vOption.height=256]
|
||||
* @param {String} [vOption.colorDark="#000000"]
|
||||
* @param {String} [vOption.colorLight="#ffffff"]
|
||||
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
|
||||
*/
|
||||
QRCode = function (el, vOption) {
|
||||
this._htOption = {
|
||||
width : 256,
|
||||
height : 256,
|
||||
typeNumber : 4,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRErrorCorrectLevel.H
|
||||
};
|
||||
|
||||
if (typeof vOption === 'string') {
|
||||
vOption = {
|
||||
text : vOption
|
||||
};
|
||||
}
|
||||
|
||||
// Overwrites options
|
||||
if (vOption) {
|
||||
for (var i in vOption) {
|
||||
this._htOption[i] = vOption[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof el == "string") {
|
||||
el = document.getElementById(el);
|
||||
}
|
||||
|
||||
if (this._htOption.useSVG) {
|
||||
Drawing = svgDrawer;
|
||||
}
|
||||
|
||||
this._android = _getAndroid();
|
||||
this._el = el;
|
||||
this._oQRCode = null;
|
||||
this._oDrawing = new Drawing(this._el, this._htOption);
|
||||
|
||||
if (this._htOption.text) {
|
||||
this.makeCode(this._htOption.text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the QRCode
|
||||
*
|
||||
* @param {String} sText link data
|
||||
*/
|
||||
QRCode.prototype.makeCode = function (sText) {
|
||||
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
|
||||
this._oQRCode.addData(sText);
|
||||
this._oQRCode.make();
|
||||
this._el.title = sText;
|
||||
this._oDrawing.draw(this._oQRCode);
|
||||
this.makeImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the Image from Canvas element
|
||||
* - It occurs automatically
|
||||
* - Android below 3 doesn't support Data-URI spec.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
QRCode.prototype.makeImage = function () {
|
||||
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
|
||||
this._oDrawing.makeImage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
QRCode.prototype.clear = function () {
|
||||
this._oDrawing.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* @name QRCode.CorrectLevel
|
||||
*/
|
||||
QRCode.CorrectLevel = QRErrorCorrectLevel;
|
||||
})();
|
1
ready2use/srv/libs/qrcode.min.js
vendored
Executable file
1
ready2use/srv/libs/webtorrent.min.js
vendored
Normal file
60
ready2use/srv/php/AdminController.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require_once "Utils/Constants.php";
|
||||
require_once 'Utils/Helpers.php';
|
||||
|
||||
Class AdminController {
|
||||
|
||||
function validPassword($password){
|
||||
|
||||
$passwordFile = file_get_contents(Constants::CONST_PASSWORD_FOLDER."/".Constants::CONST_PASSWORD_FILE, FILE_USE_INCLUDE_PATH);
|
||||
if( Helpers::verify_pw($password, $passwordFile)){
|
||||
$_SESSION['superadmin'] = true;
|
||||
return true;
|
||||
} else {
|
||||
$_SESSION['superadmin'] = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function unlog(){
|
||||
$_SESSION['superadmin'] = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function isAdminLogged(){
|
||||
if(!isset( $_SESSION['superadmin'])) return false;
|
||||
return $_SESSION['superadmin'];
|
||||
}
|
||||
|
||||
function setPassword($password){
|
||||
|
||||
if($this->isPassword()) return false;
|
||||
|
||||
$hash = Helpers::hash_pw($password);
|
||||
|
||||
//Test if the folder exist
|
||||
if (!file_exists(Constants::CONST_PASSWORD_FOLDER.'/')) {
|
||||
mkdir(Constants::CONST_PASSWORD_FOLDER, 0777, true);
|
||||
}
|
||||
|
||||
//Record the hash
|
||||
$fp = fopen(Constants::CONST_PASSWORD_FOLDER."/".Constants::CONST_PASSWORD_FILE, 'w');
|
||||
fwrite($fp, $hash);
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function isPassword(){
|
||||
|
||||
if (!file_exists(Constants::CONST_PASSWORD_FOLDER.'/')) return false;
|
||||
if (!file_exists(Constants::CONST_PASSWORD_FOLDER.'/'.Constants::CONST_PASSWORD_FILE)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
1145
ready2use/srv/php/ChanController.php
Normal file
389
ready2use/srv/php/ChanWebService.php
Normal file
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
________ _ _______
|
||||
/ ____/ /_ ____ _____ | | / / ___/
|
||||
/ / / __ \/ __ `/ __ \ | | /| / /\__ \
|
||||
/ /___/ / / / /_/ / / / / | |/ |/ /___/ /
|
||||
\____/_/ /_/\__,_/_/ /_/ |__/|__//____/
|
||||
|
||||
|
||||
|
||||
Chan WEBSERVICES
|
||||
reception of the webservice for chan
|
||||
|
||||
*/
|
||||
|
||||
require_once 'ChanController.php';
|
||||
require_once 'AdminController.php';
|
||||
require_once 'Models/Post.php';
|
||||
|
||||
$action = "";
|
||||
if(isset($_POST["action"]))
|
||||
$action = $_POST["action"];
|
||||
|
||||
/*
|
||||
controls the RESTful services
|
||||
URL mapping
|
||||
*/
|
||||
switch($action){
|
||||
|
||||
//**************************************
|
||||
// * WS ADMIN
|
||||
// *************************************
|
||||
|
||||
case "setAdminPassword":
|
||||
|
||||
$password = "";
|
||||
if( isset($_POST['password']) ) $password = $_POST['password'];
|
||||
$AdminController = new AdminController();
|
||||
$result = $AdminController -> setPassword($password);
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "validAdmin":
|
||||
|
||||
$password = "";
|
||||
if( isset($_POST['password']) ) $password = $_POST['password'];
|
||||
$AdminController = new AdminController();
|
||||
$result = $AdminController -> validPassword($password);
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "testAdminSession":
|
||||
|
||||
$AdminController = new AdminController();
|
||||
$result = $AdminController -> isAdminLogged();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "unLog":
|
||||
|
||||
$AdminController = new AdminController();
|
||||
$result = $AdminController -> unlog();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "deletePost":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$mapKey = "";
|
||||
$postId = -1;
|
||||
if( isset($_POST['map_key']) ) $mapKey = $_POST['map_key'];
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
|
||||
$result = $chanController -> deletePost($mapKey ,$postId );
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "setBan":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$mapKey = "";
|
||||
$postId = -1;
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
|
||||
$result = $chanController -> setBan($postId );
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "deletePostForVal":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$val = "";
|
||||
$result = false;
|
||||
if( isset($_POST['val']) ){
|
||||
$val = $_POST['val'];
|
||||
$result = $chanController -> deletePostForVal($val);
|
||||
}
|
||||
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "setPostUrlToFile":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$mapKey = "";
|
||||
$postId = -1;
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
|
||||
$result = $chanController -> setPostUrlToFile($postId );
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case "setPostCanon":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$mapKey = "";
|
||||
$postId = -1;
|
||||
if( isset($_POST['map_key']) ) $mapKey = $_POST['map_key'];
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
|
||||
$result = $chanController -> setPostCanon($mapKey ,$postId );
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
case "banUser":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$mapKey = "";
|
||||
$reason = "";
|
||||
$durationD = 0;
|
||||
$postId = -1;
|
||||
if( isset($_POST['map_key']) ) $mapKey = $_POST['map_key'];
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
if( isset($_POST['durationD']) ) $durationD = $_POST['durationD'];
|
||||
if( isset($_POST['reason']) ) $reason = $_POST['reason'];
|
||||
|
||||
$result = $chanController -> banForPost($mapKey, $postId, $reason, $durationD);
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;*/
|
||||
|
||||
case "getAllPost":
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getAllPost();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "getAllMaps":
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getAllMaps();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
case "getAllTiles":
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getAllTiles();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
case "saveMapModel":
|
||||
|
||||
$mapKey = "";
|
||||
$levelData = "";
|
||||
|
||||
if( isset($_POST['id']) ) $mapKey = $_POST['key'];
|
||||
if( isset($_POST['level_data']) ) $levelData = $_POST['level_data'];
|
||||
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> saveMapModel($mapKey, $levelData);
|
||||
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
//**************************************
|
||||
// * WS for PUR CHAN
|
||||
// * Actual version
|
||||
// *************************************
|
||||
|
||||
case "getDungeonSettings":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getSettings();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "getMapPosts":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getMapPosts();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
case "getAllPost":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getAllPost();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;*/
|
||||
|
||||
case "getReplies":
|
||||
|
||||
if( isset($_POST['post_id']) ) $postId = $_POST['post_id'];
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getReplies($postId);
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "createPost":
|
||||
|
||||
$chanController = new ChanController();
|
||||
|
||||
$torrentBytes = NULL;
|
||||
$file = NULL;
|
||||
$img = NULL;
|
||||
|
||||
if( isset($_FILES['file']) ) $file = $_FILES['file'];
|
||||
if( isset($_POST['torrent']) ) $torrentBytes = $_POST['torrent'];
|
||||
if( isset($_POST['image_data']) ) $img = $_POST['image_data'];
|
||||
|
||||
$postModel = new Post();
|
||||
$postModel -> fillWithPostData();
|
||||
|
||||
$result = $chanController -> createPost($postModel,$file, $img);
|
||||
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
//**************************************
|
||||
// * WS PLAYER
|
||||
// *************************************
|
||||
|
||||
case "getActions":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> getActions();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
case "setAction":
|
||||
|
||||
if( isset($_POST['player_action']) ) $player_action = $_POST['player_action'];
|
||||
if( isset($_POST['value']) ) $value = $_POST['value'];
|
||||
$chanController = new ChanController();
|
||||
$result = $chanController -> setAction($player_action,$value);
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "initPlayer":
|
||||
|
||||
$chanController = new ChanController();
|
||||
|
||||
$playerId = null;
|
||||
$playerKey = null;
|
||||
$mapKey = null;
|
||||
$playerPassword = null;
|
||||
|
||||
if( isset($_POST['player_id']) ) $playerId = $_POST['player_id'];
|
||||
if( isset($_POST['player_key']) ) $playerKey = $_POST['player_key'];
|
||||
if( isset($_POST['player_password']) ) $playerPassword = $_POST['player_password'];
|
||||
if( isset($_POST['map_key']) ) $mapKey = $_POST['map_key'];
|
||||
|
||||
$playerData = $chanController->init( $playerId, $playerKey, $playerPassword, $mapKey );
|
||||
//$playerId = null;
|
||||
|
||||
//if(array_key_exists ("id", $playerData)) $playerId = $playerData["id"];
|
||||
|
||||
//return the player postion
|
||||
//$playersList = $chanController->getAllPlayers($playerId);
|
||||
//$arts = $chanController->getArtByMap($playerData);
|
||||
/*
|
||||
$result = array (
|
||||
'list' => $playersList,
|
||||
'player' => $playerData
|
||||
);*/
|
||||
Helpers::makeGenericResponse(true, $playerData, null);
|
||||
|
||||
break;
|
||||
|
||||
case "changeMapPlayer":
|
||||
$chanController = new ChanController();
|
||||
$mapKey = null;
|
||||
if( isset($_POST['map_key']) ) $mapKey = $_POST['map_key'];
|
||||
$chanController->setPlayerMapKey( $mapKey );
|
||||
$result = $chanController -> getMapPosts();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
case "changeMapPlayerName":
|
||||
$chanController = new ChanController();
|
||||
$mapName = null;
|
||||
if( isset($_POST['map_name']) ) $mapName = $_POST['map_name'];
|
||||
$chanController->setPlayerMapName( $mapName );
|
||||
$result = $chanController -> getMapPosts();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
case "changeMapRandom":
|
||||
$chanController = new ChanController();
|
||||
$secret = true;
|
||||
if( isset($_POST['secret']) ) $secret = $_POST['secret'];
|
||||
$chanController->setPlayerMapRand( $secret );
|
||||
$result = $chanController -> getMapPosts();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
break;
|
||||
|
||||
case "setPlayerItem":
|
||||
|
||||
$chanController = new ChanController();
|
||||
$itemKey = null;
|
||||
if( isset($_POST['item_key']) ) $itemKey = $_POST['item_key'];
|
||||
$chanController->setItem( $itemKey );
|
||||
$result = $chanController -> getMapPosts();
|
||||
Helpers::makeGenericResponse(true, $result, null);
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
case "movePlayer":
|
||||
|
||||
$chanController = new ChanController();
|
||||
|
||||
$playerId = null;
|
||||
$playerKey = null;
|
||||
$playerPassword = null;
|
||||
|
||||
if( isset($_POST['player_id']) ) $playerId = $_POST['player_id'];
|
||||
if( isset($_POST['player_key']) ) $playerKey = $_POST['player_key'];
|
||||
if( isset($_POST['player_password']) ) $playerPassword = $_POST['player_password'];
|
||||
|
||||
//position in 3D to get
|
||||
$playerData = array();
|
||||
if( isset($_POST['position_x']) ) $playerData['position_x'] = $_POST['position_x'];
|
||||
if( isset($_POST['position_y']) ) $playerData['position_y'] = $_POST['position_y'];
|
||||
if( isset($_POST['position_z']) ) $playerData['position_z'] = $_POST['position_z'];
|
||||
if( isset($_POST['map_key']) ) $playerData['map_key'] = $_POST['map_key'];
|
||||
|
||||
|
||||
$playerResult = $chanController->move( $playerId, $playerKey, $playerPassword, $playerData);
|
||||
|
||||
if($playerResult == null){
|
||||
|
||||
//PLAYER DONT EXIST ANYMORE!!!
|
||||
$playerResult = $chanController->init( $playerId, $playerKey, $playerPassword );
|
||||
$playerId = null;
|
||||
|
||||
if(array_key_exists ("id", $playerResult)) $playerId = $playerResult["id"];
|
||||
}
|
||||
|
||||
//return the player postion
|
||||
$playersList = $chanController->getAllPlayers($playerId);
|
||||
|
||||
//Gte post datas
|
||||
$postsList = $chanController->getArtByMap($playerData);
|
||||
|
||||
//IS the player Null??? if yes
|
||||
$result = array(
|
||||
'user' => $playerResult,
|
||||
'players' => $playersList,
|
||||
'arts' => $postsList
|
||||
);
|
||||
|
||||
Helpers::makeGenericResponse(true,$result, null);
|
||||
|
||||
break;
|
||||
*/
|
||||
}
|
311
ready2use/srv/php/DatabaseWebService.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
____ __ __ _ _______
|
||||
/ __ \____ _/ /_____ _/ /_ ____ _________ | | / / ___/
|
||||
/ / / / __ `/ __/ __ `/ __ \/ __ `/ ___/ _ \ | | /| / /\__ \
|
||||
/ /_/ / /_/ / /_/ /_/ / /_/ / /_/ (__ ) __/ | |/ |/ /___/ /
|
||||
/_____/\__,_/\__/\__,_/_.___/\__,_/____/\___/ |__/|__//____/
|
||||
|
||||
Database WS
|
||||
*/
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
require_once "Utils/Constants.php";
|
||||
require_once "Imports/LazerImports.php";
|
||||
require_once 'MapController.php';
|
||||
require_once 'AdminController.php';
|
||||
|
||||
use Lazer\Classes\Database as Lazer;
|
||||
defined('LAZER_DATA_PATH') or define('LAZER_DATA_PATH', realpath(dirname(__FILE__)).'/'.Constants::CONST_DB_FOLDER.'/');
|
||||
|
||||
//Admin password
|
||||
$password = "";
|
||||
if(isset($_POST["password"])) $password = $_POST["password"];
|
||||
|
||||
$adminController = new AdminController();
|
||||
|
||||
if(!$adminController ->validPassword($password)){
|
||||
echo "bad password!!";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
//Create an autoloader
|
||||
$action = "";
|
||||
if(isset($_POST["action"]))
|
||||
$action = $_POST["action"];
|
||||
|
||||
|
||||
switch($action){
|
||||
|
||||
|
||||
case "initDB":
|
||||
|
||||
//**************************************
|
||||
// * DB MAIN
|
||||
// *************************************
|
||||
|
||||
try{
|
||||
$banExtist = false;
|
||||
try{
|
||||
$banExtist = \Lazer\Classes\Helpers\Validate::table(Constants::CONST_TABLE_BANS)->exists();
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
//Database doesn't exist
|
||||
}
|
||||
|
||||
if(!$banExtist){
|
||||
Lazer::create(Constants::CONST_TABLE_BANS, array(
|
||||
'id' => 'integer',
|
||||
'reason' => 'string',
|
||||
'id_post' => 'integer',
|
||||
//'thread_key' => 'string',
|
||||
'map_key' => 'string',
|
||||
'date' => 'integer',
|
||||
'duration' => 'integer',
|
||||
'player_ip' => 'string'
|
||||
));
|
||||
echo 'Ban created';
|
||||
}
|
||||
|
||||
Lazer::create(Constants::CONST_TABLE_FILES, array(
|
||||
'id' => 'integer',
|
||||
'id_post' => 'integer',
|
||||
'map_key' => 'string',
|
||||
'fake_path' => 'string',
|
||||
'fake_name' => 'string',
|
||||
'file_name' => 'string'
|
||||
));
|
||||
|
||||
|
||||
echo 'Forum creation succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
try{
|
||||
|
||||
Lazer::create(Constants::CONST_TABLE_PLAYERS, array(
|
||||
'id' => 'integer',
|
||||
'name' => 'string',
|
||||
'talk' => 'string',
|
||||
'is_admin' => 'boolean',
|
||||
'player_key' => 'string',
|
||||
'hp' => 'integer',
|
||||
'money' => 'integer',
|
||||
'map_key' => 'string',
|
||||
'last_action' => 'integer',
|
||||
'position_x' => 'double',
|
||||
'position_y' => 'double',
|
||||
'position_z' => 'double'
|
||||
));
|
||||
|
||||
|
||||
Lazer::create(Constants::CONST_TABLE_ITEMS, array(
|
||||
'id' => 'integer',
|
||||
'key' => 'string',
|
||||
'player_id' => 'integer',
|
||||
'action' => 'string',
|
||||
'type' => 'string',
|
||||
'name' => 'string',
|
||||
'description' => 'string',
|
||||
'map_key' => 'string',
|
||||
'x' => 'double',
|
||||
'y' => 'double',
|
||||
'is_expendable' => 'boolean',
|
||||
'value' => 'integer'
|
||||
));
|
||||
|
||||
Lazer::create(Constants::CONST_TABLE_LOGS, array(
|
||||
'id' => 'integer',
|
||||
'map_key' => 'string',
|
||||
'last_action'=> 'integer',
|
||||
'ip' => 'string',
|
||||
'to' => 'integer',
|
||||
'name' => 'string',
|
||||
'player_id' => 'integer',
|
||||
'value' => 'string',
|
||||
'action' => 'string'
|
||||
));
|
||||
|
||||
echo 'PLAYER creation succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//**************************************
|
||||
// * DB MAPS AND POST
|
||||
// *************************************
|
||||
|
||||
//init the data base
|
||||
case "initMapsAndPosts":
|
||||
|
||||
try{
|
||||
|
||||
Lazer::create(Constants::CONST_TABLE_POSTS, array(
|
||||
'id' => 'integer',
|
||||
'show' => 'boolean',
|
||||
'key' => 'string',
|
||||
'scale' => 'integer',
|
||||
'date' => 'integer',
|
||||
'reply' => 'integer',
|
||||
'player_ip' => 'string',
|
||||
'player_id' => 'integer',
|
||||
'is_canon' => 'boolean',
|
||||
'is_admin' => 'boolean',
|
||||
'nsfw' => 'boolean',
|
||||
'graffiti' => 'boolean',
|
||||
'preview' => 'string',
|
||||
'player_name' => 'string',
|
||||
//'thread_key' => 'string',
|
||||
'map_key' => 'string',
|
||||
'canvas_key' => 'string',
|
||||
'message' => 'string',
|
||||
'url' => 'string',
|
||||
'magnet' => 'string',
|
||||
'torrent' => 'string',
|
||||
'hash' => 'string'
|
||||
));
|
||||
|
||||
//Map creation
|
||||
Lazer::create(Constants::CONST_TABLE_MAP, array(
|
||||
'id' => 'integer',
|
||||
'key' => 'string',
|
||||
'name' => 'string',
|
||||
'description' => 'string',
|
||||
'theme' => 'string',
|
||||
'width' => 'integer',
|
||||
'height' => 'integer',
|
||||
|
||||
'x' => 'integer',
|
||||
'y' => 'integer',
|
||||
|
||||
'door_key_n' => 'string',
|
||||
'door_key_e' => 'string',
|
||||
'door_key_s' => 'string',
|
||||
'door_key_w' => 'string',
|
||||
|
||||
'level_data' => 'string',
|
||||
|
||||
'num_post_max' => 'integer',
|
||||
'fast_travel' => 'boolean',
|
||||
'is_safe' => 'boolean',
|
||||
'is_chan' => 'boolean',
|
||||
'is_secret' => 'boolean'
|
||||
));
|
||||
|
||||
$mapController = new MapController();
|
||||
$mapController -> generateWorld();
|
||||
|
||||
|
||||
echo 'MAP creation succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//init the data base
|
||||
case "initBans":
|
||||
$banExtist = false;
|
||||
try{
|
||||
$banExtist = \Lazer\Classes\Helpers\Validate::table(Constants::CONST_TABLE_BANS)->exists();
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
//Database doesn't exist
|
||||
}
|
||||
|
||||
if(!$banExtist){
|
||||
Lazer::create(Constants::CONST_TABLE_BANS, array(
|
||||
'id' => 'integer',
|
||||
'reason' => 'string',
|
||||
'id_post' => 'integer',
|
||||
//'thread_key' => 'string',
|
||||
'map_key' => 'string',
|
||||
'date' => 'integer',
|
||||
'duration' => 'integer',
|
||||
'player_ip' => 'string'
|
||||
));
|
||||
echo 'Ban created';
|
||||
}
|
||||
break;
|
||||
|
||||
case "destroyBans":
|
||||
Lazer::remove(Constants::CONST_TABLE_BANS);
|
||||
echo 'ban destroyed';
|
||||
break;
|
||||
|
||||
|
||||
//init the data base
|
||||
case "destroyDB":
|
||||
|
||||
try{
|
||||
|
||||
//Lazer::remove(Constants::CONST_TABLE_BANS);
|
||||
Lazer::remove(Constants::CONST_TABLE_FILES);
|
||||
Lazer::remove(Constants::CONST_TABLE_PLAYERS);
|
||||
Lazer::remove(Constants::CONST_TABLE_ITEMS);
|
||||
Lazer::remove(Constants::CONST_TABLE_LOGS);
|
||||
|
||||
|
||||
echo 'DB erase succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//init the data base
|
||||
case "destroyMapsAndPosts":
|
||||
|
||||
try{
|
||||
|
||||
Lazer::remove(Constants::CONST_TABLE_POSTS);
|
||||
Lazer::remove(Constants::CONST_TABLE_MAP);
|
||||
|
||||
echo 'Maps and Posts erase succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//init the data base
|
||||
/*
|
||||
case "cleanDB":
|
||||
try{
|
||||
|
||||
Lazer::table(Constants::CONST_TABLE_POSTS)->delete();
|
||||
Lazer::table(Constants::CONST_TABLE_BANS)->delete();
|
||||
Lazer::table(Constants::CONST_TABLE_PLAYERS)->delete();
|
||||
Lazer::table(Constants::CONST_TABLE_FILES)->delete();
|
||||
Lazer::table(Constants::CONST_TABLE_ITEMS)->delete();
|
||||
//Lazer::table(Constants::CONST_TABLE_LOOT)->delete();
|
||||
Lazer::table(Constants::CONST_TABLE_MAP)->delete();
|
||||
|
||||
echo 'DB erase succed';
|
||||
|
||||
} catch(\Lazer\Classes\LazerException $e){
|
||||
|
||||
echo 'exception'.$e;
|
||||
|
||||
}
|
||||
break;*/
|
||||
|
||||
}
|
10
ready2use/srv/php/Imports/LazerImports.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?
|
||||
|
||||
include_once "Libs/Lazer/Classes/Database.php";
|
||||
include_once "Libs/Lazer/Classes/Helpers/Data.php";
|
||||
include_once "Libs/Lazer/Classes/Helpers/Config.php";
|
||||
//include "Libs/Lazer/Classes/Helpers/File.php";
|
||||
//include "Libs/Lazer/Classes/Helpers/FileInterface.php";
|
||||
//include "Libs/Lazer/Classes/LazerException.php";
|
||||
//include "Libs/Lazer/Classes/Relations.php";
|
||||
//include "Libs/Lazer/Classes/Helpers/Validate.php";
|
961
ready2use/srv/php/Libs/Lazer/Classes/Core/Database.php
Executable file
@ -0,0 +1,961 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes;
|
||||
|
||||
|
||||
include "Libs/Lazer/Classes/Helpers/Validate.php";
|
||||
include "Libs/Lazer/Classes/LazerException.php";
|
||||
|
||||
use Lazer\Classes\LazerException;
|
||||
use Lazer\Classes\Database;
|
||||
use Lazer\Classes\Relation;
|
||||
use Lazer\Classes\Helpers;
|
||||
|
||||
/**
|
||||
* Core class of Lazer.
|
||||
*
|
||||
* There are classes to use JSON files like file database.
|
||||
*
|
||||
* Using style was inspired by ORM classes.
|
||||
*
|
||||
* @category Core
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
abstract class Core_Database implements \IteratorAggregate, \Countable {
|
||||
|
||||
/**
|
||||
* Contain returned data from file as object or array of objects
|
||||
* @var mixed Data from table
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Name of file (table)
|
||||
* @var string Name of table
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Object with setted data
|
||||
* @var object Setted data
|
||||
*/
|
||||
protected $set;
|
||||
|
||||
/**
|
||||
* ID of current row if setted
|
||||
* @var integer Current ID
|
||||
*/
|
||||
protected $currentId;
|
||||
|
||||
/**
|
||||
* Key if current row if setted
|
||||
* @var integer Current key
|
||||
*/
|
||||
protected $currentKey;
|
||||
|
||||
/**
|
||||
* Pending functions with values
|
||||
* @see \Lazer\Classes\Core_Database::setPending()
|
||||
* @var array
|
||||
*/
|
||||
protected $pending;
|
||||
|
||||
/**
|
||||
* Information about to reset keys in array or not to
|
||||
* @var integer
|
||||
*/
|
||||
protected $resetKeys = 1;
|
||||
|
||||
/**
|
||||
* Factory pattern
|
||||
* @param string $name Name of table
|
||||
* @return \Lazer\Classes\Database
|
||||
* @throws LazerException If there's problems with load file
|
||||
*/
|
||||
public static function table($name)
|
||||
{
|
||||
Helpers\Validate::table($name)->exists();
|
||||
|
||||
$self = new Database;
|
||||
$self->name = $name;
|
||||
|
||||
$self->setFields();
|
||||
$self->setPending();
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rows from table
|
||||
* @uses Lazer\Classes\Helpers\Data::get() to get data from file
|
||||
* @return array
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return Helpers\Data::table($this->name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting data to Database::$data
|
||||
*/
|
||||
protected function setData()
|
||||
{
|
||||
$this->data = $this->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array key of row with specified ID
|
||||
* @param integer $id Row ID
|
||||
* @return integer Row key
|
||||
* @throws LazerException If there's no data with that ID
|
||||
*/
|
||||
protected function getRowKey($id)
|
||||
{
|
||||
foreach ($this->getData() as $key => $data)
|
||||
{
|
||||
if ($data->id == $id)
|
||||
{
|
||||
return $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw new LazerException('No data found with ID: ' . $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set NULL for currentId and currentKey
|
||||
*/
|
||||
protected function clearKeyInfo()
|
||||
{
|
||||
$this->currentId = $this->currentKey = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting fields with default values
|
||||
* @uses Lazer\Classes\Helpers\Validate::isNumeric() to check if type of field is numeric
|
||||
*/
|
||||
protected function setFields()
|
||||
{
|
||||
$this->set = new \stdClass();
|
||||
$schema = $this->schema();
|
||||
|
||||
foreach ($schema as $field => $type)
|
||||
{
|
||||
if (Helpers\Validate::isNumeric($type) AND $field != 'id')
|
||||
{
|
||||
$this->set->{$field} = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set->{$field} = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pending functions in right order with default values (Empty).
|
||||
*/
|
||||
protected function setPending()
|
||||
{
|
||||
$this->pending = array(
|
||||
'where' => array(),
|
||||
'orderBy' => array(),
|
||||
'limit' => array(),
|
||||
'with' => array(),
|
||||
'groupBy' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear info about previous queries
|
||||
*/
|
||||
protected function clearQuery()
|
||||
{
|
||||
$this->setPending();
|
||||
$this->clearKeyInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validating fields and setting variables to current operations
|
||||
* @uses Lazer\Classes\Helpers\Validate::field() to check that field exist
|
||||
* @uses Lazer\Classes\Helpers\Validate::type() to check that field type is correct
|
||||
* @param string $name Field name
|
||||
* @param mixed $value Field value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (Helpers\Validate::table($this->name)->field($name) && Helpers\Validate::table($this->name)->type($name, $value))
|
||||
{
|
||||
$this->set->{$name} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning variable from Object
|
||||
* @param string $name Field name
|
||||
* @return mixed Field value
|
||||
* @throws LazerException
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->set->{$name}))
|
||||
return $this->set->{$name};
|
||||
|
||||
throw new LazerException('There is no data');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given field exists
|
||||
* @param string $name Field name
|
||||
* @return boolean True if the field exists, false otherwise
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return isset($this->set->{$name});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute pending functions
|
||||
*/
|
||||
protected function pending()
|
||||
{
|
||||
$this->setData();
|
||||
foreach ($this->pending as $func => $args)
|
||||
{
|
||||
if (!empty($args))
|
||||
{
|
||||
call_user_func(array($this, $func . 'Pending'));
|
||||
}
|
||||
}
|
||||
|
||||
//clear pending values after executed query
|
||||
$this->clearQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creating new table
|
||||
*
|
||||
* For example few fields:
|
||||
*
|
||||
* Database::create('news', array(
|
||||
* 'title' => 'string',
|
||||
* 'content' => 'string',
|
||||
* 'rating' => 'double',
|
||||
* 'author' => 'integer'
|
||||
* ));
|
||||
*
|
||||
* Types of field:
|
||||
* - boolean
|
||||
* - integer
|
||||
* - string
|
||||
* - double (also for float type)
|
||||
*
|
||||
* ID field isn't required (it will be created automatically) but you can specify it at first place.
|
||||
*
|
||||
* @uses Lazer\Classes\Helpers\Data::arrToLower() to lower case keys and values of array
|
||||
* @uses Lazer\Classes\Helpers\Data::exists() to check if data file exists
|
||||
* @uses Lazer\Classes\Helpers\Config::exists() to check if config file exists
|
||||
* @uses Lazer\Classes\Helpers\Validate::types() to check if type of fields are correct
|
||||
* @uses Lazer\Classes\Helpers\Data::put() to save data file
|
||||
* @uses Lazer\Classes\Helpers\Config::put() to save config file
|
||||
* @param string $name Table name
|
||||
* @param array $fields Field configuration
|
||||
* @throws LazerException If table exist
|
||||
*/
|
||||
public static function create($name, array $fields)
|
||||
{
|
||||
$fields = Helpers\Validate::arrToLower($fields);
|
||||
|
||||
if (Helpers\Data::table($name)->exists() && Helpers\Config::table($name)->exists())
|
||||
{
|
||||
throw new LazerException('helper\Table "' . $name . '" already exists');
|
||||
}
|
||||
|
||||
$types = array_values($fields);
|
||||
|
||||
Helpers\Validate::types($types);
|
||||
|
||||
if (!array_key_exists('id', $fields))
|
||||
{
|
||||
$fields = array('id' => 'integer') + $fields;
|
||||
}
|
||||
|
||||
$data = new \stdClass();
|
||||
$data->last_id = 0;
|
||||
$data->schema = $fields;
|
||||
$data->relations = new \stdClass();
|
||||
|
||||
Helpers\Data::table($name)->put(array());
|
||||
Helpers\Config::table($name)->put($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removing table with config
|
||||
* @uses Lazer\Classes\Helpers\Data::remove() to remove data file
|
||||
* @uses Lazer\Classes\Helpers\Config::remove() to remove config file
|
||||
* @param string $name Table name
|
||||
* @return boolean|LazerException
|
||||
*/
|
||||
public static function remove($name)
|
||||
{
|
||||
if (Helpers\Data::table($name)->remove() && Helpers\Config::table($name)->remove())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouping results by one field
|
||||
* @param string $column
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function groupBy($column)
|
||||
{
|
||||
if (Helpers\Validate::table($this->name)->field($column))
|
||||
{
|
||||
$this->resetKeys = 0;
|
||||
$this->pending[__FUNCTION__] = $column;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouping array pending method
|
||||
*/
|
||||
protected function groupByPending()
|
||||
{
|
||||
$column = $this->pending['groupBy'];
|
||||
|
||||
$grouped = array();
|
||||
foreach ($this->data as $object)
|
||||
{
|
||||
$grouped[$object->{$column}][] = $object;
|
||||
}
|
||||
|
||||
$this->data = $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* JOIN other tables
|
||||
* @param string $table relations separated by :
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function with($table)
|
||||
{
|
||||
$this->pending['with'][] = explode(':', $table);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending function for with(), joining other tables to current
|
||||
*/
|
||||
protected function withPending()
|
||||
{
|
||||
$joins = $this->pending['with'];
|
||||
foreach ($joins as $join)
|
||||
{
|
||||
$local = (count($join) > 1) ? array_slice($join, -2, 1)[0] : $this->name;
|
||||
$foreign = end($join);
|
||||
|
||||
$relation = Relation::table($local)->with($foreign);
|
||||
|
||||
$data = $this->data;
|
||||
|
||||
foreach ($join as $part)
|
||||
{
|
||||
$data = $relation->build($data, $part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorting data by field
|
||||
* @param string $key Field name
|
||||
* @param string $direction ASC|DESC
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function orderBy($key, $direction = 'ASC')
|
||||
{
|
||||
if (Helpers\Validate::table($this->name)->field($key))
|
||||
{
|
||||
$directions = array(
|
||||
'ASC' => SORT_ASC,
|
||||
'DESC' => SORT_DESC
|
||||
);
|
||||
$this->pending[__FUNCTION__][$key] = isset($directions[$direction]) ? $directions[$direction] : 'ASC';
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort an array of objects by more than one field.
|
||||
* @
|
||||
* @link http://blog.amnuts.com/2011/04/08/sorting-an-array-of-objects-by-one-or-more-object-property/ It's not mine algorithm
|
||||
*/
|
||||
protected function orderByPending()
|
||||
{
|
||||
$properties = $this->pending['orderBy'];
|
||||
uasort($this->data, function($a, $b) use ($properties)
|
||||
{
|
||||
foreach ($properties as $column => $direction)
|
||||
{
|
||||
if (is_int($column))
|
||||
{
|
||||
$column = $direction;
|
||||
$direction = SORT_ASC;
|
||||
}
|
||||
$collapse = function($node, $props)
|
||||
{
|
||||
if (is_array($props))
|
||||
{
|
||||
foreach ($props as $prop)
|
||||
{
|
||||
$node = (!isset($node->$prop)) ? null : $node->$prop;
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (!isset($node->$props)) ? null : $node->$props;
|
||||
}
|
||||
};
|
||||
$aProp = $collapse($a, $column);
|
||||
$bProp = $collapse($b, $column);
|
||||
|
||||
if ($aProp != $bProp)
|
||||
{
|
||||
return ($direction == SORT_ASC) ? strnatcasecmp($aProp, $bProp) : strnatcasecmp($bProp, $aProp);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Where function, like SQL
|
||||
*
|
||||
* Operators:
|
||||
* - Standard operators (=, !=, >, <, >=, <=)
|
||||
* - IN (only for array value)
|
||||
* - NOT IN (only for array value)
|
||||
*
|
||||
* @param string $field Field name
|
||||
* @param string $op Operator
|
||||
* @param mixed $value Field value
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function where($field, $op, $value)
|
||||
{
|
||||
$this->pending['where'][] = array(
|
||||
'type' => 'and',
|
||||
'field' => $field,
|
||||
'op' => $op,
|
||||
'value' => $value,
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for where()
|
||||
* @param string $field Field name
|
||||
* @param string $op Operator
|
||||
* @param mixed $value Field value
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function andWhere($field, $op, $value)
|
||||
{
|
||||
$this->where($field, $op, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for where(), setting OR for searching
|
||||
* @param string $field Field name
|
||||
* @param string $op Operator
|
||||
* @param mixed $value Field value
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function orWhere($field, $op, $value)
|
||||
{
|
||||
$this->pending['where'][] = array(
|
||||
'type' => 'or',
|
||||
'field' => $field,
|
||||
'op' => $op,
|
||||
'value' => $value,
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for array_filter() in where()
|
||||
* @return boolean
|
||||
*/
|
||||
protected function wherePending()
|
||||
{
|
||||
$operator = array(
|
||||
'=' => '==',
|
||||
'!=' => '!=',
|
||||
'>' => '>',
|
||||
'<' => '<',
|
||||
'>=' => '>=',
|
||||
'<=' => '<=',
|
||||
'and' => '&&',
|
||||
'or' => '||'
|
||||
);
|
||||
|
||||
$this->data = array_filter($this->data, function($row) use ($operator)
|
||||
{
|
||||
$clause = '';
|
||||
$result = true;
|
||||
|
||||
foreach ($this->pending['where'] as $key => $condition)
|
||||
{
|
||||
extract($condition);
|
||||
|
||||
if (is_array($value) && $op == 'IN')
|
||||
{
|
||||
$value = (in_array($row->{$field}, $value)) ? 1 : 0;
|
||||
$op = '==';
|
||||
$field = 1;
|
||||
}
|
||||
elseif (!is_array($value) && in_array($op, array('LIKE', 'like')))
|
||||
{
|
||||
$regex = "/^" . str_replace('%', '(.*?)', preg_quote($value)) . "$/si";
|
||||
$value = preg_match($regex, $row->{$field});
|
||||
$op = '==';
|
||||
$field = 1;
|
||||
}
|
||||
elseif (!is_array($value) && $op != 'IN')
|
||||
{
|
||||
$value = is_string($value) ?
|
||||
'\'' . mb_strtolower($value) . '\'' :
|
||||
$value;
|
||||
|
||||
$op = $operator[$op];
|
||||
$field = is_string($row->{$field}) ?
|
||||
'mb_strtolower($row->' . $field .')' :
|
||||
'$row->' . $field;
|
||||
}
|
||||
|
||||
$type = (!$key) ?
|
||||
null :
|
||||
$operator[$type];
|
||||
|
||||
$query = array($type, $field, $op, $value);
|
||||
$clause .= implode(' ', $query) . ' ';
|
||||
|
||||
eval('$result = ' . $clause . ';');
|
||||
}
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning data as indexed or assoc array.
|
||||
* @param string $key Field that will be the key, NULL for Indexed
|
||||
* @param string $value Field that will be the value
|
||||
* @return array
|
||||
*/
|
||||
public function asArray($key = null, $value = null)
|
||||
{
|
||||
if (!is_null($key))
|
||||
{
|
||||
Helpers\Validate::table($this->name)->field($key);
|
||||
}
|
||||
if (!is_null($value))
|
||||
{
|
||||
Helpers\Validate::table($this->name)->field($value);
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
if (!$this->resetKeys)
|
||||
{
|
||||
if (is_null($key) && is_null($value))
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->data as $rowKey => $data)
|
||||
{
|
||||
$datas[$rowKey] = array();
|
||||
foreach ($data as $row)
|
||||
{
|
||||
if (is_null($key))
|
||||
{
|
||||
$datas[$rowKey][] = $row->{$value};
|
||||
}
|
||||
elseif (is_null($value))
|
||||
{
|
||||
$datas[$rowKey][$row->{$key}] = $row;
|
||||
}
|
||||
else
|
||||
{
|
||||
$datas[$rowKey][$row->{$key}] = $row->{$value};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_null($key) && is_null($value))
|
||||
{
|
||||
foreach ($this->data as $data)
|
||||
{
|
||||
$datas[] = get_object_vars($data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->data as $data)
|
||||
{
|
||||
if (is_null($key))
|
||||
{
|
||||
$datas[] = $data->{$value};
|
||||
}
|
||||
elseif (is_null($value))
|
||||
{
|
||||
$datas[$data->{$key}] = $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$datas[$data->{$key}] = $data->{$value};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit returned data
|
||||
*
|
||||
* Should be used at the end of chain, before end method
|
||||
* @param integer $number Limit number
|
||||
* @param integer $offset Offset number
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function limit($number, $offset = 0)
|
||||
{
|
||||
$this->pending['limit'] = array(
|
||||
'offset' => $offset,
|
||||
'number' => $number
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending function for limit()
|
||||
*/
|
||||
protected function limitPending()
|
||||
{
|
||||
$offset = $this->pending['limit']['offset'];
|
||||
$num = $this->pending['limit']['number'];
|
||||
$this->data = array_slice($this->data, $offset, $num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new fields to table, array schema like in create() function
|
||||
* @param array $fields Associative array
|
||||
*/
|
||||
public function addFields(array $fields)
|
||||
{
|
||||
$fields = Helpers\Validate::arrToLower($fields);
|
||||
|
||||
Helpers\Validate::types(array_values($fields));
|
||||
|
||||
$schema = $this->schema();
|
||||
$fields = array_diff_assoc($fields, $schema);
|
||||
|
||||
if (!empty($fields))
|
||||
{
|
||||
$config = $this->config();
|
||||
$config->schema = array_merge($schema, $fields);
|
||||
|
||||
$data = $this->getData();
|
||||
foreach ($data as $key => $object)
|
||||
{
|
||||
foreach ($fields as $name => $type)
|
||||
{
|
||||
if (Helpers\Validate::isNumeric($type))
|
||||
$data[$key]->{$name} = 0;
|
||||
else
|
||||
$data[$key]->{$name} = null;
|
||||
}
|
||||
}
|
||||
|
||||
Helpers\Data::table($this->name)->put($data);
|
||||
Helpers\Config::table($this->name)->put($config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete fields from array
|
||||
* @param array $fields Indexed array
|
||||
*/
|
||||
public function deleteFields(array $fields)
|
||||
{
|
||||
$fields = Helpers\Validate::arrToLower($fields);
|
||||
|
||||
Helpers\Validate::table($this->name)->fields($fields);
|
||||
|
||||
$config = $this->config();
|
||||
$config->schema = array_diff_key($this->schema(), array_flip($fields));
|
||||
|
||||
$data = $this->getData();
|
||||
foreach ($data as $key => $object)
|
||||
{
|
||||
foreach ($fields as $name)
|
||||
{
|
||||
unset($data[$key]->{$name});
|
||||
}
|
||||
}
|
||||
|
||||
Helpers\Data::table($this->name)->put($data);
|
||||
Helpers\Config::table($this->name)->put($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table name
|
||||
* @return string table name
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning object with config for table
|
||||
* @return object Config
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
return Helpers\Config::table($this->name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array with names of fields
|
||||
* @return array Fields
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
return Helpers\Config::table($this->name)->fields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning assoc array with types of fields
|
||||
* @return array Fields type
|
||||
*/
|
||||
public function schema()
|
||||
{
|
||||
return Helpers\Config::table($this->name)->schema();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning assoc array with relationed tables
|
||||
* @param string|null $tableName
|
||||
* @return array Fields type
|
||||
*/
|
||||
public function relations($tableName = null)
|
||||
{
|
||||
return Helpers\Config::table($this->name)->relations($tableName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning last ID from table
|
||||
* @return integer Last ID
|
||||
*/
|
||||
public function lastId()
|
||||
{
|
||||
return Helpers\Config::table($this->name)->lastId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving inserted or updated data
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$data = $this->getData();
|
||||
if (!$this->currentId)
|
||||
{
|
||||
$config = $this->config();
|
||||
$config->last_id++;
|
||||
|
||||
$this->set->id = $config->last_id;
|
||||
array_push($data, $this->set);
|
||||
|
||||
Helpers\Config::table($this->name)->put($config);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set->id = $this->currentId;
|
||||
$data[$this->currentKey] = $this->set;
|
||||
}
|
||||
|
||||
Helpers\Data::table($this->name)->put($data);
|
||||
|
||||
// $this->setFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleting loaded data
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$data = $this->getData();
|
||||
if (isset($this->currentId))
|
||||
{
|
||||
unset($data[$this->currentKey]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->pending();
|
||||
$old = $data;
|
||||
$data = array_diff_key($old, $this->data);
|
||||
}
|
||||
$this->data = array_values($data);
|
||||
|
||||
return Helpers\Data::table($this->name)->put($this->data) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return count in integer or array of integers (if grouped)
|
||||
* @return mixed
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if (!$this->resetKeys)
|
||||
{
|
||||
$count = array();
|
||||
foreach ($this->data as $group => $data)
|
||||
{
|
||||
$count[$group] = count($data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$count = count($this->data);
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns one row with specified ID
|
||||
* @param integer $id Row ID
|
||||
* @return \Lazer\Classes\Core_Database
|
||||
*/
|
||||
public function find($id = NULL)
|
||||
{
|
||||
if ($id !== NULL)
|
||||
{
|
||||
$data = $this->getData();
|
||||
$this->currentId = $id;
|
||||
$this->currentKey = $this->getRowKey($id);
|
||||
foreach ($data[$this->currentKey] as $field => $value)
|
||||
{
|
||||
$this->set->{$field} = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->limit(1)->findAll();
|
||||
$data = $this->data;
|
||||
if (count($data))
|
||||
{
|
||||
foreach ($data[0] as $field => $value)
|
||||
{
|
||||
$this->set->{$field} = $value;
|
||||
}
|
||||
|
||||
$this->currentId = $this->set->id;
|
||||
$this->currentKey = $this->getRowKey($this->currentId);
|
||||
}
|
||||
}
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make data ready to read
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$this->pending();
|
||||
$this->data = $this->resetKeys ? array_values($this->data) : $this->data;
|
||||
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator for Data
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug functions, prints whole query with values
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
$print = "Lazer::table(" . $this->name . ")\n";
|
||||
foreach ($this->pending as $function => $values)
|
||||
{
|
||||
if (!empty($values))
|
||||
{
|
||||
|
||||
if (is_array($values))
|
||||
{
|
||||
if (is_array(reset($values)))
|
||||
{
|
||||
foreach ($values as $value)
|
||||
{
|
||||
if ($function == 'where')
|
||||
{
|
||||
array_shift($value);
|
||||
}
|
||||
if ($function == 'with')
|
||||
{
|
||||
$params = implode(':', $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$params = implode(', ', $value);
|
||||
}
|
||||
$print .= "\t" . '->' . $function . '(' . $params . ')' . "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$params = implode(', ', $values);
|
||||
$print .= "\t" . '->' . $function . '(' . $params . ')' . "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$print .= "\t" . '->' . $function . '(' . $values . ')' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '<pre>' . print_r($print, true) . '</pre>';
|
||||
$this->clearQuery();
|
||||
}
|
||||
|
||||
}
|
394
ready2use/srv/php/Libs/Lazer/Classes/Core/Relation.php
Executable file
@ -0,0 +1,394 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes;
|
||||
|
||||
use Lazer\Classes\Helpers\Validate;
|
||||
use Lazer\Classes\Helpers\Config;
|
||||
use Lazer\Classes\Database;
|
||||
use Lazer\Classes\LazerException;
|
||||
|
||||
/**
|
||||
* Relation class of LAZER project.
|
||||
*
|
||||
* @category Core
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
abstract class Core_Relation {
|
||||
|
||||
/**
|
||||
* Tables names
|
||||
* @var array tables
|
||||
*/
|
||||
protected $tables = array(
|
||||
'local' => null,
|
||||
'foreign' => null
|
||||
);
|
||||
|
||||
/**
|
||||
* Relation keys names
|
||||
* @var array keys
|
||||
*/
|
||||
protected $keys = array(
|
||||
'local' => null,
|
||||
'foreign' => null
|
||||
);
|
||||
|
||||
/**
|
||||
* Current relation type
|
||||
* @var string
|
||||
*/
|
||||
protected $relationType;
|
||||
|
||||
/**
|
||||
* All relations types
|
||||
* @var array
|
||||
*/
|
||||
protected static $relations = array('belongsTo', 'hasMany', 'hasAndBelongsToMany');
|
||||
|
||||
/**
|
||||
* Factory method
|
||||
* @param string $name Name of table
|
||||
* @return \Lazer\Classes\Relation
|
||||
*/
|
||||
public static function table($name)
|
||||
{
|
||||
Validate::table($name)->exists();
|
||||
|
||||
$self = new Relation;
|
||||
$self->tables['local'] = $name;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of junction table name in many2many relation
|
||||
* @return boolean|string Name of junction table or false
|
||||
*/
|
||||
public function getJunction()
|
||||
{
|
||||
if ($this->relationType == 'hasAndBelongsToMany')
|
||||
{
|
||||
$tables = $this->tables;
|
||||
sort($tables);
|
||||
return implode('_', $tables);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set relation type to field
|
||||
* @param string $relation Name of relation
|
||||
*/
|
||||
protected function setRelationType($relation)
|
||||
{
|
||||
Validate::relationType($relation);
|
||||
$this->relationType = $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table name
|
||||
* @param string $type local or foreign
|
||||
* @param string $name table name
|
||||
*/
|
||||
protected function setTable($type, $name)
|
||||
{
|
||||
Validate::table($name)->exists();
|
||||
$this->tables[$type] = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set key name
|
||||
* @param string $type local or foreign
|
||||
* @param string $key key name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
* @throws LazerException First you must define tables name
|
||||
*/
|
||||
protected function setKey($type, $key)
|
||||
{
|
||||
if (!in_array(null, $this->tables))
|
||||
{
|
||||
Validate::table($this->tables[$type])->field($key);
|
||||
|
||||
$this->keys[$type] = $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new LazerException('First you must define tables name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set local key name
|
||||
* @param string $key key name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
* @throws LazerException First you must define tables name
|
||||
*/
|
||||
public function localKey($key)
|
||||
{
|
||||
return $this->setKey('local', $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set foreign key name
|
||||
* @param string $key key name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
* @throws LazerException First you must define tables name
|
||||
*/
|
||||
public function foreignKey($key)
|
||||
{
|
||||
return $this->setKey('foreign', $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set relation one2many to table
|
||||
* @param string $table Table name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
*/
|
||||
public function belongsTo($table)
|
||||
{
|
||||
$this->setTable('foreign', $table);
|
||||
$this->setRelationType(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set relation many2one to table
|
||||
* @param string $table Table name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
*/
|
||||
public function hasMany($table)
|
||||
{
|
||||
$this->setTable('foreign', $table);
|
||||
$this->setRelationType(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set relation many2many to table
|
||||
* @param string $table Table name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
*/
|
||||
public function hasAndBelongsToMany($table)
|
||||
{
|
||||
$this->setTable('foreign', $table);
|
||||
$this->setRelationType(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use relation to table
|
||||
* @param string $table Table name
|
||||
* @return \Lazer\Classes\Core_Relation
|
||||
*/
|
||||
public function with($table)
|
||||
{
|
||||
Validate::relation($this->tables['local'], $table);
|
||||
$this->setTable('foreign', $table);
|
||||
$this->setRelationType(Config::table($this->tables['local'])->relations($this->tables['foreign'])->type);
|
||||
$this->setKey('local', Config::table($this->tables['local'])->relations($this->tables['foreign'])->keys->local);
|
||||
$this->setKey('foreign', Config::table($this->tables['local'])->relations($this->tables['foreign'])->keys->foreign);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set specified relation
|
||||
* @throws LazerException Tables names or keys missing
|
||||
*/
|
||||
public function setRelation()
|
||||
{
|
||||
if (!in_array(null, $this->tables) && !in_array(null, $this->keys))
|
||||
{
|
||||
$this->addRelation();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LazerException('Tables names or keys missing');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relation information
|
||||
* @return array relation information
|
||||
*/
|
||||
public function getRelation()
|
||||
{
|
||||
return array(
|
||||
'tables' => $this->tables,
|
||||
'keys' => $this->keys,
|
||||
'type' => $this->relationType
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove relation
|
||||
*/
|
||||
public function removeRelation()
|
||||
{
|
||||
if ($this->relationType == 'hasAndBelongsToMany')
|
||||
{
|
||||
$junction = $this->getJunction();
|
||||
|
||||
$this->deleteRelationData($junction, $this->tables['local']);
|
||||
$this->deleteRelationData($junction, $this->tables['foreign']);
|
||||
}
|
||||
$this->deleteRelationData($this->tables['local'], $this->tables['foreign']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to configs and create all necessary files
|
||||
*/
|
||||
protected function addRelation()
|
||||
{
|
||||
if ($this->relationType == 'hasAndBelongsToMany')
|
||||
{
|
||||
$junction = $this->getJunction();
|
||||
|
||||
try
|
||||
{
|
||||
Validate::table($junction)->exists();
|
||||
}
|
||||
catch (LazerException $e)
|
||||
{
|
||||
Database::create($junction, array(
|
||||
$this->tables['local'] . '_id' => 'integer',
|
||||
$this->tables['foreign'] . '_id' => 'integer',
|
||||
));
|
||||
|
||||
$this->insertRelationData($junction, $this->tables['local'], 'hasMany', array(
|
||||
'local' => $this->tables['local'] . '_id',
|
||||
'foreign' => $this->keys['local']
|
||||
));
|
||||
|
||||
$this->insertRelationData($junction, $this->tables['foreign'], 'hasMany', array(
|
||||
'local' => $this->tables['foreign'] . '_id',
|
||||
'foreign' => $this->keys['foreign']
|
||||
));
|
||||
}
|
||||
}
|
||||
$this->insertRelationData($this->tables['local'], $this->tables['foreign'], $this->relationType, $this->keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts relation data to config file
|
||||
* @param string $from Local table
|
||||
* @param string $to Related table
|
||||
* @param string $type Relation type
|
||||
* @param array $keys Relationed keys
|
||||
*/
|
||||
protected function insertRelationData($from, $to, $type, array $keys)
|
||||
{
|
||||
$config = Config::table($from);
|
||||
$content = $config->get();
|
||||
$content->relations->{$to} = array(
|
||||
'type' => $type,
|
||||
'keys' => $keys,
|
||||
);
|
||||
$config->put($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts relation data to config file
|
||||
* @param string $from Local table
|
||||
* @param string $to Related table
|
||||
*/
|
||||
protected function deleteRelationData($from, $to)
|
||||
{
|
||||
$config = Config::table($from);
|
||||
$content = $config->get();
|
||||
unset($content->relations->{$to});
|
||||
$config->put($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process query with joined data
|
||||
* @param object $row One row of data
|
||||
* @return Database
|
||||
*/
|
||||
protected function join($row)
|
||||
{
|
||||
$keys['local'] = $this->keys['local'];
|
||||
$keys['foreign'] = $this->keys['foreign'];
|
||||
|
||||
if ($this->relationType == 'hasAndBelongsToMany')
|
||||
{
|
||||
$join = Database::table($this->getJunction())
|
||||
->groupBy($this->tables['local'] . '_id')
|
||||
->where($this->tables['local'] . '_id', '=', $row->{$keys['local']})
|
||||
->findAll()
|
||||
->asArray(null, $this->tables['foreign'] . '_id');
|
||||
|
||||
|
||||
if (empty($join))
|
||||
return array();
|
||||
|
||||
return Database::table($this->tables['foreign'])
|
||||
->where($keys['foreign'], 'IN', $join[$row->{$keys['local']}]);
|
||||
}
|
||||
|
||||
return Database::table($this->tables['foreign'])
|
||||
->where($keys['foreign'], '=', $row->{$keys['local']});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $part
|
||||
* @return array
|
||||
*/
|
||||
public function build(array $array, $part)
|
||||
{
|
||||
$return = array();
|
||||
foreach ($array as $key => $row)
|
||||
{
|
||||
if (is_object($row))
|
||||
{
|
||||
if ($row instanceof \stdClass)
|
||||
{
|
||||
$part = ucfirst($part);
|
||||
|
||||
if (!isset($row->{$part}))
|
||||
{
|
||||
$query = $this->join($row);
|
||||
|
||||
if ($this->relationType == 'belongsTo')
|
||||
{
|
||||
$query = $query->findAll();
|
||||
$query = reset($query)[0];
|
||||
}
|
||||
|
||||
$row->{$part} = $query;
|
||||
}
|
||||
|
||||
$array[$key] = $row->{$part};
|
||||
$return[] = $row->{$part};
|
||||
}
|
||||
else
|
||||
{
|
||||
$row->with($part);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$return = array_merge($return, $this->build($row, $part));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relations types
|
||||
* @return array
|
||||
*/
|
||||
public static function relations()
|
||||
{
|
||||
return self::$relations;
|
||||
}
|
||||
|
||||
}
|
9
ready2use/srv/php/Libs/Lazer/Classes/Database.php
Executable file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes;
|
||||
|
||||
include "Core/Database.php";
|
||||
|
||||
class Database extends Core_Database {
|
||||
|
||||
}
|
91
ready2use/srv/php/Libs/Lazer/Classes/Helpers/Config.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes\Helpers;
|
||||
|
||||
/**
|
||||
* Config managing class
|
||||
*
|
||||
* @category Helpers
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
class Config extends File {
|
||||
|
||||
/**
|
||||
* Get key from returned config
|
||||
* @param string $field key
|
||||
* @param bool $assoc
|
||||
* @return mixed
|
||||
*/
|
||||
public function getKey($field, $assoc = false)
|
||||
{
|
||||
return $assoc ? $this->get($assoc)[$field] : $this->get($assoc)->{$field};
|
||||
}
|
||||
|
||||
public static function table($name)
|
||||
{
|
||||
$file = new Config;
|
||||
$file->name = $name;
|
||||
$file->setType('config');
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array with names of fields
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
return array_keys($this->getKey('schema', true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return relations configure
|
||||
* @param mixed $tableName null-all tables;array-few tables;string-one table relation informations
|
||||
* @param boolean $assoc Object or associative array
|
||||
* @return array|object
|
||||
*/
|
||||
public function relations($tableName = null, $assoc = false)
|
||||
{
|
||||
if (is_array($tableName))
|
||||
{
|
||||
$relations = $this->getKey('relations', $assoc);
|
||||
if ($assoc)
|
||||
{
|
||||
return array_intersect_key($relations, array_flip($tableName));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (object) array_intersect_key((array) $relations, array_flip($tableName));
|
||||
}
|
||||
}
|
||||
elseif ($tableName !== null)
|
||||
{
|
||||
return $assoc ? $this->getKey('relations', $assoc)[$tableName] : $this->getKey('relations', $assoc)->{$tableName};
|
||||
}
|
||||
|
||||
return $this->getKey('relations', $assoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning assoc array with types of fields
|
||||
* @return array
|
||||
*/
|
||||
public function schema()
|
||||
{
|
||||
return $this->getKey('schema', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning last ID from table
|
||||
* @return integer
|
||||
*/
|
||||
public function lastId()
|
||||
{
|
||||
return $this->getKey('last_id');
|
||||
}
|
||||
|
||||
}
|
27
ready2use/srv/php/Libs/Lazer/Classes/Helpers/Data.php
Executable file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes\Helpers;
|
||||
|
||||
include "File.class.php";
|
||||
|
||||
/**
|
||||
* Data managing class
|
||||
*
|
||||
* @category Helpers
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
class Data extends File {
|
||||
|
||||
public static function table($name)
|
||||
{
|
||||
$file = new Data;
|
||||
$file->name = $name;
|
||||
$file->setType('data');
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
}
|
88
ready2use/srv/php/Libs/Lazer/Classes/Helpers/File.class.php
Executable file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes\Helpers;
|
||||
include "FileInterface.php";
|
||||
use Lazer\Classes\LazerException;
|
||||
|
||||
/**
|
||||
* File managing class
|
||||
*
|
||||
* @category Helpers
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
class File implements FileInterface {
|
||||
|
||||
/**
|
||||
* File name
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* File type (data|config)
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
public static function table($name)
|
||||
{
|
||||
$file = new File;
|
||||
$file->name = $name;
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public final function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public final function getPath()
|
||||
{
|
||||
if (!defined('LAZER_DATA_PATH'))
|
||||
{
|
||||
throw new LazerException('Please define constant LAZER_DATA_PATH (check README.md)');
|
||||
}
|
||||
else if (!empty($this->type))
|
||||
{
|
||||
return LAZER_DATA_PATH . $this->name . '.' . $this->type . '.json';
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LazerException('Please specify the type of file in class: ' . __CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
public final function get($assoc = false)
|
||||
{
|
||||
return json_decode(file_get_contents($this->getPath()), $assoc);
|
||||
}
|
||||
|
||||
public final function put($data)
|
||||
{
|
||||
return file_put_contents($this->getPath(), json_encode($data));
|
||||
}
|
||||
|
||||
public final function exists()
|
||||
{
|
||||
return file_exists($this->getPath());
|
||||
}
|
||||
|
||||
public final function remove()
|
||||
{
|
||||
$type = ucfirst($this->type);
|
||||
if ($this->exists())
|
||||
{
|
||||
if (unlink($this->getPath()))
|
||||
return TRUE;
|
||||
|
||||
throw new LazerException($type . ': Deleting failed');
|
||||
}
|
||||
|
||||
throw new LazerException($type . ': File does not exists');
|
||||
}
|
||||
|
||||
}
|
55
ready2use/srv/php/Libs/Lazer/Classes/Helpers/FileInterface.php
Executable file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes\Helpers;
|
||||
|
||||
use Lazer\Classes\LazerException;
|
||||
|
||||
interface FileInterface {
|
||||
|
||||
/**
|
||||
* Setting name of table
|
||||
* @param string $name
|
||||
* @return File
|
||||
*/
|
||||
public static function table($name);
|
||||
|
||||
/**
|
||||
* Set the file type
|
||||
* @param string $type File type (data|config)
|
||||
*/
|
||||
public function setType($type);
|
||||
|
||||
/**
|
||||
* Returning path to file
|
||||
* @return string Path to file
|
||||
* @throws LazerException You must specify the type of file
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Return decoded JSON
|
||||
* @param boolean $assoc Returns object if false; array if true
|
||||
* @return mixed (object|array)
|
||||
*/
|
||||
public function get($assoc = false);
|
||||
|
||||
/**
|
||||
* Saving encoded JSON to file
|
||||
* @param object|array $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function put($data);
|
||||
|
||||
/**
|
||||
* Checking that file exists
|
||||
* @return boolean
|
||||
*/
|
||||
public function exists();
|
||||
|
||||
/**
|
||||
* Removing file
|
||||
* @return boolean
|
||||
* @throws LazerException If file doesn't exists or there's problems with deleting files
|
||||
*/
|
||||
public function remove();
|
||||
}
|
207
ready2use/srv/php/Libs/Lazer/Classes/Helpers/Validate.php
Executable file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes\Helpers;
|
||||
|
||||
use Lazer\Classes\LazerException;
|
||||
use Lazer\Classes\Relation;
|
||||
|
||||
/**
|
||||
* Validation for tables
|
||||
*
|
||||
* @category Helpers
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
* @license http://opensource.org/licenses/MIT The MIT License
|
||||
* @link https://github.com/Greg0/Lazer-Database GitHub Repository
|
||||
*/
|
||||
class Validate {
|
||||
|
||||
/**
|
||||
* Name of table
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
* @param string $name
|
||||
* @return Validate
|
||||
*/
|
||||
public static function table($name)
|
||||
{
|
||||
$validate = new Validate();
|
||||
$validate->name = $name;
|
||||
return $validate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that field type is numeric
|
||||
* @param string $type
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isNumeric($type)
|
||||
{
|
||||
$defined = array('integer', 'double');
|
||||
|
||||
if (in_array($type, $defined))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that types from array matching with [boolean, integer, string, double]
|
||||
* @param array $types Indexed array
|
||||
* @return bool
|
||||
* @throws LazerException
|
||||
*/
|
||||
public static function types(array $types)
|
||||
{
|
||||
$defined = array('boolean', 'integer', 'string', 'double');
|
||||
$diff = array_diff($types, $defined);
|
||||
|
||||
if (empty($diff))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
throw new LazerException('Wrong types: "' . implode(', ', $diff) . '". Available "boolean, integer, string, double"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete ID field from arrays
|
||||
* @param array $fields
|
||||
* @return array Fields without ID
|
||||
*/
|
||||
public static function filter(array $fields)
|
||||
{
|
||||
if (array_values($fields) === $fields)
|
||||
{
|
||||
if (($key = array_search('id', $fields)) !== false)
|
||||
{
|
||||
unset($fields[$key]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($fields['id']);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change keys and values case to lower
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
public static function arrToLower(array $array)
|
||||
{
|
||||
$array = array_change_key_case($array);
|
||||
$array = array_map('strtolower', $array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that typed fields really exist in table
|
||||
* @param array $fields Indexed array
|
||||
* @return boolean
|
||||
* @throws LazerException If field(s) does not exist
|
||||
*/
|
||||
public function fields(array $fields)
|
||||
{
|
||||
$fields = self::filter($fields);
|
||||
$diff = array_diff($fields, Config::table($this->name)->fields());
|
||||
|
||||
if (empty($diff))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
throw new LazerException('Field(s) "' . implode(', ', $diff) . '" does not exists in table "' . $this->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that typed field really exist in table
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
* @throws LazerException If field does not exist
|
||||
*/
|
||||
public function field($name)
|
||||
{
|
||||
if (in_array($name, Config::table($this->name)->fields()))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
throw new LazerException('Field ' . $name . ' does not exists in table "' . $this->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that Table and Config exists and throw exceptions if not
|
||||
* @return boolean
|
||||
* @throws LazerException
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
if (!Data::table($this->name)->exists())
|
||||
throw new LazerException('Table "' . $this->name . '" does not exists');
|
||||
|
||||
if (!Config::table($this->name)->exists())
|
||||
throw new LazerException('Config "' . $this->name . '" does not exists');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that typed field have correct type of value
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
* @throws LazerException If type is wrong
|
||||
*/
|
||||
public function type($name, $value)
|
||||
{
|
||||
$schema = Config::table($this->name)->schema();
|
||||
if (array_key_exists($name, $schema) && $schema[$name] == gettype($value))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
throw new LazerException('Wrong data type');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that relation between tables exists
|
||||
* @param string $local local table
|
||||
* @param string $foreign related table
|
||||
* @return bool relation exists
|
||||
* @throws LazerException
|
||||
*/
|
||||
public static function relation($local, $foreign)
|
||||
{
|
||||
$relations = Config::table($local)->relations();
|
||||
if (isset($relations->{$foreign}))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
throw new LazerException('Relation "' . $local . '" to "' . $foreign . '" doesn\'t exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking that relation type is correct
|
||||
* @param string $type
|
||||
* @return bool relation type
|
||||
* @throws LazerException Wrong relation type
|
||||
*/
|
||||
public static function relationType($type)
|
||||
{
|
||||
if (in_array($type, Relation::relations()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new LazerException('Wrong relation type');
|
||||
}
|
||||
|
||||
}
|
14
ready2use/srv/php/Libs/Lazer/Classes/LazerException.php
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes;
|
||||
|
||||
/**
|
||||
* Exception extend
|
||||
*
|
||||
* @category Exceptions
|
||||
* @author Grzegorz Kuźnik
|
||||
* @copyright (c) 2013, Grzegorz Kuźnik
|
||||
*/
|
||||
class LazerException extends \Exception {
|
||||
|
||||
}
|
9
ready2use/srv/php/Libs/Lazer/Classes/Relation.php
Executable file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Lazer\Classes;
|
||||
|
||||
include "Core/Relation.php";
|
||||
|
||||
class Relation extends Core_Relation {
|
||||
|
||||
}
|
0
ready2use/srv/php/Libs/Lazer/data/blank
Executable file
347
ready2use/srv/php/Libs/forceutf8/Encoding.php
Executable file
@ -0,0 +1,347 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2008 Sebastián Grignoli
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of copyright holders nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author "Sebastián Grignoli" <grignoli@gmail.com>
|
||||
* @package Encoding
|
||||
* @version 2.0
|
||||
* @link https://github.com/neitanod/forceutf8
|
||||
* @example https://github.com/neitanod/forceutf8
|
||||
* @license Revised BSD
|
||||
*/
|
||||
|
||||
namespace ForceUTF8;
|
||||
|
||||
class Encoding {
|
||||
|
||||
const ICONV_TRANSLIT = "TRANSLIT";
|
||||
const ICONV_IGNORE = "IGNORE";
|
||||
const WITHOUT_ICONV = "";
|
||||
|
||||
protected static $win1252ToUtf8 = array(
|
||||
128 => "\xe2\x82\xac",
|
||||
|
||||
130 => "\xe2\x80\x9a",
|
||||
131 => "\xc6\x92",
|
||||
132 => "\xe2\x80\x9e",
|
||||
133 => "\xe2\x80\xa6",
|
||||
134 => "\xe2\x80\xa0",
|
||||
135 => "\xe2\x80\xa1",
|
||||
136 => "\xcb\x86",
|
||||
137 => "\xe2\x80\xb0",
|
||||
138 => "\xc5\xa0",
|
||||
139 => "\xe2\x80\xb9",
|
||||
140 => "\xc5\x92",
|
||||
|
||||
142 => "\xc5\xbd",
|
||||
|
||||
|
||||
145 => "\xe2\x80\x98",
|
||||
146 => "\xe2\x80\x99",
|
||||
147 => "\xe2\x80\x9c",
|
||||
148 => "\xe2\x80\x9d",
|
||||
149 => "\xe2\x80\xa2",
|
||||
150 => "\xe2\x80\x93",
|
||||
151 => "\xe2\x80\x94",
|
||||
152 => "\xcb\x9c",
|
||||
153 => "\xe2\x84\xa2",
|
||||
154 => "\xc5\xa1",
|
||||
155 => "\xe2\x80\xba",
|
||||
156 => "\xc5\x93",
|
||||
|
||||
158 => "\xc5\xbe",
|
||||
159 => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $brokenUtf8ToUtf8 = array(
|
||||
"\xc2\x80" => "\xe2\x82\xac",
|
||||
|
||||
"\xc2\x82" => "\xe2\x80\x9a",
|
||||
"\xc2\x83" => "\xc6\x92",
|
||||
"\xc2\x84" => "\xe2\x80\x9e",
|
||||
"\xc2\x85" => "\xe2\x80\xa6",
|
||||
"\xc2\x86" => "\xe2\x80\xa0",
|
||||
"\xc2\x87" => "\xe2\x80\xa1",
|
||||
"\xc2\x88" => "\xcb\x86",
|
||||
"\xc2\x89" => "\xe2\x80\xb0",
|
||||
"\xc2\x8a" => "\xc5\xa0",
|
||||
"\xc2\x8b" => "\xe2\x80\xb9",
|
||||
"\xc2\x8c" => "\xc5\x92",
|
||||
|
||||
"\xc2\x8e" => "\xc5\xbd",
|
||||
|
||||
|
||||
"\xc2\x91" => "\xe2\x80\x98",
|
||||
"\xc2\x92" => "\xe2\x80\x99",
|
||||
"\xc2\x93" => "\xe2\x80\x9c",
|
||||
"\xc2\x94" => "\xe2\x80\x9d",
|
||||
"\xc2\x95" => "\xe2\x80\xa2",
|
||||
"\xc2\x96" => "\xe2\x80\x93",
|
||||
"\xc2\x97" => "\xe2\x80\x94",
|
||||
"\xc2\x98" => "\xcb\x9c",
|
||||
"\xc2\x99" => "\xe2\x84\xa2",
|
||||
"\xc2\x9a" => "\xc5\xa1",
|
||||
"\xc2\x9b" => "\xe2\x80\xba",
|
||||
"\xc2\x9c" => "\xc5\x93",
|
||||
|
||||
"\xc2\x9e" => "\xc5\xbe",
|
||||
"\xc2\x9f" => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $utf8ToWin1252 = array(
|
||||
"\xe2\x82\xac" => "\x80",
|
||||
|
||||
"\xe2\x80\x9a" => "\x82",
|
||||
"\xc6\x92" => "\x83",
|
||||
"\xe2\x80\x9e" => "\x84",
|
||||
"\xe2\x80\xa6" => "\x85",
|
||||
"\xe2\x80\xa0" => "\x86",
|
||||
"\xe2\x80\xa1" => "\x87",
|
||||
"\xcb\x86" => "\x88",
|
||||
"\xe2\x80\xb0" => "\x89",
|
||||
"\xc5\xa0" => "\x8a",
|
||||
"\xe2\x80\xb9" => "\x8b",
|
||||
"\xc5\x92" => "\x8c",
|
||||
|
||||
"\xc5\xbd" => "\x8e",
|
||||
|
||||
|
||||
"\xe2\x80\x98" => "\x91",
|
||||
"\xe2\x80\x99" => "\x92",
|
||||
"\xe2\x80\x9c" => "\x93",
|
||||
"\xe2\x80\x9d" => "\x94",
|
||||
"\xe2\x80\xa2" => "\x95",
|
||||
"\xe2\x80\x93" => "\x96",
|
||||
"\xe2\x80\x94" => "\x97",
|
||||
"\xcb\x9c" => "\x98",
|
||||
"\xe2\x84\xa2" => "\x99",
|
||||
"\xc5\xa1" => "\x9a",
|
||||
"\xe2\x80\xba" => "\x9b",
|
||||
"\xc5\x93" => "\x9c",
|
||||
|
||||
"\xc5\xbe" => "\x9e",
|
||||
"\xc5\xb8" => "\x9f"
|
||||
);
|
||||
|
||||
static function toUTF8($text){
|
||||
/**
|
||||
* Function \ForceUTF8\Encoding::toUTF8
|
||||
*
|
||||
* This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
|
||||
*
|
||||
* It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
|
||||
*
|
||||
* It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
|
||||
*
|
||||
* 1) when any of these characters: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß
|
||||
* are followed by any of these: ("group B")
|
||||
* ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶•¸¹º»¼½¾¿
|
||||
* For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
|
||||
* The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
|
||||
* is also a valid unicode character, and will be left unchanged.
|
||||
*
|
||||
* 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
|
||||
* 3) when any of these: ðñòó are followed by THREE chars from group B.
|
||||
*
|
||||
* @name toUTF8
|
||||
* @param string $text Any string.
|
||||
* @return string The same string, UTF8 encoded
|
||||
*
|
||||
*/
|
||||
|
||||
if(is_array($text))
|
||||
{
|
||||
foreach($text as $k => $v)
|
||||
{
|
||||
$text[$k] = self::toUTF8($v);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
if(!is_string($text)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$max = self::strlen($text);
|
||||
|
||||
$buf = "";
|
||||
for($i = 0; $i < $max; $i++){
|
||||
$c1 = $text{$i};
|
||||
if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
|
||||
$c2 = $i+1 >= $max? "\x00" : $text{$i+1};
|
||||
$c3 = $i+2 >= $max? "\x00" : $text{$i+2};
|
||||
$c4 = $i+3 >= $max? "\x00" : $text{$i+3};
|
||||
if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2;
|
||||
$i++;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xe0" & $c1 <= "\xef"){ //looks like 3 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3;
|
||||
$i = $i + 2;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xf0" & $c1 <= "\xf7"){ //looks like 4 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3 . $c4;
|
||||
$i = $i + 3;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { //doesn't look like UTF8, but should be converted
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif(($c1 & "\xc0") == "\x80"){ // needs conversion
|
||||
if(isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
|
||||
$buf .= self::$win1252ToUtf8[ord($c1)];
|
||||
} else {
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { // it doesn't need conversion
|
||||
$buf .= $c1;
|
||||
}
|
||||
}
|
||||
return $buf;
|
||||
}
|
||||
|
||||
static function toWin1252($text, $option = self::WITHOUT_ICONV) {
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::toWin1252($v, $option);
|
||||
}
|
||||
return $text;
|
||||
} elseif(is_string($text)) {
|
||||
return static::utf8_decode($text, $option);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
static function toISO8859($text) {
|
||||
return self::toWin1252($text);
|
||||
}
|
||||
|
||||
static function toLatin1($text) {
|
||||
return self::toWin1252($text);
|
||||
}
|
||||
|
||||
static function fixUTF8($text, $option = self::WITHOUT_ICONV){
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::fixUTF8($v, $option);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
$last = "";
|
||||
while($last <> $text){
|
||||
$last = $text;
|
||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
||||
}
|
||||
$text = self::toUTF8(static::utf8_decode($text, $option));
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function UTF8FixWin1252Chars($text){
|
||||
// If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
|
||||
// (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
|
||||
// See: http://en.wikipedia.org/wiki/Windows-1252
|
||||
|
||||
return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
|
||||
}
|
||||
|
||||
static function removeBOM($str=""){
|
||||
if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
|
||||
$str=substr($str, 3);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
protected static function strlen($text){
|
||||
return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload')) & 2) ?
|
||||
mb_strlen($text,'8bit') : strlen($text);
|
||||
}
|
||||
|
||||
public static function normalizeEncoding($encodingLabel)
|
||||
{
|
||||
$encoding = strtoupper($encodingLabel);
|
||||
$encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
|
||||
$equivalences = array(
|
||||
'ISO88591' => 'ISO-8859-1',
|
||||
'ISO8859' => 'ISO-8859-1',
|
||||
'ISO' => 'ISO-8859-1',
|
||||
'LATIN1' => 'ISO-8859-1',
|
||||
'LATIN' => 'ISO-8859-1',
|
||||
'UTF8' => 'UTF-8',
|
||||
'UTF' => 'UTF-8',
|
||||
'WIN1252' => 'ISO-8859-1',
|
||||
'WINDOWS1252' => 'ISO-8859-1'
|
||||
);
|
||||
|
||||
if(empty($equivalences[$encoding])){
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
return $equivalences[$encoding];
|
||||
}
|
||||
|
||||
public static function encode($encodingLabel, $text)
|
||||
{
|
||||
$encodingLabel = self::normalizeEncoding($encodingLabel);
|
||||
if($encodingLabel == 'ISO-8859-1') return self::toLatin1($text);
|
||||
return self::toUTF8($text);
|
||||
}
|
||||
|
||||
protected static function utf8_decode($text, $option)
|
||||
{
|
||||
if ($option == self::WITHOUT_ICONV || !function_exists('iconv')) {
|
||||
$o = utf8_decode(
|
||||
str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))
|
||||
);
|
||||
} else {
|
||||
$o = iconv("UTF-8", "Windows-1252" . ($option == self::ICONV_TRANSLIT ? '//TRANSLIT' : ($option == self::ICONV_IGNORE ? '//IGNORE' : '')), $text);
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
}
|
BIN
ready2use/srv/php/Libs/php-bittorrent.phar
Normal file
2
ready2use/srv/php/Libs/torrent-rw/.gitignore
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
.idea
|
||||
.php_cs.cache
|
36
ready2use/srv/php/Libs/torrent-rw/.php_cs.dist
Executable file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
$config = PhpCsFixer\Config::create()
|
||||
->setUsingCache(false)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@Symfony' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'phpdoc_align' => true,
|
||||
'phpdoc_indent' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'phpdoc_separation' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
'concat_space' => ["spacing" => "one"],
|
||||
'align_multiline_comment' => ['comment_type' => 'phpdocs_like'],
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'binary_operator_spaces' => ['default' => 'align'],
|
||||
'cast_spaces' => ['space' => 'single'],
|
||||
'combine_consecutive_issets' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__)
|
||||
->exclude('vendor')
|
||||
->exclude('node_modules')
|
||||
->exclude('plugins')
|
||||
->notPath('adminer.php')
|
||||
)
|
||||
;
|
||||
|
||||
return $config;
|
674
ready2use/srv/php/Libs/torrent-rw/LICENSE
Executable file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
54
ready2use/srv/php/Libs/torrent-rw/README.md
Executable file
@ -0,0 +1,54 @@
|
||||
Torrent RW
|
||||
|
||||
PHP version 5.2+
|
||||
|
||||
1) Features:
|
||||
- Decode torrent file or data
|
||||
- Build torrent from source folder/file(s)
|
||||
- Silent Exception error system
|
||||
|
||||
2) Usage example
|
||||
```php
|
||||
require_once 'Torrent.php';
|
||||
|
||||
// get torrent infos
|
||||
$torrent = new Torrent( './test.torrent' );
|
||||
echo '<br>private: ', $torrent->is_private() ? 'yes' : 'no',
|
||||
'<br>annonce: ', $torrent->announce(),
|
||||
'<br>name: ', $torrent->name(),
|
||||
'<br>comment: ', $torrent->comment(),
|
||||
'<br>piece_length: ', $torrent->piece_length(),
|
||||
'<br>size: ', $torrent->size( 2 ),
|
||||
'<br>hash info: ', $torrent->hash_info(),
|
||||
'<br>stats: ';
|
||||
var_dump( $torrent->scrape() );
|
||||
echo '<br>content: ';
|
||||
var_dump( $torrent->content() );
|
||||
echo '<br>source: ',
|
||||
$torrent;
|
||||
|
||||
// get magnet link
|
||||
$torrent->magnet(); // use $torrent->magnet( false ); to get non html encoded ampersand
|
||||
|
||||
// create torrent
|
||||
$torrent = new Torrent( array( 'test.mp3', 'test.jpg' ), 'http://torrent.tracker/annonce' );
|
||||
$torrent->save('test.torrent'); // save to disk
|
||||
|
||||
// modify torrent
|
||||
$torrent->announce('http://alternate-torrent.tracker/annonce'); // add a tracker
|
||||
$torrent->announce(false); // reset announce trackers
|
||||
$torrent->announce(array('http://torrent.tracker/annonce', 'http://alternate-torrent.tracker/annonce')); // set tracker(s), it also works with a 'one tracker' array...
|
||||
$torrent->announce(array(array('http://torrent.tracker/annonce', 'http://alternate-torrent.tracker/annonce'), 'http://another-torrent.tracker/annonce')); // set tiered trackers
|
||||
$torrent->comment('hello world');
|
||||
$torrent->name('test torrent');
|
||||
$torrent->is_private(true);
|
||||
$torrent->httpseeds('http://file-hosting.domain/path/'); // Bittornado implementation
|
||||
$torrent->url_list(array('http://file-hosting.domain/path/','http://another-file-hosting.domain/path/')); // GetRight implementation
|
||||
|
||||
// print errors
|
||||
if ( $errors = $torrent->errors() )
|
||||
var_dump( $errors );
|
||||
|
||||
// send to user
|
||||
$torrent->send();
|
||||
```
|
1132
ready2use/srv/php/Libs/torrent-rw/Torrent.php
Executable file
1
ready2use/srv/php/Libs/torrent-rw/_config.yml
Executable file
@ -0,0 +1 @@
|
||||
theme: jekyll-theme-slate
|
334
ready2use/srv/php/MapController.php
Normal file
@ -0,0 +1,334 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
__ ___ ______ __ ____
|
||||
/ |/ /___ _____ / ____/___ ____ / /__________ / / /__ _____
|
||||
/ /|_/ / __ `/ __ \ / / / __ \/ __ \/ __/ ___/ __ \/ / / _ \/ ___/
|
||||
/ / / / /_/ / /_/ / / /___/ /_/ / / / / /_/ / / /_/ / / / __/ /
|
||||
/_/ /_/\__,_/ .___/ \____/\____/_/ /_/\__/_/ \____/_/_/\___/_/
|
||||
/_/
|
||||
|
||||
-create a new map
|
||||
-change an old map
|
||||
-get map data
|
||||
-----------------
|
||||
-get tile values
|
||||
|
||||
*/
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
require_once "Utils/Constants.php";
|
||||
require_once "Imports/LazerImports.php";
|
||||
require_once 'Utils/Helpers.php';
|
||||
|
||||
require_once 'Models/Game/Coord.php';
|
||||
require_once 'Models/Game/Level.php';
|
||||
require_once 'Models/Game/Tile.php';
|
||||
|
||||
use \ForceUTF8\Encoding;
|
||||
|
||||
//Autoload usage https://stackoverflow.com/questions/16175023/php-include-class-in-other-class
|
||||
|
||||
use Lazer\Classes\Database as Lazer;
|
||||
defined('LAZER_DATA_PATH') or define('LAZER_DATA_PATH', realpath(dirname(__FILE__)).'/'.Constants::CONST_DB_FOLDER.'/');
|
||||
|
||||
|
||||
Class MapController {
|
||||
|
||||
/***************************
|
||||
* SAVING AND GETTIGNS DATA
|
||||
***************************/
|
||||
|
||||
function createLevel($level) {
|
||||
|
||||
$row = Lazer::table(Constants::CONST_TABLE_MAP);
|
||||
$row = $level ->fillRow($row);
|
||||
$row->save();
|
||||
}
|
||||
|
||||
function placePlayerFromTo($to_,$from_){
|
||||
|
||||
$row = Lazer::table(Constants::CONST_TABLE_MAP)->where('key', '=', $to_)->find();
|
||||
$level = Level::parseRow($row);
|
||||
|
||||
//get the future player coordonates
|
||||
$coord = $level -> placePlayerForKey($from_);
|
||||
|
||||
//return Coord
|
||||
return $coord;
|
||||
}
|
||||
|
||||
function getAllTiles(){
|
||||
return Tile::getAllTiles();
|
||||
}
|
||||
|
||||
/**************************
|
||||
* MAP PROCEDURAL GENERATION
|
||||
*************************/
|
||||
|
||||
function generateWorld(){
|
||||
|
||||
//importnat VARS
|
||||
$gridData;
|
||||
$gridWidth = 2;
|
||||
$gridHeight = 2;
|
||||
|
||||
$levelToPlace;
|
||||
$levelNumMax;
|
||||
$levelWidthMax;
|
||||
$levelHeightMax;
|
||||
|
||||
//1. generate the dungeon grid
|
||||
$gridData = $this->fillgrid(null, $gridWidth, $gridHeight);
|
||||
|
||||
$levelToPlace = array();
|
||||
|
||||
array_push($levelToPlace, new Level(Constants::CONST_MAP_ALPHA_NAME, 15, 13, true, true));
|
||||
array_push($levelToPlace, new Level("request", 15, 13, true, false) );
|
||||
array_push($levelToPlace, new Level("conspi", 15, 13, true, false) );
|
||||
array_push($levelToPlace, new Level("art", 15, 13, true, false) );
|
||||
|
||||
array_push($levelToPlace, new Level("lulz", 15, 13, true, true) );
|
||||
/*
|
||||
$size = Level::getDim(26);
|
||||
array_push($levelToPlace, new Level("tripletrap", $size->x, $size->y, true));
|
||||
$size = Level::getDim(26);
|
||||
array_push($levelToPlace, new Level("pol", $size->x, $size->y, true) );
|
||||
$size = Level::getDim(26);
|
||||
array_push($levelToPlace, new Level("senpai", $size->x, $size->y, true));
|
||||
$size = Level::getDim(26);
|
||||
array_push($levelToPlace, new Level("varg", $size->x, $size->y, true) );
|
||||
$size = Level::getDim(26);
|
||||
array_push($levelToPlace, new Level("crypto", $size->x, $size->y, true) );*/
|
||||
|
||||
//2. place the main level on this grid
|
||||
/*
|
||||
foreach ($levelToPlace as $lvl){
|
||||
$coord = $this->pickPointFromGrid($gridData , $gridWidth, $gridHeight );
|
||||
if(isset($coord)){
|
||||
$gridData = $this->placeToGrid($gridData, $lvl, $gridWidth, $gridHeight, $coord );
|
||||
$lvl -> x = $coord-> x;
|
||||
$lvl -> y = $coord-> y;
|
||||
}
|
||||
}*/
|
||||
|
||||
//Genrate room for missing points
|
||||
/*
|
||||
$emptyCoord = $this->getCoordsFor($gridData, NULL, $gridWidth, $gridHeight);
|
||||
|
||||
for($l = 0; $l < count($levelToPlace); $l++){
|
||||
$index = rand(0, count($emptyCoord)-1 );
|
||||
$coord = $emptyCoord[$index];
|
||||
$level = new Level("???", rand(2,7), rand(2,7), false );
|
||||
$gridData = $this->placeToGrid($gridData, $level , $gridWidth, $gridHeight, $coord);
|
||||
array_splice($emptyCoord, $index, 1);
|
||||
$level-> x = $coord-> x;
|
||||
$level-> y = $coord-> y;
|
||||
if(count($emptyCoord) < 1) break;
|
||||
}*/
|
||||
|
||||
$this->displayGrid($gridData, $gridWidth, $gridHeight, true);
|
||||
|
||||
|
||||
//3. each level need to have at least 1 door
|
||||
/*
|
||||
$allLevels = $this->getAllLevels($gridData);
|
||||
foreach ($allLevels as $lvl){
|
||||
|
||||
$dir = 0;
|
||||
$numDoors = rand(1,2);
|
||||
|
||||
for( $dir; $dir < 3; $dir ++ ){
|
||||
|
||||
//CAUTION level found are the door on the other direction!!!
|
||||
|
||||
$levelFound = null;
|
||||
$oppDir;
|
||||
$coord = new Coord($lvl-> x, $lvl-> y);
|
||||
|
||||
//South
|
||||
if($dir == 2 ){
|
||||
|
||||
$levelFound = $this->getLevelForDir($gridData, $gridWidth, $gridHeight, $coord,$dir);
|
||||
if(isset( $levelFound->door_key_N )) $levelFound = null;
|
||||
$oppDir = 0;
|
||||
|
||||
}
|
||||
|
||||
//West
|
||||
if($dir == 3 ){
|
||||
|
||||
$levelFound = $this->getLevelForDir($gridData, $gridWidth, $gridHeight, $coord,$dir);
|
||||
if(isset( $levelFound->door_key_E )) $levelFound = null;
|
||||
$oppDir = 1;
|
||||
|
||||
}
|
||||
|
||||
//North
|
||||
if($dir == 0){
|
||||
|
||||
$levelFound = $this->getLevelForDir($gridData, $gridWidth, $gridHeight, $coord,$dir);
|
||||
if(isset( $levelFound->door_key_S )) $levelFound = null;
|
||||
$oppDir = 2;
|
||||
|
||||
}
|
||||
|
||||
//East
|
||||
if($dir == 1 ){
|
||||
|
||||
$levelFound = $this->getLevelForDir($gridData, $gridWidth, $gridHeight, $coord,$dir);
|
||||
if(isset( $levelFound->door_key_W )) $levelFound = null;
|
||||
$oppDir = 3;
|
||||
|
||||
}
|
||||
|
||||
if( isset($levelFound) && $numDoors > 0){
|
||||
$levelFound -> setKeyForDir($lvl->key, $oppDir);
|
||||
$lvl-> setKeyForDir($levelFound->key, $dir);
|
||||
$numDoors --;
|
||||
}
|
||||
}
|
||||
|
||||
//echo $lvl->name." has ".$lvl->getNumDoors()." doors<br/>";
|
||||
|
||||
}*/
|
||||
|
||||
//Get the level
|
||||
foreach ($levelToPlace as $lvl){
|
||||
$lvl -> initLevelData();
|
||||
$this->createLevel($lvl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****************************
|
||||
* UTILS for PROCEDURAL
|
||||
* Generation
|
||||
****************************/
|
||||
|
||||
function fillgrid($defaultTile_, $width_, $height_){
|
||||
|
||||
$newGrid = array();
|
||||
for ($i = 0; $i < ($height_*$width_); $i++) {
|
||||
array_push($newGrid,$defaultTile_);
|
||||
}
|
||||
|
||||
return $newGrid;
|
||||
}
|
||||
|
||||
function pickPointFromGrid($gridData, $width_, $height_ ){
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
|
||||
$x = rand ( 0 , $width_-1);
|
||||
$y = rand ( 0 , $height_-1);
|
||||
|
||||
//is grid coordonate occupped?
|
||||
$val = $gridData[ ($y*$height_) + $x];
|
||||
if( !isset($val)) return new Coord($x, $y);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function placeToGrid($gridData, $data, $width_, $height_, $coord){
|
||||
$gridData[ ( $coord->y *$width_) + $coord->x] = $data;
|
||||
return $gridData;
|
||||
}
|
||||
|
||||
function getLevelForCoord($gridData_, $coord_, $width_, $height_){
|
||||
return $gridData_[ ( $coord_->y *$width_) + $coord_->x];
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCoordsFor($gridData, $data, $width_, $height_){
|
||||
$listData = array();
|
||||
|
||||
for ($y = 0; $y < $height_; $y++) {
|
||||
|
||||
for ($x = 0; $x < $width_; $x++) {
|
||||
if( $gridData[ ($y*$width_) + $x] == $data) array_push($listData, new Coord($x, $y));
|
||||
}
|
||||
|
||||
}
|
||||
return $listData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the levels from the griddata
|
||||
* Return Level[] array;
|
||||
*/
|
||||
function getAllLevels($gridData){
|
||||
$levels = array();
|
||||
foreach ($gridData as $lvl){
|
||||
if(isset($lvl)) array_push($levels,$lvl);
|
||||
}
|
||||
return $levels;
|
||||
}
|
||||
|
||||
function displayGrid($gridData_, $width_, $height_, $is_null){
|
||||
|
||||
for ($y = 0; $y < $height_; $y++) {
|
||||
|
||||
for ($x = 0; $x < $width_; $x++) {
|
||||
if( !isset($gridData_[($y*$width_) + $x]) || !isset($gridData_[ ($y*$width_) + $x] -> name)){
|
||||
echo ".";
|
||||
} else {
|
||||
$name = $gridData_[ ($y*$width_) + $x] -> name;
|
||||
echo substr($name,0,1);
|
||||
}
|
||||
}
|
||||
|
||||
echo "<br/>";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getLevelForDir($gridData_, $width_, $height_, $coord_,$dir_){
|
||||
|
||||
switch($dir_){
|
||||
|
||||
case 0:
|
||||
for ($y = $coord_->y -1; $y >= 0; $y--) {
|
||||
$coord = new Coord( $coord_->x,$y);
|
||||
$level = $this->getLevelForCoord($gridData_, $coord, $width_, $height_);
|
||||
if(isset($level)) return $level;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
for ($x = $coord_->x +1; $x < $width_; $x++) {
|
||||
$coord = new Coord( $x,$coord_->y);
|
||||
$level = $this->getLevelForCoord($gridData_, $coord, $width_, $height_);
|
||||
if(isset($level)){
|
||||
return $level;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
for ($y = $coord_->y +1; $y < $height_; $y++) {
|
||||
$coord = new Coord( $coord_->x,$y);
|
||||
$level = $this->getLevelForCoord($gridData_, $coord, $width_, $height_);
|
||||
if(isset($level)) return $level;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
for ($x = $coord_->x -1; $x >= 0; $x--) {
|
||||
$coord = new Coord( $x,$coord_->y);
|
||||
$level = $this->getLevelForCoord($gridData_, $coord, $width_, $height_);
|
||||
if(isset($level)) return $level;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
24
ready2use/srv/php/Models/FakeFile.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?
|
||||
require_once 'Utils/Helpers.php';
|
||||
|
||||
class FakeFile {
|
||||
/*
|
||||
'id' => 'integer',
|
||||
'id_post' => 'integer',
|
||||
'thread_key' => 'string',
|
||||
'fake_path' => 'string',
|
||||
'fake_name' => 'string',
|
||||
'file_name' => 'string'*/
|
||||
|
||||
function __construct($file_path_, $file_ext_, $map_key ) {
|
||||
|
||||
$name = uniqid();
|
||||
$this ->fake_name = $name.'.'.$file_ext_;
|
||||
$this ->file_name = Helpers::getRealFileName($this ->fake_name).'.'.$file_ext_;
|
||||
//$this ->fake_path = $file_path_."img/".$map_key."_". $this ->file_name;
|
||||
$this ->fake_path = $file_path_."php/uploads/".$map_key."/".Helpers::getRealFileName($this ->fake_name).'.'.$file_ext_;
|
||||
$this ->map_key = $map_key;
|
||||
|
||||
}
|
||||
|
||||
}
|
13
ready2use/srv/php/Models/Game/Coord.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class Coord{
|
||||
public $x;
|
||||
public $y;
|
||||
|
||||
function __construct($x, $y ) {
|
||||
$this-> x = $x;
|
||||
$this-> y = $y;
|
||||
}
|
||||
|
||||
|
||||
}
|
15
ready2use/srv/php/Models/Game/GameData.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?
|
||||
|
||||
class GameData {
|
||||
|
||||
public $player;
|
||||
public $players;
|
||||
public $posts;
|
||||
public $itemsPlayer;
|
||||
public $itemsMap;
|
||||
|
||||
function __construct() {
|
||||
|
||||
}
|
||||
|
||||
}
|
106
ready2use/srv/php/Models/Game/Items.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?
|
||||
|
||||
class Item {
|
||||
|
||||
public $name;
|
||||
public $description;
|
||||
public $player_id; // owner ID
|
||||
public $map_key;
|
||||
public $key;
|
||||
|
||||
public $action;
|
||||
public $type;
|
||||
public $itemsPerPlayer;
|
||||
//weapon
|
||||
//potion
|
||||
//paint
|
||||
//sponge
|
||||
//ring
|
||||
//armor
|
||||
|
||||
//Influence it has
|
||||
public $is_expendable = true;
|
||||
public $numOfUse;
|
||||
public $value;
|
||||
//----------------
|
||||
public $valueMin;
|
||||
public $valueMax;
|
||||
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
public static function getAllPotentialItems()
|
||||
{
|
||||
$items = array();
|
||||
|
||||
$item = new Item();
|
||||
$item-> name = "sponge";
|
||||
$item-> action = "post delete";
|
||||
$item-> type = "posting";
|
||||
$item-> description = "The sponge give you the ability to make disappear a post that isn't canon";
|
||||
$item-> is_expendable = true;
|
||||
$item-> valueMin = 1;
|
||||
$item-> valueMax = 3;
|
||||
$item-> itemsPerPlayer = 1;
|
||||
array_push( $items ,$item);
|
||||
|
||||
/*
|
||||
$item = new Item();
|
||||
$item-> name = "ring of upload";
|
||||
$item-> action = "upload";
|
||||
$item-> type = "posting";
|
||||
$item-> description = "Give you the ability to upload picture when you post";
|
||||
$item-> is_expendable = false;
|
||||
$item-> valueMin = 10;
|
||||
$item-> valueMax = 18;
|
||||
$item-> itemsPerPlayer = 1;
|
||||
array_push( $items ,$item);
|
||||
|
||||
$item = new Item();
|
||||
$item-> name = "pen";
|
||||
$item-> action = "drawing";
|
||||
$item-> type = "posting";
|
||||
$item-> description = "Give you the ability to draw";
|
||||
$item-> is_expendable = true;
|
||||
$item-> valueMin = 1;
|
||||
$item-> valueMax = 10;
|
||||
$item-> itemsPerPlayer = 10;
|
||||
array_push( $items ,$item);
|
||||
|
||||
$item = new Item();
|
||||
$item-> name = "black powder";
|
||||
$item-> action = "canon";
|
||||
$item-> type = "posting";
|
||||
$item-> description = "Set a post as canon";
|
||||
$item-> is_expendable = true;
|
||||
$item-> valueMin = 1;
|
||||
$item-> valueMax = 5;
|
||||
$item-> itemsPerPlayer = 3;
|
||||
array_push( $items ,$item);
|
||||
|
||||
$item = new Item();
|
||||
$item-> name = "knife";
|
||||
$item-> action = "harm";
|
||||
$item-> type = "fight";
|
||||
$item-> description = "You can kill enemies from the dungeon or even other anons";
|
||||
$item-> is_expendable = true;
|
||||
$item-> valueMin = 99;
|
||||
$item-> valueMax = 100;
|
||||
$item-> itemsPerPlayer = 1;
|
||||
array_push( $items ,$item);
|
||||
|
||||
$item = new Item();
|
||||
$item-> name = "rope";
|
||||
$item-> action = "bound";
|
||||
$item-> type = "fight";
|
||||
$item-> description = "You bound certain enemies and anons";
|
||||
$item-> is_expendable = true;
|
||||
$item-> valueMin = 2;
|
||||
$item-> valueMax = 4;
|
||||
$item-> itemsPerPlayer = 1;
|
||||
array_push( $items ,$item);*/
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
362
ready2use/srv/php/Models/Game/Level.php
Normal file
@ -0,0 +1,362 @@
|
||||
<?php
|
||||
|
||||
class Level {
|
||||
|
||||
public $name;
|
||||
public $key;
|
||||
public $theme = "medieval";
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
|
||||
public $width;
|
||||
public $height;
|
||||
public $data;
|
||||
|
||||
public $door_key_n;
|
||||
public $door_key_e;
|
||||
public $door_key_s;
|
||||
public $door_key_w;
|
||||
|
||||
public $is_safe = false;
|
||||
public $is_chan = false;
|
||||
public $is_secret = false;
|
||||
|
||||
public $level_data;
|
||||
/*
|
||||
public $TILE_GROUND = 0;
|
||||
public $TILE_WALL = 1;
|
||||
public $TILE_WALL_DRAWABLE = 2;
|
||||
public $TILE_DOOR = 3;*/
|
||||
|