프로그래밍/C/C++2013.08.19 17:02

cocos2dx 3.0.0 이 kick start 되었습니다.


기존 2.x.x에서 3.x.x로 바뀌었단 얘기는 많은것이 바뀌었단 얘기죠.


가장 큰 변화점은 C++11 을 정식으로 지원한단 얘깁니다.


C++10 또는 C++0x 은 기존 C++의 불편한 점을 개선하고 최근 트렌드 (java, phython등) 를 따라가려고 노력합니다.


앞으로 이 부분에 대해 간략하게 소개할까 합니다.


따..딱히 할일이 없어서 그러는건 아니라능!


cocos2dx 3.0.0 (이하 cocos3.0) 에서는 다음과 같은 재료를 필요로합니다.


- Xcode 4.6 (for iOS or Mac)

- gcc 4.7 for Linux or Android. For Android ndk-r8e or newer is required.


업데이트 해주세요 :)

참고로 ios7에서 앱을 만들고 업로드하려면 xcode5 가 필요합니다. 그리고 xcode5 는 마운틴라이언부터 지원하고요. -_-;;;


cocos3.0 에서 c++11 을 지원하는 부분은 크게 4가지입니다.


- std::function, including lambda objects for callbacks

- strongly typed enums, for most of the cocos2d-x enums and constants

- std::thread for threading

- override context keyword, for overriden methods


오늘은 std::function, lambda object 에 대해 설명하겠습니다.


위에서도 말했듯이 c++0x부터 최신 트렌드를 따라가기 위한 많은 노력이 있었는데


예를들어 java에서


{

    this.callback(new callback(){ Log.d(TAG, "CALLBACK!"); });

}


같은 코드를 자주 쓰셨을겁니다.


함수안에서 함수의 내용을 선언해서 사용하는 부분인데 c++에서는 해당 기능을 지원해주지 않아서 쓸데없이 header가 길어졌죠.


c++0x에서는 이걸 이렇게 지원해줍니다.


{

    this->callback([]{ Log.d(TAG, "CALLBACK!"); });

}


만세! 이제 .h 는 좀 더 깔끔해질겁니다!


기본적인 사용법은 [introducer]->return type(parameter){statement} 입니다.


parameter, statement 야 다들 아실테고 introducer 를 설명드리자면


이 람다에 외부 변수들을 어떻게 연결시켜줄지 선언하는 부분입니다.


1) 아무것도 넣지 않으면 외부 변수들을 쓰지 않겠다.


2) [=] 는 외부의 변수를 값(const)으로 사용하겠다


3) [&] 는 외부의 변수를 참조(*)해서 사용하겠다.


4) [this] 는 외부와 직접적으로 연결하겠다.


introducer는 좀 더 복잡하게 사용 가능합니다.


만약 


{

    int a, b;

    [=, &a](){ };

}


라면 외부의 변수의 값을 전부 가져오되, a만 참조하겠다. 라는 뜻입니다.


[&, b](){ }; 처럼 쓸 수도 있습니다.


return type 은 해당 람다가 값을 리턴할때 그 형을 명시해줄 수 있습니다.


(어떠한 형인지 확정할 수 없을때 java 에서 Object 를 쓰듯이, objective-c 에서 id 를 쓰듯이, c++0x에선 auto 를 쓸 수 있습니다.)


또한 람다 자체를 객체로서 보관할 수 도 있습니다.


function<void (int)> func = [](int n) { cout << n * n * n << " "; };


다음에는 threading 에 대해 알아보겠습니다.


참고자료 : http://scor7910.tistory.com/55

Posted by Yria

댓글을 달아 주세요

안드로이드 시뮬레이터가 많이 느린데


얘는 진짜 빠릅니다. 디버깅할때 많은 편함을 느낄 수 있습니다.



장점 - 


렌더링을 virtual machine 의 비디오 메모리로 하지 않고 PC의 것을 사용하기 때문에 부드럽습니다.


해상도를 마음대로 조절 가능합니다.




단점 - 


deviceid가 어떻게 나올지 잘 모르겠습니다


OpenGL을 사용할때 가끔 해상도가 깨져서 이상하게 나올 수 도 있습니다.





준비물 - 


1. virtualbox https://www.virtualbox.org/ )


2. 안드로이드 이미지


