티거의 개발 공간

월드에딧


월드에딧 플러그인은 건축에서 단순 작업이나 입체적인 모양을 구현할 때 쉽게 제작하도록 도와주는 플러그인이다.

이 플러그인을 연동하면 월드에딧에서의 첫번째 지점과 두번째 지점을 선택한 지역을 불러오는 등 월드에딧 기능을 자신의 플러그인에서 사용할 수 있게 된다.

우선 월드에딧을 연동하기 위해서는 사용하는 또는 사용하고자 하는 월드에딧 플러그인을 다운로드하여 자신의 버킷의 플러그인에 넣어두자, 

연동했을 때 주의점은 꼭 그 연동한 플러그인이 자신의 버킷의 플러그인안에 있어야하고 서버에 인식되어야한다. 그렇지 않다면 플러그인의 기능을 사용하려 하는데

플러그인을 찾을 수 없기에 오류가 발생한다.


연동



프로젝트에 라이브러리로 월드에딧을 추가하기 위해 Build Path에 들어간다.



위와 같은 윈도우에서 'Add External JARs' 를 눌러 월드에딧 파일을 추가한다.


이 단계를 거치면 자신의 프로젝트 안에서 월드에딧의 기능을 사용할 수 있게된다.




1
2
3
4
5
public WorldEditPlugin getWorldEdit() {
    Plugin p = Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
    if (p instanceof WorldEditPlugin) return (WorldEditPlugin) p;
    else return null;
}
cs


위의 메서드는 월드에딧 플러그인을 불러오는 메서드이다. 필자는 한번 사용할 때 onEnable() 메서드에 플러그인이 활성화 될 때 한번만 불러오게 한 후 변수에 저장해서

계속 사용한다.


1
Selection sel = getWorldEdit().getSelection(Player);
cs


위의 메서드를 호출하여 플레이어가 선택한 두 지점으로 정의된 구역을 받을 수 있다.

물론 이 정의된 구역으로 첫 번째 지점과 두 번째 지점 모두 구할 수 있다.


1
2
3
Selection sel = getWorldEdit().getSelection(Player);
Location pos1 = sel.getMaximumPoint();
Location pos2 = sel.getMinimumPoint();

cs


위처럼 pos1은 첫 번째 지점, pos2는 두 번째 지점이다.


