var port = 52533;

import Filter from 'badwords-ko';
var filter = new Filter();

import mysql, {} from 'mysql2';
var conn = mysql.createConnection({
	host: '127.0.0.1',
	user: 'web',
	password: '1q2w3e4r5t',
	database: 'test_nodam',
	port: 53306,
	multipleStatements: true,
});
conn.addListener('error', function (err){
	console.log(err);	
});

conn.query(`select word from fword where is_active = 1`, function (err_00, res_00){
	var arr_fword = [];
	_.each(res_00, function (v, i){
		arr_fword.push(v.word);
	});
	filter.addWords(...arr_fword);
});

import {createServer} from 'http';
import express from 'express';
import {Server} from 'socket.io';
var app = express();
var server = createServer(app);
var io = new Server(server, {
	cors: {
		origin: '*',
		methods: ['GET', 'POST'],
	}, 
	allowEIO3: true
});

import moment from 'moment';

server.listen(port, function (){
	console.log(port);
});

io.engine.on('connection_error', function (err){
	console.log(err);
});

import {faker} from '@faker-js/faker';
import * as _ from 'underscore';
var arr_trash = [];
var arr_trash_exclude = [
	// 나무
	{x: 4, y: 4},
	{x: 4, y: 14},
	{x: 14, y: 4},
	{x: 14, y: 14},
	// 호수
	{x: 9, y: 6},
	{x: 9, y: 7},
	{x: 6, y: 9},
	{x: 7, y: 9},
	{x: 11, y: 9},
	{x: 12, y: 9},
	{x: 9, y: 11},
	{x: 9, y: 12},
	{x: 8, y: 8},
	{x: 9, y: 8},
	{x: 10, y: 8},
	{x: 8, y: 9},
	{x: 9, y: 9},
	{x: 10, y: 9},
	{x: 8, y: 10},
	{x: 9, y: 10},
	{x: 10, y: 10},
];
var arr_sign = [
	{uid_us: -1, data: -1, comment: '', set_at: parseInt(moment.now() / 1000) - 300},
	{uid_us: -1, data: -1, comment: '', set_at: parseInt(moment.now() / 1000) - 300},
	{uid_us: -1, data: -1, comment: '', set_at: parseInt(moment.now() / 1000) - 300},
	{uid_us: -1, data: -1, comment: '', set_at: parseInt(moment.now() / 1000) - 300},
];

console.log(arr_sign);

function set_arr_trash(){
	do{
		if(arr_trash.length >= 50){
			break;
		}
		while(true){
			var trash = {
				x: faker.number.int({min: 1, max: 17}), 
				y: faker.number.int({min: 1, max: 17}), 
				//type: 1
				type: faker.number.int({min: 1, max: 4})
			};
			// 이미 쓰레기가 있는 곳들은 제외
			var is_in = _.find(arr_trash, function (v){
				return ((v.x == trash.x) && (v.y == trash.y));
			});
			// 사물이나 호수 등이 있는 곳들은 제외
			var is_exclude = _.find(arr_trash_exclude, function (v){
				return ((v.x == trash.x) && (v.y == trash.y));
			});
			// 둘 모두 해당사항이 없어야 쓰레기가 생성됨
			if((is_in == undefined) && (is_exclude == undefined)){
				arr_trash.push(trash);
				break;
			}
		}
	}while(true);
	console.log(`set_arr_trash\t${new Date()}`);
	/*
	var arr_trash_visual = [
		['■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ','■','■','■',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ','■','■','■','■','■','■','■',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ','■','■','■',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ','■',' ',' ',' ',' ',' ',' ',' ',' ',' ','■',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','■'],
		['■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■'],
	];
	for(var i = 0; i < arr_trash.length; i++){
		if(arr_trash[i].type > 0){
			var x = arr_trash[i].x;
			var y = arr_trash[i].y;
			arr_trash_visual[x][y] = '★';
		}
	}
	for(var i = 0; i < arr_trash_visual.length; i++){
		console.log(arr_trash_visual[i].join(' '));
	}
	*/
}
set_arr_trash()

// 쓰레기 자동 삭제 및 생성
setInterval(function (){
	arr_trash.shift();
	set_arr_trash();
}, 10000);