3. AndroVMPlayer


2번과 3번은 http://androvm.org/blog/ 에 가셔서 Download 페이지에 있는 이미지를 받으시면 됩니다.


2번은 vbox86tp version with gapps & houdini & flash 


3번은 AndroVMplayer archives - (OS별로 맞는 파일을 받으면 됩니다.)




설치방법 - 


1. virtualbox 를 설치합니다.


2. 2번파일을 실행합니다. 확장자가 ova 입니다.


3. 생성된 가상머신을 오른쪽 클릭하여 옵션 - 네트워크 에서 호스트 전용 어댑터로 변경하고 저장합니다.


4. 가상머신을 실행합니다.


5. 안드로이드 초기설정화면이 나옵니다. 아직 pc의 gpu를 사용하는게 아니기 때문에 많이 느립니다. 일단 어거지로 설정을 끝내고 인터넷 연결을 확인합니다.


잘 되면 성공, 그렇지 않으면 위의 네트워크 설정을 호스트 전용 어댑터가 아닌 브릿지 어댑터로 변경하고 다시 확인합니다.


6. 실행된 안드로이드 가상머신의 앱을 보면 AndroVM Config 란 앱이 있습니다. 이것을 실행하여 Hardware OpenGL 체크하고 저장합니다.


7. 실행된 가상머신을 종료합니다.


8. 3번파일을 실행합니다. 


9. Manual resolution 에서 원하는 해상도를 선택하시면 됩니다. 어떤 해상도이냐에 따라 타블렛UI 또는 일반UI가 나옵니다.


10. Virtual Machine to start 에서 아까 만든 가상머신의 이름을 선택합니다. 디폴트는 androVM_vbox86tp_4.1.1~~로 시작합니다.


11. Settings 로 들어가서 VM starts 를 In a GUI 로 바꿉니다.


12. Run 을 누릅니다. 앞으로 안드로이드 가상머신은 virtualbox를 통한것이 아닌 3번 파일을 통해 실행합니다.


끝!



안드로이드 개발시 디버깅을 원할때는 adb connect [가상머신 창에 씌여있는 IP]:5555 를 하시면 기존 에뮬레이터처럼 사용 가능합니다.

Posted by Yria

댓글을 달아 주세요

프로그래밍2011.07.17 07:46
자주 다니는 모 커뮤니티에서 회원들간의 분쟁이 자주 일어나는데

그 분쟁의 의도였든 의도가 아니었든 사용하는 사람 입장에선 빡빡하거든요...

그래서 애초에 분쟁거리를 만들지 않고자, 크롬 익스텐션을 만들었습니다.

이름하야 Hide ID for CUG!

문자 그대로 아이디를 입력하면 해당 아이디의 글이 보이지 않습니다! 

보이지 않기만 하므로 수동으로 입력하면 접속할 수 있고 목록에서만 보이지 않는다는 단점이 있지만

누군가에게는 도움이 되었으면 하네요.

차기버전으로 댓글지우기, 키워드 지우기도 고려해볼 예정입니다.

hideIdForCug.crx




이걸 계기로 언젠가 크롬 익스텐션 개발 포스팅을 올릴까 생각중.

일정 잡아서 지금까지 했던 모든 결과들을 포트폴리오 형식으로 만드는것도 고려중입니다.

최소한 누군가 나에게 너 뭐했니? 라고 물으면 내세울건 있어야지요.. 개발자가.. 

'프로그래밍' 카테고리의 다른 글

Hide ID for CUG  (0) 2011.07.17
Visual Studio 2010 에서 돌아가는 AssistX 10  (1) 2010.06.13
Posted by Yria

댓글을 달아 주세요

프로그래밍/PHP/JSP2011.02.09 14:25


http://code.google.com/intl/ko/android/c2dm/index.html

구글의 예제에 있는 코드는

안드로이드 앱에 의해 통제가 됩니다.

앱에서 신호를 보내고, 다시 앱으로 받죠.

다시 설명하자면,

앱-구글서버-다시 앱

의 구조로 되어있거든요.

이걸 조금 응용해서 서버에서 메세지를 던져 앱으로 받을수 있게 만들었습니다.

C2DM의 특성상 어플을 구동할때마다 다른 인증키가 나옵니다.