1
2
3
4
Selection sel = getWorldEdit().getSelection(Player);
if(sel.contains(player.getLocation()){
    player.sendMessage("구역 안에 있습니다.");
}
cs


이런 식으로 위치값이 구역 안에 있는지도 파악 할 수 있다.


만약 플레이어에 의해서 정의된 구역 뿐만이 아닌 자신의 플러그인 상에서 구역을 정의하고 싶다면


1
2
3
Location loc1 = new Location(Bukkit.getWorld("world"), 0,0,0);
Location loc2 = new Location(Bukkit.getWorld("world"), 5,5,5);
CuboidSelection sel = new CuboidSelection(loc1.getWorld(), loc1, loc2);
cs


이렇게 새로운 구역을 정의할 수 있다.


1
getWorldEdit().setSelection(player, sel);
cs


위의 메서드는 플레이어가 정의한 구역을 플러그인 내부에서 임의로 교체할 수 있다.


이 이외에도 많은 기능들이 있지만 필자는 모든 내용을 이 게시글에서 다룰 수 없다.

필자는 많이 사용하는 기능들만 적어놓았고 아래 예시 프로젝트를 첨부했으니 참고바란다.







코딩 예시

우선 필자는 아래의 코딩 예시를 먼저 들어 설명을 시작하고자 한다.


1
2
3
4
5
public class Main{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}
cs


위의 예시는 프로그램을 실행했을 때 'Hello, World!' 라고 출력하는 가장 기초적인 프로그램이다.


코딩 방법


위의 예시를 계속 인용해 설명하겠다. 우선 코드는 블럭을 이해해야한다. 블럭이란, 중괄호 { 나 } 로 묶여있는 한 덩어리를 의미한다.


1
2
3
4
5
public class Main{ //첫번째 중괄호 시작
    public static void main(String[] args){ //두번째 중괄호 시작
        System.out.println("Hello, World!"); //세미콜론
    } //두번째 중괄호 
//첫번째 중괄호 끝
cs


이렇게 블럭은 시작과 끝이 정확히 존재해야하며 시작과 끝이 정확하지 않을 경우 오류가 발생한다.


그 다음으로 세미콜론( ; ) 이다. 세미콜론은 실행할 코드의 끝을 맺을 때 사용하는 문자다. 국어 문법에 비유하자면 마침표(.) 와 같다고 할 수 있다.

세미콜론을 찍지 않는다면 해당 코드의 끝은 정확해 지지 않아 오류가 발생한다.


첫번째 중괄호는 '클래스' 인 Main의 블럭이다.

Main 클래스 블럭 안에 무언가 생성된다면 그것들은 모두 Main에 소속된다.


두번째 중괄호는 '메서드' 인 main의 블럭이다.

이 메서드는 프로그램이 실행될 때 가장 먼저 실행되는 메서드이다. 메서드에 붙어있는

(String[] args) 는 메서드 호출에 필요한 '인자'이다. 이 부분은 아직 우리가 손대지 않을 것이므로 용어에 대해서

알아가기만 하자.


변수


변수는 프로그램이 실행되는 중 바뀔 수 있는 유동적인 값을 의미한다.

변수는 아래와 같이 선언할 수 있다.


1
int i = 0//선언 후 0으로 초기화
cs


1
2
int i; //선언
= 0//변수에 0 
cs


위처럼 두 가지 사용법이 있다. 기본적으로 int 는 해당 변수의 형(形)이다. int 는 정수형으로 정수만 대입될 수 있다.

그리고 i 는 변수의 이름이다. 선언 후 아래코드에서 i라는 이름으로 변수 사용이 가능하다.

= 는 이후 연산자 파트에서 언급하겠지만 '대입 연산자' 라는 연산자이다. 


1
2
3
4
5
6
public class Main{
    public static void main(String[] args){
        int i = 0;
        System.out.println(i);
    }
}
cs


위는 변수의 사용 예시이다. 메서드 안에 정수형 변수인 i가 선언되고 0으로 초기화됐다. 그리고 아래에서 변수 i를 출력하고 있다.

이 때 이 프로그램의 결과는 '0' 이라고 출력한다.


여기서 가장 중요한 것은 변수의 '명명(命名)규칙' 이다. 4개가 존재하니 아래 언급하는 4개의 내용은 모두 숙지하자.


1. 대, 소문자가 구분되며 길이에 제한이 없다.

2. 예약어를 사용해서는 안된다.

3. 숫자로 시작해서는 안된다.

4. 특수문자는 '_'와 '$' 만 허용된다.


1번은 변수의 이름이 Hello 와 hello가 있다고 한다면, 두 변수는 다른 변수로 인식된다는 것이다.

2번은 예약어가 무엇인지에 대해 알아야하는데 예약어는 위의 코드에서 자주 보이는 public, class, static, void 와 같이 보라색으로 하이라이팅되는 단어들이다.

이러한 단어들이 포함되는것은 가능하나, 한 예약어 자체가 변수 이름이 되어서는 안된다.

3번 'hello1' 과 같이 명명은 가능하지만 '1hello' 와 같이 명명은 불가능하다는 뜻이다.

4번은 변수 이름안에 'frame_hello' 와 같이 명명은 가능하지만, 'frame!hello' 와 같이 위에 언급된 두 특문이 아니라면 사용이 안된다.


형(形)


변수의 형은 크게 기본형과 참조형으로 나뉜다.


기본형은 다시 논리형, 문자형, 정수형, 실수형 으로 나뉜다.


 논리형

문자형 

정수형 

실수형 

 boolean

char 

byte 

float

 

 

short

double

 

 

int

 

 

 

long

 


아래 표는 변수의 형들이 받을 수 있는 값의 범위이다.


 형

 저장할 수 있는 값의 범위

 boolean

 false,true

 char

 \u0000 ~ \uffff

 byte

 -128 ~ 127

 short

 -32,768 ~ 32,767

 int

 -2147483648 ~ 2147483647

 long

 -9223372036854775808 ~ 9223372036854775807

 float

 1.4E-45 ~ 3.4028235E38

 double

 4.9E-324 ~ 1.7976931348623157E308


기본형들은 쓰다보면 외워지겠지만, 값의 범위는 외워지지도 않고 외우지 않아도 된다. 필자도 값의 범위는 책이나 인터넷을 참고한다.


참조형은 기본형을 제외한 나머지이기에 기본형을 모두 외우면 되지만, 참조형 중에서도 매우 잘 사용하는 형이 하나 있다.

'String' 이라는 문자열인데, 기본형인 문자 하나만 저장하는 char을 여러개로 배열하여 저장하는 참조형이다. 사용은 아래와 같이 가능하다.


1
String hello = "Hello, World!";
cs


 



1. 이클립스의 화면 구성

 

 

 

사용빈도가 높은 순서대로 (파일 수정 공간, 패키지 탐색기, 콘솔, 툴바, 클래스 파일 구성 확인) 인 것 같다.

이 사용 빈도는 개발자마다 다르겠지만, 필자는 이 순서대로 인듯 하다.

 

 

 

2. 프로젝트 (Project)

 

앞으로 새로운 프로그램을 만들 때 마다 프로젝트를 새로 만들게 될 것이다.

프로젝트 만드는 방법은 아래 순서를 따르면 된다.

 

 

왼쪽의 Package Explorer 창에 오른쪽 클릭 후

New - Java Project 를 클릭한다.

 

 

그러면 위와 같은 화면이 나타날 것이다.

상단의 빨간색 사각형 부분에는 프로젝트의 이름을 적는다.

(필자는 Example 이라고 적었다.)

그 후 Finish를 눌러 프로젝트를 생성을 마친다.

 

 

프로젝트 생성을 마치면 Package Explorer에 Example이라는 프로젝트가 나타난다.

빨간색 사격형으로 표시된 화살표를 누르면 사진과 같이 프로젝트의 내용이 보일 것이다.

 

3. 패키지(Package)

 

패키지는 간단히 '클래스 파일을 패키지라는 그룹으로 구분한다' 라고 생각해도 될 듯하다.

패키지 생성 방법은 아래와 같다.

 

 

프로젝트 파일 안에 src에 마우스 오른쪽 클릭 후

New - Package 를 클릭한다.

 

 

그럼 위와 같은 창이 나타나며

상단의 빨간색 사각형 안에 패키지 명을 쓴다.

대부분 메인 패키지명은 'com.닉네임.프로젝트명' 으로 적는다.

물론 아닌 경우도 있지만, 필자는 이렇게 적는다.

패키지명 작성 후 Finish를 눌러 패키지 생성을 마친다.

 

 

위는 패키지 생성이 완료된 모습이다.

안에 아무런 내용이 없고 빈 패키지이기 때문에 하얀 패키지 아이콘으로 나온다.

안타깝게도 아직은 코딩을 시작할 수 없다.

다음 단계인 클래스 파일을 만들어야만 코딩을 시작할 수 있다.

 

4. 클래스(Class)

 

 

클래스 파일은 생성하고 싶은 패키지에 커서를 대고

오른쪽 클릭 후 New - Class를 클릭한다.

 

 

그럼 위와 같은 창이 나타난다.

상단 빨간색 사각형 안에 클래스명을 적는다.


클래스명 적는 곳보다 위에 Package라는 항목이 있다. 저 항목은 지금 생성하는 클래스 파일이 어느 패키지에 생성될 것인지

적는 곳인데, 패키지 생성을 하지 않고 src에 직접 클래스 파일 생성을 시작하고저 Package에 패키지 명을 새로 적으면 없는 패키지를 생성하고 그 패키지에 바로 클래스 파일을 생성한다.

패키지 생성에 대한 얘기는 했지만, 이 방식대로 클래스를 생성한다면, 따로 패키지를 생성하는 작업은 건너뛰어도 된다.

실제로 필자는 패키지 생성부분은 건너뛰고 코딩한다.


중간에 public static void main(String[] args) 라는 체크 항목이 있는데

실행 가능한 프로그램을 만들기 위한 기본 메서드를 만들어주는 역할을 한다.

메서드는 이후 강좌에서 설명하기에 여기서 설명하지는 않겠다.

물론 실행 가능한 프로그램이 아닌 다른 목적으로 만들거나 직접 적어도 큰 상관은 없다.


필자는 사진에 나오지 않았지만 체크를 하고 마쳤다.

Finish를 눌러 생성을 마친다.

 

 


생성을 마치면 만들었던 Package가 하얀 아이콘에서 갈색 아이콘으로 변하고 그 안에 Main.java라는 파일이 생겼다.

그리고 중앙에 코딩하는 자리에는 생성한 Main 클래스 파일이 열려 코딩이 가능하게 되어있다.

여기까지가 클래스 파일의 생성과정이다.


다음 강좌는 본격적인 코딩으로 문자를 출력하고 변수를 다루어 볼 것이다.

 

 

1. JDK 설치

자바 프로그래밍을 시작하기 위해서는 Java Development Kit(이하 JDK)를 설치해야 한다.

이 JDK는 자바 개발사인 Oracle 사의 홈페이지에서 직접 받을 수 있다


>> 오라클 JDK 다운로드 페이지

>> http://www.oracle.com/technetwork/java/javase/downloads/index.html


위의 링크는 Oracle 사의 다운로드 페이지이다 위의 페이지에 접속 후 아래의 순서를 따르도록 하자

 

 

링크된 사이트의 첫페이지 화면은 위와 같다.
빨간색 사각형으로 표시가 된 저부분이 최신 JDK를 다운로드 한다는 건데
저곳을 클릭해보자 

 

 

 

그림 위와 같은 화면이 나오게 된다.
간색 사각형의 체크하는 부분(Accept License Agreement) 를 체크한다.
그래야 아래 JDK 설치 파일을 받을 수 있다.
체크 후 아래 파일들 중 자신의 운영체제에 맞는 JDK 설치파일을 다운로드한다.

다운로드 후 기본 설정대로 쭉 설치만 하면 문제 없이 원활이 설치가 될 것이다.

 

2. Eclipse 설치

 

JDK 설치를 완료했다면 Eclipse 를 설치해야 한다.
요즘 Eclipse를 .exe 파일로 설치 파일을 배포하기도 하지만,
필자는 .zip 파일로 배포되는 Eclipse 패키지를 받을 것이다.
어떤 것을 받든 간에 별문제는 발생하지 않는다.
다만 'Java EE Developers' 버전을 받아야 한다. 꼭!

>> 이클립스 다운로드 페이지

위 사이트는 공식 다운로드 사이트이다.

 

 

처음 접속하면 위와 같은 페이지가 나올 텐데, 대부분 빨간색 사각형이 표시된 곳을 보면
운영체제를 인식하여 다운로드 권장을 한다.
물론 자신의 운영체제 비트에 맞게 클릭하면 된다.

만약, 빨간색 사각형 쪽에 정상적으로 자신의 운영체제가 인식되지 않고 다른 운영체제 다운로드로 나온다면,
파란색 사각형이 표시된 곳을 클릭해보자.

 

 

파란색 사각형을 클릭해서 들어와 보면 오른쪽에 Download Links 라고 해서
여러 운영체제가 나열되어있다. 저곳에서 자신에게 맞는 운영체제를 클릭해도 상관없다.

 

 

마지막, 자신의 운영체제에 맞게 클릭을 하였다면 이런 페이지가 나타나는데
그냥 바로 DOWNLOAD 주황색 버튼을 클릭하면 다운로드가 시작된다.

 

 

다운로드 후 압축을 풀고 안에 파일을 보면 위와 같은 구조일 것이다.
위의 사진에서 선택해놓은 eclipse.exe 파일을 실행시켜보자.

 

 

실행하면 로딩 화면을 거쳐 위와 비슷한 팝업창이 나타날 것이다.
이후에 프로젝트 파일을 생성하고 저장하는데 쓰일 경로를 설정하는 건데,
필자는 이미 설정해놓았기에 초기 팝업과는 조금 다르다.

초기 팝업은 팝업창 아래에 'Use this as the default and do not ask again' 이라는 체크 항목이 있다.
이 항목은 위에 설정한 경로를 기본으로 사용하고 이후 실행할 때는 이런 경로 선택창을 띄우지 않는다라는 옵션인데,
켜질 때마다 물어보는 귀찮은 일이 생기기 싫은 사람이라면 체크하고 OK를 누르기 바란다.

 

 

 


OK 를 누르고 나면 위와 같은 화면이 나타난다. 딱히 볼 것도 없으니 오른쪽 상단의 Workbench를 눌러 작업환경으로 이동하자.

위까지가 개발 환경 구축 단계이다.
다음 강좌에서는 프로젝트, 클래스 파일에 대해 설명하고 변수까지 만들어보겠다.


 

이클립스는 한글폰트가 매우 이상하다. 한글폰트가 뭉개져 잘 보이지도 않는다.
그래서 필자는 컴퓨터를 포맷하거나 이클립스 프로젝트 폴더를 새로 생성하면 바로 폰트부터 바꾼다.

 


 

 

 

이클립스 상단바에서 Window  - Preferences 를 클릭하면 나타나는 창이다.
이 설정창 왼쪽 카테고리에서 General - Appearance - Colors and Fonts 를 클릭한다.

그리고 중앙의 카테고리에서 Basic을 열어 Text Font를 선택한 후 'Edit...' 버튼을 클릭한다.

 

 

필자는 네이버에서 배포하는 '나눔고딕코딩' 폰트를 주로 사용한다. 사용할 폰트를 선택한 후
'확인' 버튼을 누르고 설정창에서 OK 또는 Apply 버튼을 눌러 적용시키면 완료된다.

 

 

위의 사진은 '나눔고딕코딩' 폰트가 정상 적용된 모습이다.

 

 

p.s. 아무리 생각해도 코딩 기본 폰트는 Visual Studio가 짱이다...

아래 암호화 알고리즘은 여러가지 인코딩 방식을 제공해주고 있는 Apache Commons Codec
라이브러리를 사용한다. 이 라이브러리는 게시물 하단에 링크를 걸어두겠다.

 


 

 암호화 부분
인자값은 순서대로 (암호화할 문자열, 비밀번호 문자열) 이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public String Encryption(String str, String pw) throws Exception{
    byte[] bytes = pw.getBytes();
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(bytes);
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128, sr);
    
    SecretKey skey = kgen.generateKey();
    SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");
    Cipher c = Cipher.getInstance("AES");
    c.init(Cipher.ENCRYPT_MODE, skeySpec);
    
    byte[] encrypted = c.doFinal(str.getBytes());
    return Hex.encodeHexString(encrypted);
}
 
cs

 

 

복호화 부분
인자값은 순서대로 (복호화할 문자열, 비밀번호 문자열) 이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public String Decryption(String str, String pw) throws Exception{
    byte[] bytes = pw.getBytes();
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(bytes);
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128, sr);
    
    SecretKey skey = kgen.generateKey();
    SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");
    
    Cipher c = Cipher.getInstance("AES");
    c.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] decrypted = c.doFinal(Hex.decodeHex(str.toCharArray()));
    return new String(decrypted);
}
 
