블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2851)
Unity3D (894)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (189)
협업 (64)
3DS Max (3)
Game (12)
Utility (142)
Etc (99)
Link (34)
Portfolio (19)
Subject (90)
iOS,OSX (52)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

접속 유틸 (  putty  혹은  winscp  )

– 파일 다운로드 사이트
http://www.putty.org/
https://winscp.net/eng/download.php

DSM  SSH 설정

  • DSM 의 제어판 -> 터미널 및 SNMP -> SSH 서비스 활성화  후 포트 번호는  임의지정 ( 보안상 )
    ( SSH 사용시에만 활성화 이외엔 비활성화 권장 )

synology-ssh

  • 다시 제어판의 정보센터 -> 서비스 항목에서 SSH 방화벽 통화 허용에 체크후 저장 합니다.
    ( 저장시 방화벽 설정 어쩌구 하는 에러 발생시엔
    제어판->보안->방화벽->규칙편집의 활성화 된 항목을 삭제후 재시도 )

synology-ssh2

공유기 설정

( 사용중인  공유기가 IPTIME 인 관계로 IPTIME 으로 예시를 둡니다. )

사용중인 공유기 설정으로 가서 포트포워드 설정으로 위에서
SSH 활성화시에 적은 포트번호를 내부포트 번호로 적고
외부에서  ssh 접속 유틸에서 사용할
포트번호를 외부포트에 적은 후  추가 -> 동작 시킴니다.

내부 IP 는 synology 에서 사용중인 IP 주소를 적습니다.

synology 에서 사용중인 IP 주소를 모를경우엔  synology 의
제어판 -> 네트워크 -> 네트워크 인터페이스 탭의 -> LAN 포트의 항목에 나와있습니다.

iptime-port-forwarding

 

ssh 접속하기

PuTTY 설정  본인의 외부아이피를 적고  공유기에서 포트포워드로 설정한 외부포트 번호를 적은후 OPEN 으로 접속 합니다.

( SSH 접속시엔 DSM6.0 에서 이전 버전과 다르게 root 아이디 접속이 불가능 함으로
admin 계정으로 접속후 sudo -i 명령으로 root 권한을 받아서 사용해야 합니다. )

putty setting

 

WinSCP 는 protocol 을 SCP 로 선택하고 PuTTY 와 마찬가지로 각 항목 기입후 접속 합니다.

winscp setting

 


[출처] http://saltdoll.kr/nas/synology/p=99

반응형
Posted by blueasa
, |

NAS를 살 때 많은 고민을 하고 Synology 제품을 선택했다.

FTP 같은 기능은 당연한 것이고,

CloudStation 은 참 만족스러운 기능으로 사용을 했다.

 

최근에 주변 사람을 통해서 소스 형상관리툴 Git을 알게 되었다.

나의 NAS에서 Git을 설치할 수 있다는 것을 알게 되고는

구글링등의 많은 방법을 통하여 설치하는 방법을 알게 되었다.

 

이걸 정리를 해 놓아야지 다음에 다시 설치하더라고 유용할꺼 같아서 정리를 해 보았다.

 

● 설치 환경

Synology NAS DS212J

DSM 5.2

 

● 사용환경

Visual Studio 2013

 

● 설정방법

 

1.NAS에서 SSH서비스를 활성화해야 한다.

 

제어판에 들어가서 응용 프로그램란에 [터미널 및 SNMP]를 선택한다. 

 

 

SSH 서비스를 활성화 시켜준다. 

 

 

2.Git Server 설치

 

NAS바탕화면에 있는 패키지 센터를 실행해서, [모두] 또는 [유틸리티]화면을 열어보면 아래와 같이 Git Server라는게 보인다.

서버가 설치되기 전에는 버튼이 [설치]라고 되어 있어 설치하고 나서 보면 아래와 같이 [열기]로 보여진다. 

 

 

Git Server 설치 후 설치됨 메뉴를 선택해보면 아래와 같이 설치가 되었음을 알 수가 있다.

 

 

Git Server를 선택하여 들어가서 Git Server 서비스를 활성화 시켜준다. 

 

 

3.NAS에 사용자 계정을 추가해야 한다.

 

다시 제어판에 가서 사용자 메뉴를 선택한다.

사용자 메뉴에서 [생성] 버튼을 클릭한다.

 

 

사용자 정보를 입력한다.

사용자 계정을 gituser라고 했다.

 

 

gituser의 그룹은 users로 선택한다.

 

 

gituser는 homes만 접근권한을 줬다.

 

 

그 이후는 모두 다음 .. 다음 넘어가면 되고 혹시나 싶어서 WebDav는 허용하였다. 

 

 

 

4.Repository 생성

 

NAS에서의 작업은 끝이 난거 같다.

Windows 를 사용하는 관계로 PuTTY를 이용해서 Repository를 생성해야 되겠다.

PuTTY를 실행하고 root로 로그인을 한다.

 

 

 

키보드를 두드릴 시간이 왔다.

 

NAS에 disk가 하나가 있어 그 놈은 volume1인데 그 놈의 이름이 /var/services 이라는것 같다.(리눅스를 잘 모름)

아뭏튼 gituser라고 만든 계정의 홈은 /var/services/homes/gituser가 된다.

 

여기에 project.git 이라는 폴더를 생성고

그 폴더로 들어가서 Repository 초기화(?)라나 뭐 그렇게 해준다.

그리고 cd .. 하여 상위 폴더로 올라와서

project.git 이란 폴더의 하위 전체의 권한을 gituser에 넘긴다.

 

chown -R (git사용자 계정):(git 사용자가 속한 그룹)  (사용자 디렉토리)

 

여기까지 하면 Git Server의 설정이 끝이다.

 

 

 

5.Windows 에서의 설정

 

이것도 참 고생을 했다.

개념 모르고 덤비니 가시밭길이 이만 저만이 아니다.

그래도 다 왔다.

 

참고로 Windows에서의 Git 에 대한 사용법은 http://backlogtool.com/git-guide/kr/ 여기를 참고했다.

 