이것과, 개발자로그인 할때 나오는 인증키와 조합해야 push가 됩니다.

먼저 서버쪽 코드부터 보겠습니다.

언어는 PHP입니다.





HTTP_REQUEST 가 된다면 더 쉽게 구현가능하지만

현재 회사에서 쓰는 서버(cafe24)에는 이게 없네요. 전화해서 설치해달라고 하기도 귀찮고 fsockopen 을 이용했습니다.

$data = "&accountType=HOSTED_OR_GOOGLE&Email=******@gmail.com&Passwd=********&service=ac2dm&source=test-1.0";

먼저 구글개발자인증키를 위한 인자들입니다. 중요한건 accountType, Email, Passwd, service 입니다. accountType, service는 동일하게 입력하시고

Email과 Passwd는 개발자 이메일과 비밀번호를 입력합니다.

$fp = fsockopen("ssl://".$host, 443, $errno, $errstr, 30);

https 이기 때문에 443포트로 접속해야합니다. host는 말 그대로 호스트만을 입력하고 path는 아래에서 따로 입력합니다.

그 이후에는 Header값을 입력합니다. 이 과정에서 특별한 부분은 없습니다.

이렇게 하면 여러가지 결과값이 나오는데 이중 필요한건 'Auth=' 다음의 문자열입니다.

$tmp = split("Auth=",$responsecontent);

를 통하여 원하는 결과값만을 추출합니다.

이제 앱에서 나온 인증키가 필요한데, 해당 코드는 앱 부분에서 다루겠습니다.

$auth = "APA91bFl0a2gh963rI0y3Tu2vtF8PVCVCoixC****************************-9nDLDcVt83OIWawTL6JvDwzpToDjtA1WSjXLh8IYrsI";
이 부분에 앱에서 나온 인증키를 넣습니다.

$data = "&registration_id=".$auth."&collapse_key=1&data.msg=data";

이번에 서버에서 보낼 인자는 이게 답니다. data.<key> 로 사용자 임의대로 네임을 붙여서 데이터를 보낼 수 있습니다.

어플에서는 <key>를 통하여 값을 구별합니다.

fputs($fp, "Authorization: GoogleLogin auth={$result}\r\n");

Header 에 아까 구글 개발자 아이디로 발급받은 인증키를 보냅니다. 이게 없으면 에러가 뜹니다.

이 과정에서 출력값은 무의미하므로 서버에서 할 일은 끝입니다. 이제 남은건 구글에서 해당 앱으로 메세지를 PUSH하는 일만 남았습니다.

다음에는 어플리케이션의 코드에 대해 알아보겠습니다. 해당 부분은 다른 C2DM 강좌와 많이 겹치므로 다른분들의 코드를 참고하셔도 됩니다.
Posted by Yria

댓글을 달아 주세요

  1. 123

    안녕하세요 C2DM관련 서핑하다가 들르게 되었습니다
    먼저 포스팅 해주신 정보가 저에게 큰 도움이 되었습니다.
    개발하신 부분에 대해 궁금한게 있어서 질문드리려고 하는데요
    C2DM의 특성상 어플을 구동할때마다 다른 인증키가 나옵니다.라는 부분이 정확하게 어떤 부분인가요?

    구글 개발자 홈피에는 어플리케이션이 C2DM서버에 어플리케이션 ID랑 Sender Id를 보내면 등록ID를 보내주는데, 그걸 서드파티 서버에 보내면 된다라고 저는 이해했거든요 그 외에 C2DM서버에서 사용자에게 개인용인증키를 같이 보내주나요? 서버세팅부분에서도 개인 등록 ID에 대한 언급 없이 개인인증키부분을 언급하셔서 궁금해서 질문드립니다 ^^

    2011.03.07 17:42 [ ADDR : EDIT/ DEL : REPLY ]
    • 답변을 늦게드려 죄송합니다.
      제가 '인증키' 라고 썼지만 정확히 말하면 디바이스마다 어플리케이션을 설치하면 유니크한 key를 주게됩니다. 저는 이걸 인증키라고 적었습니다만 Auth의 개념이 있는건 아닙니다.

      후에 알게된 사실이지만 한번 등록하면 어플리케이션을 재설치하지 않는이상 key가 변하지 않는다는걸 알게되었고 DB에 저장해두고 호출하시면 되겠습니다.

      2011.03.14 22:55 신고 [ ADDR : EDIT/ DEL ]
  2. 유망주

    $auth = "APA91bFl0a2gh963rI0y3Tu2vtF8PV*************************************OIWawTL6JvDwzpToDjtA1WSjXLh8IYrsI";
    이줄에서 앱에서 가져온 registration id로 등록하면 되나요? 매번 설치마다 바뀌는것같습니다.
    정확히 원리를 잘모르겠네요;ㅣ;

    2011.07.12 16:01 [ ADDR : EDIT/ DEL : REPLY ]
    • 유망주

      삭제하고 키값 그대로하고 앱재설치 실행해도 잘되네요 감사합니다.

      2011.07.12 18:53 [ ADDR : EDIT/ DEL ]