cs

 

 


 

 

실행 결과

 


 

하단은 Apache Commons Codec 라이브러리를 배포하고있는 Apache 페이지이다.

 

 

소프트웨어공학과 대학교연계 스터디그룹 과제로 모래시계 알고리즘을 분석하는
내용이 나왔다. 여러 언어로 구현할 수 있는 알고리즘이나, 내가 사용하는 주 언어는 자바이므로
자바를 이용해 구현해보겠다.
자바에서 모래시계 알고리즘을 구현하는 것은 꽤나 쉽다.

 


 

모래시계 알고리즘의 출력물은 아래와 같다

1234567
0234560
0034500
0004000
0034500
0234560
1234567

위처럼 2차원 배열에 모래시계 형태로 숫자들을 배열하는 것이 모래시계 알고리즘이다.
안타깝게도 int 배열에서는 빈공간을 출력하지는 못한다. 아무것도 채워지지 않은 공간은
null로 처리되어 출력되기 때문인데, 그런 상황을 피하고자 빈공간을 0으로 채웠다.

 


 

 아래는 모래시계 알고리즘을 구현한 소스코드이다.

 

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
30
31
32
33
34
35
36
37
38
39
40
41
public static void main(String[] args) 
    {
        int row = 7;
        int line = 7;
        
        int[][] a = new int[row][line];
 
        int c = (row/2)+1;
        int t, j, q = 0;
        int small = 1;
        int large = line;
 
        for(t = 0; t < row; t ++){
            q = small;
 
            if(small>1for(int y = 0; y < small-1; y++) a[t][y] = 0
            
            for(j = small-1; j<large; j++){
                a[t][j] = q;
                q = q+1;
            } 
 
            if(large<line) for(int z = large; z < line; z ++) a[t][z] = 0;
            
            if(t+1<c){ 
                small = small + 1;
                large = large - 1;
            } else { 
                small = small - 1;
                large = large + 1;
            }
        }
 
        for(int i = 0; i < row; i ++){
            for(int k = 0; k < line; k ++){
                System.out.print(a[i][k]);
            }
            System.out.println();
        }
    }
 
cs

 

행과 열의 정보를 갖는 row 와 line은 Scanner 변수를 이용해 입력을 받아 사용할 수 있다.
다만 이 모래시계 알고리즘은 행과 열이 홀수여야만 정상적으로 출력된다.

변수가 어떻게 변하는지 출력이 어떻게 되는지 한번 직접 손으로 써보면서 하면 더욱 잘 이해가 된다.

java.util.ConcurrentModificationException

이 예외는 흔히 List나 ArrayList를 for 문에 직접 집어넣고 돌리며 remove를 호출했을 때 발생한다.

1
2
3
4
5
6
ArrayList<String> list = new ArrayList<String>();
//~ ~ ~        
for(String name : list){
    list.remove(name);
}
 
cs

 

 위의 메서드를 실행할 때 예외가 발생한다는 건데,

위의 for 문은 list에서 index를 비교하며 그에 맞는 값을 name에 넣어주고 돌리는 식이다.
그런데 돌리는 도중 remove를 호출하면 기존 index 값과 remove 호출로 인해 줄어든 size 값이 맞지 않기 때문에 예외가 발생한다. 

 


 

해결법 [1]

 

1
2
3
4
5
6
7
8
9
ArrayList<String> list = new ArrayList<String>();
~ ~ ~
            
ArrayList<String> Remove = new ArrayList<String>();
for (String name : list) 
    Remove.add(name);
for (String name : Remove) 
    list.remove(name);
 
cs

 

 위의 예외를 피하기 위해서 삭제해야 할 리스트(이하 Remove)를 따로 만들고, Remove를 for 문에 집어넣어 돌려 list를 제거하는 형식이다.

하지만 이 방법은 효율적이지 않으며 속도도 느리다고 한다.

 


 

 

해결법 [2]

 

 

1
2
3
4
5
6
7
8
9
ArrayList<String> list = new ArrayList<String>();
~ ~ ~
 
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();
    iter.remove();
}
 
cs

 

 위의 방법은 반복자(Iterator)를 이용하는 방법이다.
.remove() 메서드보다 무조건 .next() 메서드가 먼저 호출되어야만 예외가 발생하지 않는다.
해결법 1보다는 이 방법이 더 효율적이고 쓸모없는 코드들이 없다 하니 이 방법을 많이 사용하는 것을 권장한다.

'Java > Java Note' 카테고리의 다른 글

자바 AES 암호화, 복호화  (0) 2017.04.02
자바 모래시계 알고리즘  (0) 2017.04.02
이클립스 테마 변경하기  (0) 2017.04.02
이클립스 기본인코딩 변경하기(UTF-8)  (0) 2017.04.01
자바 소켓통신하는법  (0) 2017.04.01