// 쓰레기 자동 삭제 및 생성
setInterval(function (){
	conn.query('select 1');
	console.log('database handshake');
}, 1800000);

var json_user = {};

io.on('connect', function (socket){
	console.log(`connect\t${socket.id}\t${socket.client.conn.server.clientsCount}`);
	console.log(`count\t${socket.client.conn.server.clientsCount}`);
	json_user[`${socket.id}`] = {
		socket_id: socket.id,
		uid_u: '',
		name: '',
		costume: 0, 
		head: 0, 
		hair: 0, 
		face: 0, 
		tong: 0, 
		glove: 0, 
		name: 0,
		pos_x: 0,
		pos_y: 0,
		pos_z: 0,
		rot_y: 0,
		level: 0,
		point: 0,
		process: 0,
	};

	socket.on('get_users', function (){
		console.log(`get_users\t${socket.id}`);
		var arr_user = [];
		for(var i in json_user){
			arr_user.push(json_user[i]);
		}
		io.to(socket.id).emit('get_users', arr_user);
	});

	/* DESC: 	현재 필드에 존재하는 표지판 상태를 모두 불러옴
	 *		접속할 때 get_users와 동일한 타이밍에 호출하면 됨
	 *		요청한 사람한테만 데이터 전송
	 * URL:		http://121.150.20.121:52533
	 * NAME:	get_signs
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|12
	 * 		|id		|string		|보낸 사람 소켓 id
	 * OUTPUT:	|code		|int		|12
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 표지판 배열
	 * 		|-uid_us	|string		|표지판 고유값
	 * 		|-data		|int		|표지판 그림
	 * 		|-comment	|string		|표지판 표제어
	 * 		|-set_at	|int		|표지판이 갱신된 timestamp(second)
	 */
	socket.on('get_signs', function (){
		console.log(`get_signs\t${socket.id}`);
		var res_json = {code: 12, id: socket.id, data: arr_sign, err: 0};
		io.to(socket.id).emit('get_signs', res_json);
	});

	/* DESC: 	공원에 있는 표지판에 직접 만든 표지판을 설치
	 *		단, 누군가가 이미 설치한지 30초가 지나지 않았다면 설치 불가
	 * URL:		http://121.150.20.121:52533
	 * NAME:	set_sign
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|11
	 * 		|data		|json		|
	 * 		|-index_sign	|int		|0~3, 대응하는 표지판 인덱스
	 * 		|-uid_us	|string		|표지판 고유값
	 * 		|-data		|int		|표지판 그림
	 * 		|-comment	|string		|표지판 표제어
	 * OUTPUT:	|code		|int		|11
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 표지판 배열
	 * 		|-uid_us	|string		|표지판 고유값
	 * 		|-data		|int		|표지판 그림
	 * 		|-comment	|string		|표지판 표제어
	 * 		|-set_at	|int		|표지판이 갱신된 timestamp(second)
	 * 		|err		|int		|0: 정상, 1~29: 숫자에 해당하는 초만큼 시간 남음
	 */
	socket.on('set_sign', function (data){
		console.log(`set_sign\t${socket.id}\t${JSON.stringify(data)}`);
		var res_json = {code: 11, id: socket.id, data: '', err: 0};
		var index_sign = data.data.index_sign;
		var uid_us = data.data.uid_us;
		var paint = data.data.data;
		var comment = data.data.comment;
		var ts_now = parseInt(moment.now() / 1000);
		var ts_remain = (ts_now - arr_sign[index_sign].set_at);
		if(ts_remain >= 30){
			arr_sign[index_sign].set_at = ts_now;
			arr_sign[index_sign].uid_us = uid_us;
			arr_sign[index_sign].data = paint;
			arr_sign[index_sign].comment = comment;
			res_json.data = arr_sign;
			console.log(res_json);
			io.emit('set_sign', res_json);
			return;
		}else{
			console.log('set sign failed');
			res_json.err = 1;
			console.log(res_json);
			io.to(socket.io).emit('set_sign', res_json);
			return;
		}
	});

	/* DESC: 	입력받은 텍스트에서 비속어를 선별하고 * 처리하고 반환
	 * URL:		http://121.150.20.121:52533
	 * NAME:	chat
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|0
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|name		|string		|보낸 사람 닉네임
	 * 		|data		|string		|채팅 내용
	 * OUTPUT:	|code		|int		|0
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|name		|string		|보낸 사람 닉네임
	 * 		|data		|string		|필터링된 채팅 내용
	 */
	socket.on('chat', function (data){
		console.log(`chat\t${socket.id}\t${JSON.stringify(data)}`);
		console.log(filter.clean(data.data));
		data.data = filter.clean(data.data);
		if(data){
			io.emit('chat', data);
		}
	});

	/* DESC: 	
	 * URL:		http://121.150.20.121:52533
	 * NAME:	move
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|1
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|pos		|json		|
	 *		|-x		|int		|x 좌표
	 *		|-y		|int		|y 좌표
	 *		|-z		|int		|z 좌표
	 * OUTPUT:	|code		|int		|1
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|json		|
	 * 		|-x		|int		|x 좌표
	 * 		|-y		|int		|y 좌표
	 * 		|-z		|int		|z 좌표
	 */
	socket.on('move', function (data){
		//socket.broadcast.emit('move', data);
		console.log(`move\t${socket.id}\t${JSON.stringify(data)}`);
		if(data){
			json_user[socket.id].pos_x = data.pos.x;
			json_user[socket.id].pos_y = data.pos.y;
			json_user[socket.id].pos_z = data.pos.z;
			socket.broadcast.emit('move', data);
		}
	});

	/* DESC: 	
	 * URL:		http://121.150.20.121:52533
	 * NAME:	rotate
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|6
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|int		|회전축 값, unity에서라면 기본적으로 y
	 * OUTPUT:	|code		|int		|6
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|int		|회전축 값, unity에서라면 기본적으로 y
	 */
	socket.on('rotate', function (data){
		console.log(`rotate\t${socket.id}\t${JSON.stringify(data)}`);
		if(data){
			json_user[socket.id].rot_y = data.data;
			socket.broadcast.emit('rotate', data);
		}
	});

	/* DESC: 	
	 * URL:		http://121.150.20.121:52533
	 * NAME:	jump
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|2
	 * 		|id		|string		|보낸 사람 소켓 id
	 * OUTPUT:	|code		|int		|2
	 * 		|id		|string		|보낸 사람 소켓 id
	 */
	socket.on('jump', function (data){
		//socket.broadcast.emit('jump', data);
		console.log(`jump\t${socket.id}\t${JSON.stringify(data)}`);
		if(data){
			socket.broadcast.emit('jump', data);
		}
	});

	/* DESC: 	요청한 사람에게만, 쓰레기 현황을 보냄(접속 직후라던지...)
	 * URL:		http://121.150.20.121:52533
	 * NAME:	get_trash
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|3
	 * 		|id		|string		|보낸 사람 소켓 id
	 * OUTPUT:	|code		|int		|3
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|
	 * 		|-x		|int		|x축 좌표
	 * 		|-y		|int		|y축 좌표
	 * 		|-type		|int		|쓰레기 종류, 0: 없음(오류), 1: 담배, 2 ...
	 */
	socket.on('get_trash', function (data){
		console.log(`get_trash\t${data}\t${JSON.stringify(data)}`);
		if(data){
			io.to(data.id).emit('get_trash', {code: 3, id: data.id, data: arr_trash});
		}
	});

	/* DESC: 	5초마다 자동으로 모든 클라이언트에게 쓰레기 현황을 뿌림
	 * URL:		http://121.150.20.121:52533
	 * NAME:	sync_trash
	 * METHOD:	SOCKET EMIT
	 *		|NAME		|TYPE		|DESC
	 * OUTPUT:	|code		|int		|4
	 * 		|data		|array json	|
	 * 		|-x		|int		|x축 좌표
	 * 		|-y		|int		|y축 좌표
	 * 		|-type		|int		|쓰레기 종류, 0: 없음(오류), 1: 담배, 2 ...
	 */
	var sync_trash = setInterval(function (){
		//io.to(users).emit('sync_trash', {code: 4, data: arr_trash});
		io.to(socket.id).emit('sync_trash', {code: 4, data: arr_trash});
	}, 5000);

	/* DESC: 	쓰레기를 주웠다면 해당 쓰레기는 삭제하고 새 쓰레기 생성
	 * URL:		http://121.150.20.121:52533
	 * NAME:	del_trash
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|5
	 * 		|x		|int		|x축 좌표
	 * 		|y		|int		|y축 좌표
	 * 		|type		|int		|쓰레기 종류, 0: 없음(오류), 1: 담배, 2 ...
	 * OUTPUT:	|code		|int		|5
	 * 		|data		|array json	|
	 * 		|-x		|int		|x축 좌표
	 * 		|-y		|int		|y축 좌표
	 * 		|-type		|int		|쓰레기 종류, 0: 없음(오류), 1: 담배, 2 ...
	 */
	socket.on('del_trash', function (data){
		console.log(`del_trash\t${socket.id}\t${JSON.stringify(data)}`);
		arr_trash = _.without(arr_trash, _.findWhere(arr_trash, {
			x: data.x,
			y: data.y,
			type: data.type
		}));
		set_arr_trash();
		io.emit('del_trash', {code: 5, id: data.id, data: arr_trash});
	});

	/* DESC: 	새로 접속한 유저의 소켓 정보를 생성
	 * 		connect 이후에 한번만 불러주면 됨
	 * 		이후, 다른 이용자를 포함하는 이용자 정보 배열을 반환
	 * 		나를 포함한 모든 사람에게 데이터가 전달됨
	 * URL:		http://121.150.20.121:52533
	 * NAME:	add_user
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|6
	 * 		|data		|json		|
	 * 		|-uid_u		|string		|이용자 고유값
	 * OUTPUT:	|code		|int		|6
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 이용자 배열
	 * 		|-socket_id	|string		|socket_id
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-name		|string		|이름
	 * 		|-costume	|int		|몸통 파트
	 * 		|-head		|int		|머리 파트
	 * 		|-hair		|int		|머리카락 파트
	 * 		|-face		|int		|얼굴 파트
	 * 		|-sex		|int		|성별
	 * 		|-pos_x		|float		|위치 x축
	 * 		|-pos_y		|float		|위치 y축
	 * 		|-pos_z		|float		|위치 z축
	 * 		|-rot_y		|float		|회전 y축
	 * 		|-level		|int		|현재 진행 중인 미션
	 * 		|-point		|int		|경험치
	 * 		|-process	|int		|진행도
	 * 		|err		|int		|0: 정상, 1: 소켓 정보 갱신 실패, 2: select failed
	 */
	 socket.on('add_user', function (data){
		console.log(`add_user\t${socket.id}\t${JSON.stringify(data)}`);
		var res_json = {code: 6, id: socket.id, data: '', err: 0};
		if(json_user.hasOwnProperty(socket.id)){
			conn.query(`select * from user where uid = ${conn.escape(data.data.uid_u)};
			select * from user_level where uid_u = ${conn.escape(data.data.uid_u)} and is_active = 1 limit 1;`, function (err_00, res_00){
				console.log(err_00);
				if(err_00 || (res_00[0].length == 0)){
					res_json.err = 2;
					io.to(socket.io).emit('add_user', res_json);
					console.log(res_json);
					return;
				}
				json_user[socket.id].socket_id = socket.id;
				json_user[socket.id].uid_u = res_00[0][0].uid;
				json_user[socket.id].costume = res_00[0][0].costume;
				json_user[socket.id].head = res_00[0][0].head;
				json_user[socket.id].hair = res_00[0][0].hair;
				json_user[socket.id].face = res_00[0][0].face;
				json_user[socket.id].sex = res_00[0][0].sex;
				json_user[socket.id].tong = 0;
				json_user[socket.id].glove = 0;
				json_user[socket.id].name = res_00[0][0].name;
				json_user[socket.id].pos_x = 0;
				json_user[socket.id].pos_y = 0;
				json_user[socket.id].pos_z = 0;
				json_user[socket.id].rot_y = 0;
				json_user[socket.id].level = 0;
				json_user[socket.id].point = 0;
				json_user[socket.id].process = 0;
				if(res_00[1].length > 0){
					json_user[socket.id].level = res_00[1][0].level;
					json_user[socket.id].point = res_00[1][0].point;
					json_user[socket.id].process = res_00[1][0].progress;
				}
				var arr_user = [];
				for(var i in json_user){
					arr_user.push(json_user[i]);
				}
				res_json.data = arr_user;
				console.log(res_json);
				io.emit('add_user', res_json);
				return;
			});
		}else{
			console.log('add user failed');
			res_json.err = 1;
			console.log(res_json);
			io.to(socket.io).emit('add_user', res_json);
			return;
		}
	});

	/* DESC: 	이미 접속해 있던 사람의 정보를 갱신
	 * 		장갑, 집게 등을 갱신할 때 불러주면 됨
	 *		그리고 http 통신의 update_user_costume 뒤에 불러주면 됨
	 * 		이후, 다른 이용자를 포함하는 이용자 정보 배열을 반환
	 * 		나를 포함한 모든 사람에게 데이터가 전달됨
	 * URL:		http://121.150.20.121:52533
	 * NAME:	upd_user
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|7
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|json		|
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-glove		|int		|장갑, 착용시 1, 안보내면 이전값 그대로 씀
	 * 		|-tong		|int		|집게, 착용시 1, 안보내면 이전값 그대로 씀
	 * OUTPUT:	|code		|int		|7
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 이용자 배열
	 * 		|-socket_id	|string		|socket_id
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-name		|string		|이름
	 * 		|-costume	|int		|몸통 파트
	 * 		|-head		|int		|머리 파트
	 * 		|-hair		|int		|머리카락 파트
	 * 		|-face		|int		|얼굴 파트
	 * 		|-glove		|int		|장갑
	 * 		|-tong		|int		|집게
	 * 		|-pos_x		|float		|위치 x축
	 * 		|-pos_y		|float		|위치 y축
	 * 		|-pos_z		|float		|위치 z축
	 * 		|-rot_y		|float		|회전 y축
	 * 		|-level		|int		|현재 진행 중인 미션
	 * 		|-point		|int		|경험치
	 * 		|-process	|int		|진행도
	 * 		|err		|int		|0: 정상, 1: 소켓 생성 실패, 2: select failed
	 */
	socket.on('upd_user', function (data){
		console.log(`upd_user\t${socket.id}\t${JSON.stringify(data)}`);
		var res_json = {code: 7, id: socket.id, data: '', err: 0};
		if(json_user.hasOwnProperty(socket.id)){
			conn.query(`select * from user where uid = ${conn.escape(data.data.uid_u)};
			select * from user_level where uid_u = ${conn.escape(data.data.uid_u)} and is_active = 1 limit 1;`, function (err_00, res_00){
				if(err_00 || (res_00.length == 0)){
					res_json.err = 2;
					io.to(socket.io).emit('upd_user', res_json);
					return;
				}
				json_user[socket.id].costume = res_00[0][0].costume;
				json_user[socket.id].head = res_00[0][0].head;
				json_user[socket.id].hair = res_00[0][0].hair;
				json_user[socket.id].face = res_00[0][0].face;
				json_user[socket.id].tong = data.data.tong || json_user[socket.id].tong;
				json_user[socket.id].glove = data.data.glove || json_user[socket.id].glove;
				json_user[socket.id].name = res_00[0][0].name;
				if(res_00[1].length > 0){
					json_user[socket.id].level = res_00[1][0].level;
					json_user[socket.id].point = res_00[1][0].point;
					json_user[socket.id].process = res_00[1][0].progress;
				}
				var arr_user = [];
				for(var i in json_user){
					arr_user.push(json_user[i]);
				}
				res_json.data = arr_user;
				io.emit('upd_user', res_json);
				return;
			});
		}else{
			res_json.err = 1;
			io.to(socket.id).emit('upd_user', res_json);
			return;
		}
	});

	/* DESC: 	새로운 미션을 시작할 때 보내주면 됨
	 *		DB에 새 미션 정보를 저장, 저장된 정보는 다음 로그인할 때 받아옴
	 * 		나를 포함한 모든 사람에게 데이터가 전달됨
	 * URL:		http://121.150.20.121:52533
	 * NAME:	add_level
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|9
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|json		|
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-level		|string		|시작한 미션 넘버(각 미션 1~8, 올 클리어시 0)
	 * OUTPUT:	|code		|int		|9
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 이용자 배열
	 * 		|-socket_id	|string		|socket_id
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-name		|string		|이름
	 * 		|-costume	|int		|몸통 파트
	 * 		|-head		|int		|머리 파트
	 * 		|-hair		|int		|머리카락 파트
	 * 		|-face		|int		|얼굴 파트
	 * 		|-glove		|int		|장갑
	 * 		|-tong		|int		|집게
	 * 		|-pos_x		|float		|위치 x축
	 * 		|-pos_y		|float		|위치 y축
	 * 		|-pos_z		|float		|위치 z축
	 * 		|-rot_y		|float		|회전 y축
	 * 		|-level		|int		|현재 진행 중인 미션
	 * 		|-point		|int		|현재 진행 중 미션 점수, 기본값 0
	 * 		|-process	|int		|진행도, 기본값 0
	 * 		|err		|int		|0: 정상, 1: 소켓 생성 실패, 2: insert failed
	 */
	socket.on('add_level', function (data){
		console.log(`add_level\t${socket.id}\t${JSON.stringify(data)}`);
		var res_json = {code: 9, id: socket.id, data: '', err: 0};
		if(json_user.hasOwnProperty(socket.id)){
			json_user[socket.id].level = data.data.level;
			conn.query(`insert into user_level(uid, uid_u, level) 
				values("${faker.string.uuid()}", ${conn.escape(data.data.uid_u)}), ${conn.escape(data.data.level)}`, function (err_00, res_00){
				if(err_00){
					res_json.err = 2;
					io.to(socket.io).emit('add_level', res_json);
					return;
				}
				var arr_user = [];
				for(var i in json_user){
					arr_user.push(json_user[i]);
				}
				io.emit('add_level', res_json);
				return;
			});
		}else{
			res_json.err = 1;
			io.to(socket.io).emit('add_level', res_json);
			return;
		}
	});

	/* DESC: 	미션이 종료될 때만 보내주면 됨
	*		DB에 갱신 미션 정보를 저장, 다음 로그인할 때 받아옴
	 * 		나를 포함한 모든 사람에게 데이터가 전달됨
	 * URL:		http://121.150.20.121:52533
	 * NAME:	upd_level
	 * METHOD:	SOCKET ON & EMIT
	 *		|NAME		|TYPE		|DESC
	 * INPUT:	|code		|int		|10
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|json		|
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-level		|int		|미션 넘버(각 미션 1~8, 올 클리어시 0)
	 * 		|-point		|int		|해당 미션에서 획득한 누적 점수
	 * OUTPUT:	|code		|int		|10
	 * 		|id		|string		|보낸 사람 소켓 id
	 * 		|data		|array json	|현재 이용자 배열
	 * 		|-socket_id	|string		|socket_id
	 * 		|-uid_u		|string		|이용자 고유값
	 * 		|-name		|string		|이름
	 * 		|-costume	|int		|몸통 파트
	 * 		|-head		|int		|머리 파트
	 * 		|-hair		|int		|머리카락 파트
	 * 		|-face		|int		|얼굴 파트
	 * 		|-glove		|int		|장갑
	 * 		|-tong		|int		|집게
	 * 		|-pos_x		|float		|위치 x축
	 * 		|-pos_y		|float		|위치 y축
	 * 		|-pos_z		|float		|위치 z축
	 * 		|-rot_y		|float		|회전 y축
	 * 		|-level		|int		|현재 진행 중인 미션
	 * 		|-point		|int		|해당 미션에서 획득한 점수
	 * 		|-process	|int		|진행도, 기본값 0
	 * 		|err		|int		|0: 정상, 1: 소켓 생성 실패, 2: update failed
	 */
	socket.on('upd_level', function (data){
		console.log(`upd_level\t${socket.id}\t${JSON.stringify(data)}`);
		var res_json = {code: 10, id: socket.id, data: '', err: 0};
		if(json_user.hasOwnProperty(socket.id)){
			json_user[socket.id].level = data.data.level || json_user[socket.id].level;
			json_user[socket.id].point = data.data.point || json_user[socket.id].point;
			json_user[socket.id].process = data.data.process || json_user[socket.id].process;
			conn.query(`update user_level 
				set level = ${conn.escape(data.data.level)}, 
				point = ${conn.escape(data.data.point)}, 
				process = ${conn.escape(data.data.process)} 
				where uid_u = ${conn.escape(data.data.uid_u)} 
				and level = ${conn.escape(data.data.level)} 
				and is_active = 1`, function (err_00, res_00){
				if(err_00){
					res_json.err = 2;
					io.to(socket.id).emit('upd_level', res_json);
					return;
				}else{
					var arr_user = [];
					for(var i in json_user){
						arr_user.push(json_user[i]);
					}
					res_json.data = arr_user;
					io.emit('upd_level', res_json);
					return;
				}
			});
		}else{
			res_json.err = 1;
			io.to(socket.io).emit('upd_level', res_json);
			return;
		}
	});

	socket.on('pick_trash', function (data){
		console.log(`pick_trash\t${socket.id}\t${socket.client.conn.server.clientsCount}`);
		var res_json = {code: 11, id: socket.id, data: '', err: 0};
		conn.query(`select inventory 
			from user 
			where uid = ${conn.escape(data.data.uid_u)}`, function (err_00, res_00){
			if(err_00 || res_00.length == 0){
				res_json.err = 1;
				io.to(socket.id).emit('pick_trash', res_json);
				return;
			}else{
				var inven = JSON.parse(res_00[0].inventory);
				console.log(inven);
				if(inven.inven0 == 0){
					inven.inven0 = data.type;
				}else if(inven.inven1 == 0){
					inven.inven1 = data.type;
				}else if(inven.inven2 == 0){
					inven.inven2 = data.type;
				}else if(inven.inven3 == 0){
					inven.inven3 = data.type;
				}else{
					res_json.err = 2;
					io.to(socket.id).emit('pick_trash', res_json);
					return;
				}
				conn.query(`update user 
					set inventory = ${conn.escape(JSON.stringify(inven))} 
					where uid = ${conn.escape(data.data.uid_u)}`, function (err_01, res_01){
					if(err_01){
						res_json.err = 3;
						io.to(socket.id).emit('pick_trash', res_json);
						return;
					}
					arr_trash = _.without(arr_trash, _.findWhere(arr_trash, {
						x: data.data.x,
						y: data.data.y,
						type: data.data.type
					}));
					set_arr_trash();
					res_json.data = {
						id: socket.id,
						inven: inven,
					};
					io.to(socket.id).emit('pick_trash', res_json);
					io.emit('sync_trash', {code: 4, data: arr_trash});
					return;
				});
			}
		});
	});

	/* DESC: 	누군가가 접속을 끊을 때 호출
	 *		이후, 다른 이용자의 socket id 반환, 해당 id로 캐릭터 삭제
	 * 		나를 포함한 모든 사람에게 데이터가 전달됨
	 * URL:		http://121.150.20.121:52533
	 * NAME:	disconnected
	 * METHOD:	SOCKET EMIT
	 *		|NAME		|TYPE		|DESC
	 * OUTPUT:	|code		|int		|8
	 * 		|id		|string		|나간 사람 소켓 id
	 * 		|data		|string		|-
	 */
	socket.on('disconnect', function (){
		console.log(`disconnect\t${socket.id}\t${socket.client.conn.server.clientsCount}`);
		//console.log(socket.client.conn.server.clientsCount);
		var res_json = {code: 8, id: socket.id, data: ''};
		clearInterval(sync_trash);
		json_user = _.omit(json_user, function (v, i){
			return i == socket.id;
		});
		var arr_user = [];
		for(var i in json_user){
			arr_user.push(json_user[i]);
		}
		res_json.data = socket.id;
		console.log(res_json);
		io.emit('disconnected', res_json);
	});
});