TortoiseGit 프로그램을 설치를 한다.

그리고 나서 Windows 원하는 경로에 repository를 생성한다.

 

 

 

그리고는 다시 TortoiseGit의 Settings 화면에서 사용자를 저장한다.

이 때 사용자는 NAS에 만든 gituser가 아닌 개발자를 의미한다.(개발자마다의 개별 설정)

 

 

제일 중요한 마지막 설정이다.

URL 은 http로는 성공을 못했다. 그래서 ssh로 했다.

ssh://(NAS에 생성했던 계정)@(NAS의 DNS):(포워딩한 port)/volume1/homes/(사용자 계정 폴더)/(Repository 폴더 명)

(예 ssh://gituser@nas.familyds.com:9112/volume1/homes/gituser/project.git)

 

- ssh의 표준 포트는 SSH 서비스 활성화에서처럼 22이다.

  세상이 무서워서 port forwading을 하는게 좋을꺼 같다. 임의의 숫자로

 

- /volume1 대신 /var/services 라고 써도 되는거 같은데 다음에 설정할 일이 있으면 그렇게 해 보아야겠다.

 

 

 

이렇게 해서 NAS에서의 Git 사용에 관련된 모든 설정을 완료한거 같다.

많은 시간을 들여서 해 놓은 삽질을 잊어버리기 전에 이렇게 정리한 번 해 보았다.




[출처] http://kongzz.tistory.com/14

반응형
Posted by blueasa
, |

Putty로 ssh root 접속 시 "Access denied" 가 뜨면서 접속 안되는 문제로 찾아보니


DSM6 버전부터 보안이 강화되면서 root 접속을 막았나보다.


admin 권한을 가진 다른 계정으로 접속해서 root 권한이 필요하면 sudo를 사용해야 될 듯..

(다른 방법이 있는지는 아직 모르겠다)



[참조]

Your Synology probably upgraded to DSM6, in which security has been hardened... In DSM6 you can no longer use root for SSH, but you can use any other member account of the administrators group. Mind that you now need to sudo when logged in using SSH.

See the DSM6 release notes!

[참조출처] http://superuser.com/questions/1057853/synology-dsm-cant-log-as-root-but-works-with-admin

반응형
Posted by blueasa
, |

의외로 NAS에 SSH로 접속하는 방법을 묻는 분들이 많아 포스팅합니다. 
Synology NAS는 클릭 몇번으로 Telnet 또는 SSH로의 접속을 허용할 수 있습니다. 
NAS의 기능을 최대한 활용하기 위해선 root 권한 획득이 필수적이므로 반드시 사용자가 알아둬야 할 부분입니다.

먼저 SSH 기능을 활성화 합니다. Synology DiskStation으로 들어가 ‘제어판’ - ‘터미널’에 들어간 다음 Telnet 또는 SSH 중 원하는 것을 체크하고 확인을 누릅니다. 여기서는 보안이 더 나은 SSH만을 활성화 합니다.

그 다음 Putty를 설치합니다. Putty가 아닌 아무 Terminal 프로그램을 사용해도 무방합니다. 한글판 Putty는 아래의 링크에서 다운로드 받을 수 있습니다.

한글 Putty 다운로드

다운로드 받은 후 설치가 완료되면 Putty를 실행합니다. 먼저 접속할 Synology NAS의 IP 주소를 적어줍니다.

왼쪽 메뉴의 <창> - <변환>에서 문자셋을 CP949에서 UTF-8로 바꿔줍니다. 바꿔주지 않으면 한글로 된 디렉토리들이 전부 깨져서 나옵니다.

이후 열기를 누르면 접속할 NAS의 호스트 키를 저장할 것인가를 묻습니다. 이는 최초 한번만 물어보는 것으로 예를 누르고 넘어갑니다.

SSH 터미널이 열립니다. ID는 root이며 패스워드는 admin 계정의 암호와 동일합니다.

[첨언]

DSM6부터 보안이 강화돼서 root로 로그인을 못하게 막았나보다.

(참조 : http://superuser.com/questions/1057853/synology-dsm-cant-log-as-root-but-works-with-admin )

DSM6 이상이면 다른 admin 권한을 가진 다른 계정으로 접속해서 root 권한이 필요하면 sudo를 사용해야 될 듯..

(다른 방법이 있는지는 아직 모르겠다)

접속이 잘 되는것을 확인 할 수 있습니다.
만약 공유기를 사용하고 있다면 공유기 관리에서 포트포워딩을 통해 외부에서도 쉽게 접속이 가능합니다.




[출처] http://wiki.aissii.com/2530

반응형
Posted by blueasa
, |


[링크] http://shimans.tistory.com/28


[유니티에셋스토어] https://www.assetstore.unity3d.com/kr/#!/content/27591


[홈페이지] https://tinypng.com/

반응형
Posted by blueasa
, |

엑셀이 제공하는 편리한 기능 때문에 게임에 사용되는 데이터를 관리하기 위해서 엑셀을 많이 사용합니다.

하지만, 보안 문제나 이기종간 데이터 연동 문제 등이 있어서 엑셀 파일을 그대로 사용하는 경우 보다는 원하는 포맷으로 데이터를 변환해서 사용하는 경우가 더 많습니다.

게임  개발에서 사용하는 포맷은 csv, xml, binary 형태 등 여러가지고 있고, 저는 그 중에서 Json을 사용해 볼까하고 검색.

제일 먼저 검색된 툴은 node.js 로 제작된 xls-to-json

https://www.npmjs.com/package/xls-to-json

설치법과 사용법이 매우 간단해서 node가 설치되어 있다면, 아래 명령어로 간단하게 설치할 수 있습니다.

npm install xls-to-json

나머지는 사이트의 Usage 항목에 있는대로 하면 되는데,
막상 실행을 해서 변환된 json 파일을 보니 자료형에 대한 지원이 전혀 없이 모두 string 타입으로 변환.
Date 타입은 고사하고, int나 float로 지정된 값들도 모두 따옴표(“)가 양 옆에 붙어 버려서 LitJson과 같은 Json 변환 라이브러리에서 ToObject()를 실행할 수 없는 상태가 됩니다.

실제로 신나게 테스트를 했는데, 변환할 수 없다는 에러가 나와서 한동안 멍하니 있었습니다.

다시 검색을 해 보니, 국내 개발자인 최효진님께서 개발한 라이브러리가 있었습니다.

https://github.com/coolengineer/excel2json

이 툴이 좋은 점은 아래 스샷처럼, 데이터를 관리할 수 있고 결과물도 깔끔하게 나온다는 것. excel2json_shot

결과물은 아래처럼 나옵니다. 숫자에는 확실히 따옴표가 없어졌습니다.
Objects in Object, Object array 등을 지원해서 이걸 쓰기로 결정. LitJson에서도 잘 불러와 집니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
    "init": {
        "coins": 1000,
        "exp": 0,
        "golds": 0,
        "character": "wizard"
    },
    "buildings": {
        "barrack": {
            "color": "blue",
            "width": 200,
            "height": 200
        },
        "mine": {
            "color": "yellow",
            "width": 200,
            "height": 100
        },
        "gas": {
            "color": "red",
            "width": 100,
            "height": 100
        },
        "townhall": {
            "color": "black",
            "width": 200,
            "height": 200
        }
    },


[출처]

https://heartgamer.wordpress.com/2015/01/14/excel-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-json%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0/

반응형

'Programming > JSON' 카테고리의 다른 글

[펌] Unity에서 Json 사용 시 고려할 라이브러리.  (0) 2016.08.08
[펌] SimpleJSON  (0) 2016.08.08
Convert Excel to JSON  (0) 2014.03.04
Posted by blueasa
, |

Restful API로 플랫폼간 연동을 하는 일들이 많다보니, Json 라이브러리는 필수라서 정보를 찾아 본 것을 정리.

우선 http://json.org/json-ko.html 에 정리되어 있는 C# 라이브러리를 먼저 보면

이 중에서 유니티 개발자 그룹 같은데서 많이 보이는 라이브러는 LitJson과 JsonFx..

* LitJson : http://lbv.github.io/litjson
이 라이브러를 추천하는 경우가 많은데, 다른 라이브러리들과 마찬가지로 iOS에서 serialize 문제가 있는 듯.

해결법 , http://forum.unity3d.com/threads/litjson-issue-on-ios.113181/ 참고.

* JsonFx : https://github.com/jsonfx/jsonfx
LitJson의 iOS 문제를 JsonFx를 사용해서 해결했다는 글이 보이길래 찾아봤는데,
Github에 올라온 패키지가 2년전 것. 물론 단순한 구조인 json 특성 상 딱히 건드릴만한 것이 없긴 하지만, 좀 써보고 판단을 해야 할듯.


[출처]

https://heartgamer.wordpress.com/2015/01/10/unity%EC%97%90%EC%84%9C-json-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%A0-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/

반응형

'Programming > JSON' 카테고리의 다른 글

[펌] Excel 데이터를 Json으로 변환하기  (0) 2016.08.08
[펌] SimpleJSON  (0) 2016.08.08
Convert Excel to JSON  (0) 2014.03.04
Posted by blueasa
, |

[펌] SimpleJSON

Programming/JSON / 2016. 8. 8. 10:21

SimpleJSON


Contents

 [hide

Description

SimpleJSON is an easy to use JSON parser and builder. It uses strong typed classes for the different JSONTypes. The parser / builder does not distinguish between different value types. Number, boolean and null will be treated like strings. This might cause problems when you need to build a JSON string that requires the actual types.

In short: The parser conforms to rfc4627, the generator does not.


I've updated (only) the source code embedded in the page, and it now appears to round-trip, although this isn't particularly well tested and it's a very naive implementation. Use .ToJSON(0) to use the round-trip version. -- Opless (talk) 22:39, 21 September 2014 (CEST)OPless

Usage

To use SimpleJSON in Unity you just have to copy the SimpleJSON.cs file into your projects "plugins" folder inside your assets folder.

If you want to use the compression feature when it comes to saving and loading you have to download the SharpZipLib assembly and place it next to the SimpleJSON.cs file. In addition you have to uncomment the define at the top of the SimpleJSON.cs file.

For language specific usage see below.

CSharp

Like most assemblies SimpleJSON is contained in its own namespace to avoid name collisions.

To use SimpleJSON in C# you have to add this line at the top of your script:

using SimpleJSON;

UnityScript (Unity's Javascript)

To use SimpleJSON in UnityScript you have to add this line at the top of your script:

import SimpleJSON;

For UnityScript it's vital to place the SimpleJSON.cs (and SharpZipLib if needed) into a higher compilation group than the UnityScript file that should use it. The usual place is the Plugins folder which should work in most cases.

Examples (C# / UnityScript)

This is the JSON string which will be used in this example:

{
    "version": "1.0",
    "data": {
        "sampleArray": [
            "string value",
            5,
            {
                "name": "sub object"
            }
        ]
    }
}


var N = JSON.Parse(the_JSON_string);
var versionString = N["version"].Value;        // versionString will be a string containing "1.0"
var versionNumber = N["version"].AsFloat;      // versionNumber will be a float containing 1.0
var name = N["data"]["sampleArray"][2]["name"];// name will be a string containing "sub object"
 
//C#
string val = N["data"]["sampleArray"][0];      // val contains "string value"
 
//UnityScript
var val : String = N["data"]["sampleArray"][0];// val contains "string value"
 
var i = N["data"]["sampleArray"][1].AsInt;     // i will be an integer containing 5
N["data"]["sampleArray"][1].AsInt = i+6;       // the second value in sampleArray will contain "11"
 
N["additional"]["second"]["name"] = "FooBar";  // this will create a new object named "additional" in this object create another
                                               //object "second" in this object add a string variable "name"
 
var mCount = N["countries"]["germany"]["moronCount"].AsInt; // this will return 0 and create all the required objects and
                                                            // initialize "moronCount" with 0.
 
if (N["wrong"] != null)                        // this won't execute the if-statement since "wrong" doesn't exist
{}
if (N["wrong"].AsInt == 0)                     // this will execute the if-statement and in addition add the "wrong" value.
{}
 
N["data"]["sampleArray"][-1] = "Test";         // this will add another string to the end of the array
N["data"]["sampleArray"][-1]["name"] = "FooBar"; // this will add another object to the end of the array which contains a string named "name"
 
N["data"] = "erased";                          // this will replace the object stored in data with the string "erased"


Download

Here's the whole thing packed as unityPackage and as seperate files including example / test scripts

Media:SimpleJSON.zip


SimpleJSON.cs

//#define USE_SharpZipLib
#if !UNITY_WEBPLAYER
#define USE_FileIO
#endif
/* * * * *
 * A simple JSON Parser / builder
 * ------------------------------
 * 
 * It mainly has been written as a simple JSON parser. It can build a JSON string
 * from the node-tree, or generate a node tree from any valid JSON string.
 * 
 * If you want to use compression when saving to file / stream / B64 you have to include
 * SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) in your project and
 * define "USE_SharpZipLib" at the top of the file
 * 
 * Written by Bunny83 
 * 2012-06-09
 * 
 * Modified by oPless, 2014-09-21 to round-trip properly
 *
 * Features / attributes:
 * - provides strongly typed node classes and lists / dictionaries
 * - provides easy access to class members / array items / data values
 * - the parser ignores data types. Each value is a string.
 * - only double quotes (") are used for quoting strings.
 * - values and names are not restricted to quoted strings. They simply add up and are trimmed.
 * - There are only 3 types: arrays(JSONArray), objects(JSONClass) and values(JSONData)
 * - provides "casting" properties to easily convert to / from those types:
 *   int / float / double / bool
 * - provides a common interface for each node so no explicit casting is required.
 * - the parser try to avoid errors, but if malformed JSON is parsed the result is undefined
 * 
 * 
 * 2012-12-17 Update:
 * - Added internal JSONLazyCreator class which simplifies the construction of a JSON tree
 *   Now you can simple reference any item that doesn't exist yet and it will return a JSONLazyCreator
 *   The class determines the required type by it's further use, creates the type and removes itself.
 * - Added binary serialization / deserialization.
 * - Added support for BZip2 zipped binary format. Requires the SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ )
 *   The usage of the SharpZipLib library can be disabled by removing or commenting out the USE_SharpZipLib define at the top
 * - The serializer uses different types when it comes to store the values. Since my data values
 *   are all of type string, the serializer will "try" which format fits best. The order is: int, float, double, bool, string.
 *   It's not the most efficient way but for a moderate amount of data it should work on all platforms.
 * 
 * * * * */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
 
 
namespace SimpleJSON
{
	public enum JSONBinaryTag
	{
		Array = 1,
		Class = 2,
		Value = 3,
		IntValue = 4,
		DoubleValue = 5,
		BoolValue = 6,
		FloatValue = 7,
	}
 
	public abstract class JSONNode
	{
		#region common interface
 
		public virtual void Add (string aKey, JSONNode aItem)
		{
		}
 
		public virtual JSONNode this [int aIndex]   { get { return null; } set { } }
 
		public virtual JSONNode this [string aKey]  { get { return null; } set { } }
 
		public virtual string Value                { get { return ""; } set { } }
 
		public virtual int Count                   { get { return 0; } }
 
		public virtual void Add (JSONNode aItem)
		{
			Add ("", aItem);
		}
 
		public virtual JSONNode Remove (string aKey)
		{
			return null;
		}
 
		public virtual JSONNode Remove (int aIndex)
		{
			return null;
		}
 
		public virtual JSONNode Remove (JSONNode aNode)
		{
			return aNode;
		}
 
		public virtual IEnumerable<JSONNode> Children
		{
			get {
				yield break;
			}
		}
 
		public IEnumerable<JSONNode> DeepChildren
		{
			get {
				foreach (var C in Children)
					foreach (var D in C.DeepChildren)
						yield return D;
			}
		}
 
		public override string ToString ()
		{
			return "JSONNode";
		}
 
		public virtual string ToString (string aPrefix)
		{
			return "JSONNode";
		}
 
		public abstract string ToJSON (int prefix);
 
		#endregion common interface
 
		#region typecasting properties
 
		public virtual JSONBinaryTag Tag { get; set; }
 
		public virtual int AsInt
		{
			get {
				int v = 0;
				if (int.TryParse (Value, out v))
					return v;
				return 0;
			}
			set {
				Value = value.ToString ();
				Tag = JSONBinaryTag.IntValue;
			}
		}
 
		public virtual float AsFloat
		{
			get {
				float v = 0.0f;
				if (float.TryParse (Value, out v))
					return v;
				return 0.0f;
			}
			set {
				Value = value.ToString ();
				Tag = JSONBinaryTag.FloatValue;
			}
		}
 
		public virtual double AsDouble
		{
			get {
				double v = 0.0;
				if (double.TryParse (Value, out v))
					return v;
				return 0.0;
			}
			set {
				Value = value.ToString ();
				Tag = JSONBinaryTag.DoubleValue;
 
			}
		}
 
		public virtual bool AsBool
		{
			get {
				bool v = false;
				if (bool.TryParse (Value, out v))
					return v;
				return !string.IsNullOrEmpty (Value);
			}
			set {
				Value = (value) ? "true" : "false";
				Tag = JSONBinaryTag.BoolValue;
 
			}
		}
 
		public virtual JSONArray AsArray
		{
			get {
				return this as JSONArray;
			}
		}
 
		public virtual JSONClass AsObject
		{
			get {
				return this as JSONClass;
			}
		}
 
 
		#endregion typecasting properties
 
		#region operators
 
		public static implicit operator JSONNode (string s)
		{
			return new JSONData (s);
		}
 
		public static implicit operator string (JSONNode d)
		{
			return (d == null) ? null : d.Value;
		}
 
		public static bool operator == (JSONNode a, object b)
		{
			if (b == null && a is JSONLazyCreator)
				return true;
			return System.Object.ReferenceEquals (a, b);
		}
 
		public static bool operator != (JSONNode a, object b)
		{
			return !(a == b);
		}
 
		public override bool Equals (object obj)
		{
			return System.Object.ReferenceEquals (this, obj);
		}
 
		public override int GetHashCode ()
		{
			return base.GetHashCode ();
		}
 
 
		#endregion operators
 
		internal static string Escape (string aText)
		{
			string result = "";
			foreach (char c in aText) {
				switch (c) {
					case '\\':
						result += "\\\\";
						break;
					case '\"':
						result += "\\\"";
						break;
					case '\n':
						result += "\\n";
						break;
					case '\r':
						result += "\\r";
						break;
					case '\t':
						result += "\\t";
						break;
					case '\b':
						result += "\\b";
						break;
					case '\f':
						result += "\\f";
						break;
					default   :
						result += c;
						break;
				}
			}
			return result;
		}
 
		static JSONData Numberize (string token)
		{
			bool flag = false;
			int integer = 0;
			double real = 0;
 
			if (int.TryParse (token, out integer)) {
				return new JSONData (integer);
			}
 
			if (double.TryParse (token, out real)) {
				return new JSONData (real);
			}
 
			if (bool.TryParse (token, out flag)) {
				return new JSONData (flag);
			}
 
			throw new NotImplementedException (token);
		}
 
		static void AddElement (JSONNode ctx, string token, string tokenName, bool tokenIsString)
		{
			if (tokenIsString) {
				if (ctx is JSONArray)
					ctx.Add (token);
				else
					ctx.Add (tokenName, token); // assume dictionary/object
			} else {
				JSONData number = Numberize (token);
				if (ctx is JSONArray)
					ctx.Add (number);
				else
					ctx.Add (tokenName, number);
 
			}
		}
 
		public static JSONNode Parse (string aJSON)
		{
			Stack<JSONNode> stack = new Stack<JSONNode> ();
			JSONNode ctx = null;
			int i = 0;
			string Token = "";
			string TokenName = "";
			bool QuoteMode = false;
			bool TokenIsString = false;
			while (i < aJSON.Length) {
				switch (aJSON [i]) {
					case '{':
						if (QuoteMode) {
							Token += aJSON [i];
							break;
						}
						stack.Push (new JSONClass ());
						if (ctx != null) {
							TokenName = TokenName.Trim ();
							if (ctx is JSONArray)
								ctx.Add (stack.Peek ());
							else if (TokenName != "")
								ctx.Add (TokenName, stack.Peek ());
						}
						TokenName = "";
						Token = "";
						ctx = stack.Peek ();
						break;
 
					case '[':
						if (QuoteMode) {
							Token += aJSON [i];
							break;
						}
 
						stack.Push (new JSONArray ());
						if (ctx != null) {
							TokenName = TokenName.Trim ();
 
							if (ctx is JSONArray)
								ctx.Add (stack.Peek ());
							else if (TokenName != "")
								ctx.Add (TokenName, stack.Peek ());
						}
						TokenName = "";
						Token = "";
						ctx = stack.Peek ();
						break;
 
					case '}':
					case ']':
						if (QuoteMode) {
							Token += aJSON [i];
							break;
						}
						if (stack.Count == 0)
							throw new Exception ("JSON Parse: Too many closing brackets");
 
						stack.Pop ();
						if (Token != "") {
							TokenName = TokenName.Trim ();
							/*
							if (ctx is JSONArray)
								ctx.Add (Token);
							else if (TokenName != "")
								ctx.Add (TokenName, Token);
								*/
							AddElement (ctx, Token, TokenName, TokenIsString);
							TokenIsString = false;
						}
						TokenName = "";
						Token = "";
						if (stack.Count > 0)
							ctx = stack.Peek ();
						break;
 
					case ':':
						if (QuoteMode) {
							Token += aJSON [i];
							break;
						}
						TokenName = Token;
						Token = "";
						TokenIsString = false;
						break;
 
					case '"':
						QuoteMode ^= true;
						TokenIsString = QuoteMode == true ? true : TokenIsString;
						break;
 
					case ',':
						if (QuoteMode) {
							Token += aJSON [i];
							break;
						}
						if (Token != "") {
							/*
							if (ctx is JSONArray) {
								ctx.Add (Token);
							} else if (TokenName != "") {
								ctx.Add (TokenName, Token);
							}
							*/
							AddElement (ctx, Token, TokenName, TokenIsString);
							TokenIsString = false;
 
						}
						TokenName = "";
						Token = "";
						TokenIsString = false;
						break;
 
					case '\r':
					case '\n':
						break;
 
					case ' ':
					case '\t':
						if (QuoteMode)
							Token += aJSON [i];
						break;
 
					case '\\':
						++i;
						if (QuoteMode) {
							char C = aJSON [i];
							switch (C) {
								case 't':
									Token += '\t';
									break;
								case 'r':
									Token += '\r';
									break;
								case 'n':
									Token += '\n';
									break;
								case 'b':
									Token += '\b';
									break;
								case 'f':
									Token += '\f';
									break;
								case 'u':
									{
										string s = aJSON.Substring (i + 1, 4);
										Token += (char)int.Parse (
											s,
											System.Globalization.NumberStyles.AllowHexSpecifier);
										i += 4;
										break;
									}
								default  :
									Token += C;
									break;
							}
						}
						break;
 
					default:
						Token += aJSON [i];
						break;
				}
				++i;
			}
			if (QuoteMode) {
				throw new Exception ("JSON Parse: Quotation marks seems to be messed up.");
			}
			return ctx;
		}
 
		public virtual void Serialize (System.IO.BinaryWriter aWriter)
		{
		}
 
		public void SaveToStream (System.IO.Stream aData)
		{
			var W = new System.IO.BinaryWriter (aData);
			Serialize (W);
		}
 
		#if USE_SharpZipLib
		public void SaveToCompressedStream(System.IO.Stream aData)
		{
			using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData))
			{
				gzipOut.IsStreamOwner = false;
				SaveToStream(gzipOut);
				gzipOut.Close();
			}
		}
 
		public void SaveToCompressedFile(string aFileName)
		{
 
#if USE_FileIO
			System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
			using(var F = System.IO.File.OpenWrite(aFileName))
			{
				SaveToCompressedStream(F);
			}
 
#else
			throw new Exception("Can't use File IO stuff in webplayer");
#endif
		}
		public string SaveToCompressedBase64()
		{
			using (var stream = new System.IO.MemoryStream())
			{
				SaveToCompressedStream(stream);
				stream.Position = 0;
				return System.Convert.ToBase64String(stream.ToArray());
			}
		}
 
#else
		public void SaveToCompressedStream (System.IO.Stream aData)
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
 
		public void SaveToCompressedFile (string aFileName)
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
 
		public string SaveToCompressedBase64 ()
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
		#endif
 
		public void SaveToFile (string aFileName)
		{
#if USE_FileIO
			System.IO.Directory.CreateDirectory ((new System.IO.FileInfo (aFileName)).Directory.FullName);
			using (var F = System.IO.File.OpenWrite (aFileName)) {
				SaveToStream (F);
			}
			#else
			throw new Exception ("Can't use File IO stuff in webplayer");
			#endif
		}
 
		public string SaveToBase64 ()
		{
			using (var stream = new System.IO.MemoryStream ()) {
				SaveToStream (stream);
				stream.Position = 0;
				return System.Convert.ToBase64String (stream.ToArray ());
			}
		}
 
		public static JSONNode Deserialize (System.IO.BinaryReader aReader)
		{
			JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte ();
			switch (type) {
				case JSONBinaryTag.Array:
					{
						int count = aReader.ReadInt32 ();
						JSONArray tmp = new JSONArray ();
						for (int i = 0; i < count; i++)
							tmp.Add (Deserialize (aReader));
						return tmp;
					}
				case JSONBinaryTag.Class:
					{
						int count = aReader.ReadInt32 ();                
						JSONClass tmp = new JSONClass ();
						for (int i = 0; i < count; i++) {
							string key = aReader.ReadString ();
							var val = Deserialize (aReader);
							tmp.Add (key, val);
						}
						return tmp;
					}
				case JSONBinaryTag.Value:
					{
						return new JSONData (aReader.ReadString ());
					}
				case JSONBinaryTag.IntValue:
					{
						return new JSONData (aReader.ReadInt32 ());
					}
				case JSONBinaryTag.DoubleValue:
					{
						return new JSONData (aReader.ReadDouble ());
					}
				case JSONBinaryTag.BoolValue:
					{
						return new JSONData (aReader.ReadBoolean ());
					}
				case JSONBinaryTag.FloatValue:
					{
						return new JSONData (aReader.ReadSingle ());
					}
 
				default:
					{
						throw new Exception ("Error deserializing JSON. Unknown tag: " + type);
					}
			}
		}
 
		#if USE_SharpZipLib
		public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
		{
			var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData);
			return LoadFromStream(zin);
		}
		public static JSONNode LoadFromCompressedFile(string aFileName)
		{
#if USE_FileIO
			using(var F = System.IO.File.OpenRead(aFileName))
			{
				return LoadFromCompressedStream(F);
			}
#else
			throw new Exception("Can't use File IO stuff in webplayer");
#endif
		}
		public static JSONNode LoadFromCompressedBase64(string aBase64)
		{
			var tmp = System.Convert.FromBase64String(aBase64);
			var stream = new System.IO.MemoryStream(tmp);
			stream.Position = 0;
			return LoadFromCompressedStream(stream);
		}
#else
		public static JSONNode LoadFromCompressedFile (string aFileName)
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
 
		public static JSONNode LoadFromCompressedStream (System.IO.Stream aData)
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
 
		public static JSONNode LoadFromCompressedBase64 (string aBase64)
		{
			throw new Exception ("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
		}
		#endif
 
		public static JSONNode LoadFromStream (System.IO.Stream aData)
		{
			using (var R = new System.IO.BinaryReader (aData)) {
				return Deserialize (R);
			}
		}
 
		public static JSONNode LoadFromFile (string aFileName)
		{
			#if USE_FileIO
			using (var F = System.IO.File.OpenRead (aFileName)) {
				return LoadFromStream (F);
			}
			#else
			throw new Exception ("Can't use File IO stuff in webplayer");
			#endif
		}
 
		public static JSONNode LoadFromBase64 (string aBase64)
		{
			var tmp = System.Convert.FromBase64String (aBase64);
			var stream = new System.IO.MemoryStream (tmp);
			stream.Position = 0;
			return LoadFromStream (stream);
		}
	}
	// End of JSONNode
 
	public class JSONArray : JSONNode, IEnumerable
	{
		private List<JSONNode> m_List = new List<JSONNode> ();
 
		public override JSONNode this [int aIndex]
		{
			get {
				if (aIndex < 0 || aIndex >= m_List.Count)
					return new JSONLazyCreator (this);
				return m_List [aIndex];
			}
			set {
				if (aIndex < 0 || aIndex >= m_List.Count)
					m_List.Add (value);
				else
					m_List [aIndex] = value;
			}
		}
 
		public override JSONNode this [string aKey]
		{
			get{ return new JSONLazyCreator (this); }
			set{ m_List.Add (value); }
		}
 
		public override int Count
		{
			get { return m_List.Count; }
		}
 
		public override void Add (string aKey, JSONNode aItem)
		{
			m_List.Add (aItem);
		}
 
		public override JSONNode Remove (int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_List.Count)
				return null;
			JSONNode tmp = m_List [aIndex];
			m_List.RemoveAt (aIndex);
			return tmp;
		}
 
		public override JSONNode Remove (JSONNode aNode)
		{
			m_List.Remove (aNode);
			return aNode;
		}
 
		public override IEnumerable<JSONNode> Children
		{
			get {
				foreach (JSONNode N in m_List)
					yield return N;
			}
		}
 
		public IEnumerator GetEnumerator ()
		{
			foreach (JSONNode N in m_List)
				yield return N;
		}
 
		public override string ToString ()
		{
			string result = "[ ";
			foreach (JSONNode N in m_List) {
				if (result.Length > 2)
					result += ", ";
				result += N.ToString ();
			}
			result += " ]";
			return result;
		}
 
		public override string ToString (string aPrefix)
		{
			string result = "[ ";
			foreach (JSONNode N in m_List) {
				if (result.Length > 3)
					result += ", ";
				result += "\n" + aPrefix + "   ";                
				result += N.ToString (aPrefix + "   ");
			}
			result += "\n" + aPrefix + "]";
			return result;
		}
 
		public override string ToJSON (int prefix)
		{
			string s = new string (' ', (prefix + 1) * 2);
			string ret = "[ ";
			foreach (JSONNode n in m_List) {
				if (ret.Length > 3)
					ret += ", ";
				ret += "\n" + s;
				ret += n.ToJSON (prefix + 1);
 
			}
			ret += "\n" + s + "]";
			return ret;
		}
 
		public override void Serialize (System.IO.BinaryWriter aWriter)
		{
			aWriter.Write ((byte)JSONBinaryTag.Array);
			aWriter.Write (m_List.Count);
			for (int i = 0; i < m_List.Count; i++) {
				m_List [i].Serialize (aWriter);
			}
		}
	}
	// End of JSONArray
 
	public class JSONClass : JSONNode, IEnumerable
	{
		private Dictionary<string,JSONNode> m_Dict = new Dictionary<string,JSONNode> ();
 
		public override JSONNode this [string aKey]
		{
			get {
				if (m_Dict.ContainsKey (aKey))
					return m_Dict [aKey];
				else
					return new JSONLazyCreator (this, aKey);
			}
			set {
				if (m_Dict.ContainsKey (aKey))
					m_Dict [aKey] = value;
				else
					m_Dict.Add (aKey, value);
			}
		}
 
		public override JSONNode this [int aIndex]
		{
			get {
				if (aIndex < 0 || aIndex >= m_Dict.Count)
					return null;
				return m_Dict.ElementAt (aIndex).Value;
			}
			set {
				if (aIndex < 0 || aIndex >= m_Dict.Count)
					return;
				string key = m_Dict.ElementAt (aIndex).Key;
				m_Dict [key] = value;
			}
		}
 
		public override int Count
		{
			get { return m_Dict.Count; }
		}
 
 
		public override void Add (string aKey, JSONNode aItem)
		{
			if (!string.IsNullOrEmpty (aKey)) {
				if (m_Dict.ContainsKey (aKey))
					m_Dict [aKey] = aItem;
				else
					m_Dict.Add (aKey, aItem);
			} else
				m_Dict.Add (Guid.NewGuid ().ToString (), aItem);
		}
 
		public override JSONNode Remove (string aKey)
		{
			if (!m_Dict.ContainsKey (aKey))
				return null;
			JSONNode tmp = m_Dict [aKey];
			m_Dict.Remove (aKey);
			return tmp;        
		}
 
		public override JSONNode Remove (int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_Dict.Count)
				return null;
			var item = m_Dict.ElementAt (aIndex);
			m_Dict.Remove (item.Key);
			return item.Value;
		}
 
		public override JSONNode Remove (JSONNode aNode)
		{
			try {
				var item = m_Dict.Where (k => k.Value == aNode).First ();
				m_Dict.Remove (item.Key);
				return aNode;
			} catch {
				return null;
			}
		}
 
		public override IEnumerable<JSONNode> Children
		{
			get {
				foreach (KeyValuePair<string,JSONNode> N in m_Dict)
					yield return N.Value;
			}
		}
 
		public IEnumerator GetEnumerator ()
		{
			foreach (KeyValuePair<string, JSONNode> N in m_Dict)
				yield return N;
		}
 
		public override string ToString ()
		{
			string result = "{";
			foreach (KeyValuePair<string, JSONNode> N in m_Dict) {
				if (result.Length > 2)
					result += ", ";
				result += "\"" + Escape (N.Key) + "\":" + N.Value.ToString ();
			}
			result += "}";
			return result;
		}
 
		public override string ToString (string aPrefix)
		{
			string result = "{ ";
			foreach (KeyValuePair<string, JSONNode> N in m_Dict) {
				if (result.Length > 3)
					result += ", ";
				result += "\n" + aPrefix + "   ";
				result += "\"" + Escape (N.Key) + "\" : " + N.Value.ToString (aPrefix + "   ");
			}
			result += "\n" + aPrefix + "}";
			return result;
		}
 
		public override string ToJSON (int prefix)
		{
			string s = new string (' ', (prefix + 1) * 2);
			string ret = "{ ";
			foreach (KeyValuePair<string,JSONNode> n in m_Dict) {
				if (ret.Length > 3)
					ret += ", ";
				ret += "\n" + s;
				ret += string.Format ("\"{0}\": {1}", n.Key, n.Value.ToJSON (prefix + 1));
			}
			ret += "\n" + s + "}";
			return ret;
		}
 
		public override void Serialize (System.IO.BinaryWriter aWriter)
		{
			aWriter.Write ((byte)JSONBinaryTag.Class);
			aWriter.Write (m_Dict.Count);
			foreach (string K in m_Dict.Keys) {
				aWriter.Write (K);
				m_Dict [K].Serialize (aWriter);
			}
		}
	}
	// End of JSONClass
 
	public class JSONData : JSONNode
	{
		private string m_Data;
 
 
		public override string Value
		{
			get { return m_Data; }
			set {
				m_Data = value;
				Tag = JSONBinaryTag.Value;
			}
		}
 
		public JSONData (string aData)
		{
			m_Data = aData;
			Tag = JSONBinaryTag.Value;
		}
 
		public JSONData (float aData)
		{
			AsFloat = aData;
		}
 
		public JSONData (double aData)
		{
			AsDouble = aData;
		}
 
		public JSONData (bool aData)
		{
			AsBool = aData;
		}
 
		public JSONData (int aData)
		{
			AsInt = aData;
		}
 
		public override string ToString ()
		{
			return "\"" + Escape (m_Data) + "\"";
		}
 
		public override string ToString (string aPrefix)
		{
			return "\"" + Escape (m_Data) + "\"";
		}
 
		public override string ToJSON (int prefix)
		{
			switch (Tag) {
				case JSONBinaryTag.DoubleValue:
				case JSONBinaryTag.FloatValue:
				case JSONBinaryTag.IntValue:
					return m_Data;
				case JSONBinaryTag.Value:
					return string.Format ("\"{0}\"", Escape (m_Data));
				default:
					throw new NotSupportedException ("This shouldn't be here: " + Tag.ToString ());
			}
		}
 
		public override void Serialize (System.IO.BinaryWriter aWriter)
		{
			var tmp = new JSONData ("");
 
			tmp.AsInt = AsInt;
			if (tmp.m_Data == this.m_Data) {
				aWriter.Write ((byte)JSONBinaryTag.IntValue);
				aWriter.Write (AsInt);
				return;
			}
			tmp.AsFloat = AsFloat;
			if (tmp.m_Data == this.m_Data) {
				aWriter.Write ((byte)JSONBinaryTag.FloatValue);
				aWriter.Write (AsFloat);
				return;
			}
			tmp.AsDouble = AsDouble;
			if (tmp.m_Data == this.m_Data) {
				aWriter.Write ((byte)JSONBinaryTag.DoubleValue);
				aWriter.Write (AsDouble);
				return;
			}
 
			tmp.AsBool = AsBool;
			if (tmp.m_Data == this.m_Data) {
				aWriter.Write ((byte)JSONBinaryTag.BoolValue);
				aWriter.Write (AsBool);
				return;
			}
			aWriter.Write ((byte)JSONBinaryTag.Value);
			aWriter.Write (m_Data);
		}
	}
	// End of JSONData
 
	internal class JSONLazyCreator : JSONNode
	{
		private JSONNode m_Node = null;
		private string m_Key = null;
 
		public JSONLazyCreator (JSONNode aNode)
		{
			m_Node = aNode;
			m_Key = null;
		}
 
		public JSONLazyCreator (JSONNode aNode, string aKey)
		{
			m_Node = aNode;
			m_Key = aKey;
		}
 
		private void Set (JSONNode aVal)
		{
			if (m_Key == null) {
				m_Node.Add (aVal);
			} else {
				m_Node.Add (m_Key, aVal);
			}
			m_Node = null; // Be GC friendly.
		}
 
		public override JSONNode this [int aIndex]
		{
			get {
				return new JSONLazyCreator (this);
			}
			set {
				var tmp = new JSONArray ();
				tmp.Add (value);
				Set (tmp);
			}
		}
 
		public override JSONNode this [string aKey]
		{
			get {
				return new JSONLazyCreator (this, aKey);
			}
			set {
				var tmp = new JSONClass ();
				tmp.Add (aKey, value);
				Set (tmp);
			}
		}
 
		public override void Add (JSONNode aItem)
		{
			var tmp = new JSONArray ();
			tmp.Add (aItem);
			Set (tmp);
		}
 
		public override void Add (string aKey, JSONNode aItem)
		{
			var tmp = new JSONClass ();
			tmp.Add (aKey, aItem);
			Set (tmp);
		}
 
		public static bool operator == (JSONLazyCreator a, object b)
		{
			if (b == null)
				return true;
			return System.Object.ReferenceEquals (a, b);
		}
 
		public static bool operator != (JSONLazyCreator a, object b)
		{
			return !(a == b);
		}
 
		public override bool Equals (object obj)
		{
			if (obj == null)
				return true;
			return System.Object.ReferenceEquals (this, obj);
		}
 
		public override int GetHashCode ()
		{
			return base.GetHashCode ();
		}
 
		public override string ToString ()
		{
			return "";
		}
 
		public override string ToString (string aPrefix)
		{
			return "";
		}
 
		public override string ToJSON (int prefix)
		{
			return "";
		}
 
		public override int AsInt
		{
			get {
				JSONData tmp = new JSONData (0);
				Set (tmp);
				return 0;
			}
			set {
				JSONData tmp = new JSONData (value);
				Set (tmp);
			}
		}
 
		public override float AsFloat
		{
			get {
				JSONData tmp = new JSONData (0.0f);
				Set (tmp);
				return 0.0f;
			}
			set {
				JSONData tmp = new JSONData (value);
				Set (tmp);
			}
		}
 
		public override double AsDouble
		{
			get {
				JSONData tmp = new JSONData (0.0);
				Set (tmp);
				return 0.0;
			}
			set {
				JSONData tmp = new JSONData (value);
				Set (tmp);
			}
		}
 
		public override bool AsBool
		{
			get {
				JSONData tmp = new JSONData (false);
				Set (tmp);
				return false;
			}
			set {
				JSONData tmp = new JSONData (value);
				Set (tmp);
			}
		}
 
		public override JSONArray AsArray
		{
			get {
				JSONArray tmp = new JSONArray ();
				Set (tmp);
				return tmp;
			}
		}
 
		public override JSONClass AsObject
		{
			get {
				JSONClass tmp = new JSONClass ();
				Set (tmp);
				return tmp;
			}
		}
	}
	// End of JSONLazyCreator
 
	public static class JSON
	{
		public static JSONNode Parse (string aJSON)
		{
			return JSONNode.Parse (aJSON);
		}
	}
}


[출처] http://wiki.unity3d.com/index.php/SimpleJSON#Examples_.28C.23_.2F_UnityScript.29

반응형
Posted by blueasa
, |


[링크] http://edaero.net/917

반응형
Posted by blueasa
, |

[링크] http://blog.naver.com/ian0371/220109191894

반응형
Posted by blueasa
, |