수업 발표 프로젝트의 일환이었던

안드로이드 웹 게임 제작및 발표가 드디어 끝났습니다.

일단 여러명이서 각자 파트를 맞고

마지막에 합친다는 점부터 처음하는 시도였고,

그렇기 때문에 여러 우여곡절도 있었지만

발표가 끝났으니 너무 기쁩니다.

코드에 대한 설명 및 게임 소개는 방학때 차근차근 올릴 계획이고

더불어 시간맞출라고 대충 한 발코딩도 제대로 손봐야겠습니다.

Posted by Yria

댓글을 달아 주세요

  1. 마켓에도 올릴 예정이신가요?

    안드로이드가 아이폰에 비해서는 즐길만한 어플이 너무 없어서 저는 폰으로 겜을 잘 안해봤네요...
    한 번 해보고 싶군요 ㅎㅎ

    2010.12.05 04:45 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 영악

    수고하셨어요~^^

    2010.12.06 14:34 [ ADDR : EDIT/ DEL : REPLY ]

프로그래밍/PHP/JSP2010.11.22 11:35
가끔 유튜브에 자막파일이 함께 올라오는걸 볼 수 있습니다.

유튜브의 정책상 동영상업로드 따로 자막업로드 따로 할 수 있거든요,

그런데 가끔 그 자막을 받고 싶은데 영상 다운로더는 많이 보여도 자막 다운로더는 잘 보이지 않고

또 웹상에서 구현할 수 있다는 점에서 만들어봤습니다.

Youtube API 공부하시는 분들은 참고하시면 도움이 될듯.


	//input ; vid
	//output ; smi
		include_once "common/parser_php4.php";                       // 클래스 파일 include
		$sxml = "http://gdata.youtube.com/feeds/api/videos/$vid?v=2";
		$xml = file_get_contents($sxml);
		$parser = new XMLParser($xml);
		$parser->Parse();
		
		$title = $parser->document->media_group[0]->media_title[0]->tagData;
		
		$smi = "
					
					 $title 
					
					
					";
		
		
		$txml = "http://video.google.com/timedtext?v=$vid&type=list";
		$xml = file_get_contents($txml);         // 파싱할 대상XML 가져오기
		$parser = new XMLParser($xml);             // 객체생성 parser라는 객체를 생성함
		$parser->Parse();                                  // Parse()메소를 호출하여 xml을 dom 방식으로 파싱함
	
		$name = $parser->document->track[0]->tagAttrs['name'];
		$ln = $parser->document->track[0]->tagAttrs['lang_code'];
		
		
		$fxml = "http://video.google.com/timedtext?hl=$ln&lang=$ln&name=$name&v=$vid";
		$xml = file_get_contents($fxml);
		$parser = new XMLParser($xml);
		$parser->Parse();
		$xmlcap = $parser->document->tagChildren;
		
		foreach ($xmlcap as $entry) {
			$start = $entry->tagAttrs['start'];
			$start *= 1000;
			$smi = $smi."

"; $smi = $smi.$entry->tagData; $end = $entry->tagAttrs['dur']; $end = $start + $end*1000; $smi = $smi."

 "; } $smi = $smi."

";

코드 자체는 PHP로 구현하였습니다. 구조만 알면 누구나 쉽게 다른 언어로 바꿀 수 있을겁니다.

parser_php4 는 제가 php4 를 쓰는데 마땅한 XML파서가 없어서 웹에서 아무거나 주워왔습니다.

php5에는 기본으로 xml파서가 있는걸로 아는데 (simplexmlparesr였던가요?) 혹 필요하신 분이 있을까 해서 업로드 하겠습니다.

parser_php4에 대해 따로 설명드리지 않아도 될 정도로 간단하니 넘어가겠습니다.

http://gdata.youtube.com/feeds/api/videos/$vid?v=2
먼저 해당 주소에 $vid 에 video id를 넣어주면 동영상 정보가 XML로 제공됩니다. vid는 다들 아시다시피 "https://www.youtube.com/watch?v=vWH9dEfr8dI" 에서 v=다음에 오는걸 말합니다.

여기서 제목을 추출합니다. 동영상과 자막은 따로 관리가 되고 업로더도 다르기 때문에 번거롭지만 동영상 제목을 얻어내기 위해서 이렇게 해야합니다.

parser_php4 에서는 namespace 별로 xml을 파싱해주지 않기 때문에 "$parser->document->media_group[0]->media_title[0]->tagData;" 같이 번거롭게 접근했습니다만, 이름을 보시면 대충 어디의 부분인지 아실겁니다.

다음,
http://video.google.com/timedtext?v=$vid&type=list
는 해당 동영상에 첨부된 자막들의 정보를 보여줍니다. 유튜브 정책상 한 동영상에 여러 언어로 된 자막을 올릴 수 있으므로 여기서 적절히 원하는 것을 필터링해갑시다.

track 안의 name 애트리뷰트와 lang_code 애트리뷰트는 각각 자막파일의 이름, 언어를 뜻합니다. 이제 원하는것을 얻어냈으니 다음으로 갑니다.
http://video.google.com/timedtext?hl=$ln&lang=$ln&name=$name&v=$vid
이번에는 위의 주소에 hl="언어"&lang="언어"&name="이름"&v="비디오ID" 를 넣어 다시 파싱합니다. 이제 사용자가 원하는 자막이 나왔습니다.

그런데 자막이 XML로 되어있네요? TIMEDTEXT 형식으로 구성되어 있어서 기존 플레이어에서는 다른방법을 사용해야합니다. 대중적인 SMI방식으로 바꿔보지요.

		foreach ($xmlcap as $entry) {
			$start = $entry->tagAttrs['start'];
			$start *= 1000;
			$smi = $smi."

"; $smi = $smi.$entry->tagData; $end = $entry->tagAttrs['dur']; $end = $start + $end*1000; $smi = $smi."

 "; }


TIMEDTEXT 는 초단위로 구성되어 있기 때문에 마이크로초단위인 SMI를 위해 1000을 곱해줍시다. dur은 자막이 나오는 시간이므로 dur만큼 지난 후에 "nbsp;"를 출력해 자막을 사라지게 합시다.

이제 끝입니다.

더 자세한 내용은 Youtube API 페이지로 가셔야 하겠지만 자막을 얻어내는 부분만큼은 유튜브에 없더군요.. 결국 구글링해서 얻어내긴 했지만 모쪼록 다들 좋은 결과를 얻어내길 바랍니다. :)

덧. 티스토리 에디터가 태그를 멋대로 바꾸네요. 쩝... 그래서 원본파일도 첨부합니다.

Posted by Yria

댓글을 달아 주세요

  1. 유튜브에 자막 따로 올릴 수 있다는 것도 이제야 알았을 뿐더러 ㄷㄷㄷ
    뭔가 대단하시네요

    2010.12.05 04:43 신고 [ ADDR : EDIT/ DEL : REPLY ]

http://dev.naver.com/projects/spaceopera/

해당 페이지로 가면 자세한 사항을 확인할 수 있습니다.

웹게임은 처음이라 다들 고생하네요

거기에 학과공부도 해야하고

으음.... ㅠㅠ
Posted by Yria

댓글을 달아 주세요


학교 수업 프로젝트의 일환이지만

학기중엔 일단 점수따기용으로 만들고

제대로 꾸며서 담학기 시작전까지 마켓에 등록해볼까 합니다.

장르는 전략시뮬! 배경은 SF! 

진행은 웹게임의 형식을 빌려왔습니다.

왠지 디자인을 하면 할수록 어디서 본 거 같은 컨셉들...;;



개인적인 의견이지만 이미 새롭게 나오는건 한계에 다다랐기 때문에

이미 있는 컨텐츠를 재생산하는것도 의미가 있다고 생각합니다.

모던2도 문명5도 WOW도 최초는 아니잖아요?!


어쨌든 프로젝트를 진행하면서 있었던 문제점, 노하우들을 공유하고자 합니다.

좋은 의견 주시면 겸허히 받아들이겠습니다.


특히 코딩쪽은 젬병이라 쉬운길 냅두고 돌아가는 멍청한 짓을 자주 볼듯...


(프로그램 초기 디자인, 계획등등은 나중에 따라 proto version으로 내놓겠습니다.)


일단 책이 당장 없어서 오늘은 기본적인 UI디자인만 했습니다.

첫 화면에 배경 띄우려는걸 ImageView로 하려고 삽질하다가.. EditText가 묻히더라고요. 순서를 바꾸면 EditText가 위로 올라오고..

이걸 리니어말고 절대값으로 할까 생각했는데 리니어레이아웃에 background 옵션을 주면 되더라고요.

이럴수가 -ㅅ-







일단 텍스트 박스랑 버튼을 가운데다 배치했는데 아래로 내려가질 않네요?

gravity 로 bottom주면 될 줄 알았는데 안의 Hint옵션의 텍스트만 움직이고..

또 크기를 px로 주니까 해상도가 다른 기계로 보니까 크기가 확 작아져요.

크기 관련해서 책에다 적어놨는데 내일 학교가서 가져와야할듯 ㅠㅠ

package com.apps.spaceopera;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class SpaceOpera extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	EditText InputId;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        
        InputId = (EditText)findViewById(R.id.InputId);

    }
}

java안은 그냥 onCreate밖에 없습니다.

머리속에 생각해둔건 많은데 작성하려고 하면 빡치고.. 끙...
Posted by Yria

댓글을 달아 주세요

프로그래밍2010.06.13 15:48


이거 없으면 불편해서 못써요 ㅠㅠ

기존버전과는 다르게 2010에서는 사용자가 만든 toolkit을 추가 할 수 있더군요.

vsix라는 확장자로 돌아가는데

그래서 기존의 버전과 설치법이 조금 다릅니다.


해당 파일을 다운로드해서 실행하면 설치가 됩니다.

기존버전과 호환되는게 아니니 유의하시고

지울땐 Tool -> Extension Manager 가셔서 삭제하면 됩니다.

'프로그래밍' 카테고리의 다른 글

Hide ID for CUG  (0) 2011.07.17
Visual Studio 2010 에서 돌아가는 AssistX 10  (1) 2010.06.13
Posted by Yria

댓글을 달아 주세요

  1. 라제베크

    트랙백 걸었습니다. (^-^)/

    2010.09.05 22:35 [ ADDR : EDIT/ DEL : REPLY ]






프레젠테이션에도 나와있지만 OSPF는 라우터에서 쓰는 기법입니다.

Dijkstra 알고리즘을 이용해 가상 시뮬레이션을 구현해보았습니다.

지금 생각해보면 이때가 가장 즐거웠지 않을까 싶습니다.

시간은 촉박했지만, 정말 생각해볼 수 있는 여러가지를 응용해봤거든요.

잘 쓰지는 않지만 Vector 라든지, 인접리스트, 우선순위 큐 등등

Data structure쪽은 뇌자알을 많이 참고했습니다.

이 자리를 빌어 책의 저자님께 감사의 메세지를.

씬횽 땡큐 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

중간고사만 잘 봤어도 A+일텐데 ㅠㅠ

세종대학교 2009년 2학기 송오영교수님의 알고리즘 수업의 기말 과제로 제출되었습니다.

행여나 이 과제를 베껴서 얻는 피해를 저에게 따지지 마세요.

프로그램은 여기서 공개하고

소스는 따로 정리해서 올릴 생각입니다.
Posted by Yria

댓글을 달아 주세요

  1. 참 잘했어요 ^^

    2010.09.29 13:50 [ ADDR : EDIT/ DEL : REPLY ]
    • 오오 씬횽이 집적 나타나다니!

      덕분에 알고 시험&프로젝트 잘 봤음 흐흐

      2010.10.06 23:36 신고 [ ADDR : EDIT/ DEL ]