몇년만에 밑바닥부터 SpringBoot를 설정해서 개발하는지 모르겠다. 이하는 추후 활용을 위한 개인 기록용.

 

1. pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(중략)
 
<!-- Spring Boot 2.7.8 버전으로 활용 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.8</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
 
<!-- Mybatis Maven -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.2</version>
</dependency>
 
<!-- Maria DB -->
<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>2.7.11</version>
</dependency>
cs

 

maven dependency는 대략적으로 위와 같이 잡아주었다.

 

2. TestMapper.java / TestService.java / TestServiceImpl.java / TestController.java / TestSql.xml

1
2
3
4
5
6
7
8
9
10
package com.test.common.mapper;
 
import org.apache.ibatis.annotations.Mapper;
 
 
@Mapper
public interface TestMapper {
    public String getSysDate();
}
 
cs

 

 

1
2
3
4
5
6
package com.test.comm.service;
 
public interface TestService {
    String getSysdate();
}
 
cs

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.test.comm.service.impl;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.test.comm.service.TestService;
import com.test.common.mapper.TestMapper;
 
@Service
public class TestServiceImpl implements TestService {
    @Autowired
    TestMapper testMapper;
    
    @Override
    public String getSysdate() {
        String result = testMapper.getSysDate();
        return result;
    }
 
}
 
cs

 

 

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
package com.test.comm;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
 
import com.test.comm.service.TestService;
 
@RestController
public class testController {
    @Autowired
    TestService testService;
    
    @PostMapping("/test")
    public String test(@RequestBody String a) {
        String result = "";
        result = testService.getSysdate();
        System.out.println("============= :::: " +result);
        return null;
    }
    
}
 
cs
 
 
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.test.common.mapper.TestMapper">
    <select id="getSysDate" resultType="java.lang.String">
        select sysdate() from dual
    </select>
</mapper>
cs

 

 

1
mybatis.mapper-locations=mapper/**/*.xml
cs

 

패키지 구조는 다음과 같다.

com.test.comm.TestController.java

com.test.comm.service.TestService.java

com.test.comm.service.impl.TestServiceImpl.java

com.test.common.mapper.TestMapper.java

src.main.resources.mapper.TestSql.xml

 

application.properties 에는 mybatis.mapper-locations 을 설정해준다.

 

오류가 난 상황으로는 SpringBoot 2.7.8 버전에서 mybatis-spring-boot-starter를 3.x 버전으로 설정해주었더니, TestServiceImpl 에서 @Autowired로 설정한 TestMapper.java를 인식할 수 없다는 오류가 발생했었다.

여러 시행착오 끝에 SpringBoot 2.7.8과 mybatis-spring-boot-starter 3.x과 호환이 안되는것을 인지하고, 현재는 2.x 버전대로 맞추어주었다.

 

에혀 힘들었다.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

헤일로 4 (2012)

헤일로 3 에서 완벽한 끝맺음을 했다고 생각한 스토리가 어느날 새로운 트레일러로 돌아왔다. 반짝이는 빛무리가 알고보니 시냅스였다거나, 아득히 먼 메아리처럼 들리던 음성으로 좀 더 빠르게 움직이는 빛무리가 모이는 순간, 메아리가 Wake up, John! 이라는 음성으로 확연히 들릴때의 그 놀라움이란. 이렇게 헤일로4의 기대감은 엄청나게 커졌었다.

 

거기에 중간 광고로 만들어진 실사 영상화, Forward Unto Dawn의 영상은 정말이지 마스터치프 그대로 등장하던터라 기대감이 엄청났다.

그동안의 헤일로는 번지소프트에서 제작하였고, 이후 판권을 마이크로 소프트가 사들인 후 343인더스트리에서 개발을 새롭게 시작하게 된 것. 아마도 당연히 그럴것이, MS의 Xbox는 헤일로머신이라고 불려도 손색없을정도의 간판타이틀이었으니까. 
뭐 이것에 대한 논란은 어마어마하긴 한데 일단 제쳐두고.

 

Wake up John!

헤일로 3의 엔딩에서는 반파된 여명호에서 마스터치프가 냉동수면에 들어가게 되고, AI인 코타나가 이후 급박하게 깨우기 시작한다. 이유인 즉, 선조의 구조물에 반파된 여명호가 끌려들어가고 있다는 것.
이후 UNSC의 인피니트호에 구조되며 선조인 다이드액트로부터 지구를 구하자는 이야기가 주된 내용이다.

 

다이드액트, 국내판에서는 다이댁트라고 음역되는...

사실 선조의 떡밥은 과거부터 있긴 했으나 비중이 높지는 않고 숨겨진 요소로만 등장했기에 갑자기 뜬금없는 선조 이야기로 아주 당황스러웠다.
거기에 기존의 텍티컬스러운 각진 총기/방어구/차량 디자인들이 모두 둥글둥글한 공기역학적(?)인 디자인으로 바뀌기도 했고 코버넌트 세력과는 평화조약을 맺었다고 완결이 났으나 갑자기 일부 '해적' 코버넌트 세력들이 나타나질 않나, 알 수 없는 선조 이야기들이며 뭐며 아주 혼란스러움의 극치였다.
실제로 엔딩을 네댓번이나 보면서도 대체 이게 뭔소리여.. 싶을 이야기가 한두군데가 아니었다.

그리고 그놈의 뭔 버튼을 계속 누르라고 시키는 것인지. 그래픽은 확실히 XBOX 360을 풀 성능으로 갈구는 것 아닐까 싶을 정도였는데 생각보다 전반적인 스토리들이 조금 난해하다 싶었었다.
그래도 아직도 잊혀지지 않는 장면이라면, 처음에 선조 구조물에 착륙한 후 함선들의 잔해를 벗어나 마주하는 그 평원씬은 정말이지 웅장할 따름. 멀티플레이는 잠깐 즐겼으나 영 재미가 없어 맛들리지는 않았었다.


헤일로 워즈 (2013)

이후 난데없이 찾아온 헤일로 시리즈의 RTS 이야기로 이게 대체 뭔가 싶었으나 일단 구매를 하게 되었다.
대략적인 스토리는 헤일로 사건(코버넌트 조우 및 리치행성의 파괴)의 약 20여년 전으로 하베스트 행성에서의 이야기를 다루고 있다. 코버넌트를 마주하며 이들의 세력을 탈출하지 못하게 쉴드월드를 파괴하는 것. 소설에서나 접한 쉴드월드가 나오기도 했고, 패드로 무슨 RTS인가 싶었는데 의외로 쾌적해서 아주 놀라기도 했다.

 


그래도 전략시뮬은 영 내취향이 아니었던지 멀티까지는 하지는 않았던듯. 중간중간 나오던 실사화 컷씬이 아주 재미있었고, 스토리도 나름 괜찮아서 네댓번은 엔딩봤던 기억이 난다.
ODST 스킬을 사용하면 실제로 ODST 대원이 드랍포드로 강하하게 되는데, 이 스킬을 주로 사용했고 스파르탄 화력조의 분위기가 엄청나서 이 또한 자주 사용하기도 했었다.


추후, 헤일로 워즈 2가 발매되면서 더없이 행복했던 게임 중 하나.

헤일로 5 가디언즈 (2015)

어정쩡한 헤일로 4의 이야기를 뒤로하고 헤일로 5의 소식이 들려왔다. 공개된 홍보영상과 라디오 영상들이 기대감을 엄청나게 높혀주었다. 거기에 마스터치프는 배신자가 되었으며 해군정보국 ONI는 그러한 마스터치프를 체포할것이라는 내용. 이어지는 트레일러들에서는 쓰러진 마스터치프의 모습이라거나, 스파르탄 로크의 모습도 보이는 등 이 또한 대체 어떻게 흘러가는 것인지에 대한 떡밥이 무궁무진하게 쏟아졌다.
헤일로 4 에서 사용기한이 지난 AI 코타나의 썰이 풀려왔던터라 코타나와 관련된 것이라는 추측이 아주 신빙성이 있었으나...

 


대략적인 스토리로는 블루팀을 만나 임무를 수행중인 마스터치프에게 코타나의 환상이 보였고, 명령을 어기고 이를 찾아가게 된다. 이 와중에 코타나는 흑화하여 인류 AI들을 반란하게 만들었으며 코타나는 마스터치프를 자기네 편(?)으로 만드려 회유하지만 넘어오지 않았다. 명령 불복종에 따라 로크는 마스터치프를 쫓아가는 와중에 결국 선조무기인 가디언이 깨어난다는 것이 큰 스토리의 흐름인데... 대체 그래서 이게 뭔소린데 씹덕아, 소리가 절로 나오는 미친 수준의 스토리텔링이었다. 헤일로 4는 너무나도 많은 정보가 일시에 주입되는데다가 설명 또한 부족해서 문제였다면, 헤일로 5는 대체 이게 뭔소린지 정말 1도 모르겠다는 것이 가장 큰 문제였다. 그래서 로크는 왜 마스터치프를 쫓아다니는건지, 코타나는 왜 흑화를 한 것인지, 오시리스팀의 존재 의의는 무엇인건지, 그래서 블루팀은 어떻게 된 것인지 이 모든 이야기들에 궁금증만 남기고 엔딩이 나버린 것이다.


그나마 봐줄만한 점이라면 중간중간 인게임 컷씬이 아주 보기 좋을 정도, 말 그대로 헤일로 뽕 오지게 찰 정도로 좋았다는 것 뿐이며 그 개쩐다는 코버넌트들의 활동 인공지능 또한 퇴화할 정도.

 

워존 파이어 파이트 모드

그래도 헤일로 5의 스토리는 개막장중의 개막장으로 쫄딱 망해버렸지만 의외로 멀티플레이만큼은 정말 역대 헤일로 시리즈 중 최고였는데, 워존이라는 대형맵이 등장하면서 24인 멀티플레이를 지원한다거나 하는 식으로의 재미는 확실했었다. 비록 클래식 헤일로 시리즈와는 전혀 다른 스피디한 헤일로라서 비판은 상당히 많았지만 워존이라는 모드로 팀vs팀으로 싸우건, 팀vs코버넌트로 싸우건 뭘 해도 재미가 있었으니 이거 하나만으로도 500시간을 넘게 플레이하게 된 것이다. 거기에 단순한 인게임 무기가 아니라 각종 설정을 덕지덕지 붙인 특수능력 무기들이 많이 등장하다보니(물론 포인트 뽑기가 있어야 하지만) 워존모드에서 이걸 사용하는 재미 또한 쏠쏠한 편.

 

헬멧, 바이저, 갑옷등의 수백가지 조합을 제공하는데 이마저도 게임 내 재화로 구매가 가능하다니

사후지원도 역대급이었는데, 이 사후지원으로도 많은 멀티플레이어들이 존재하며 지금도 멀티서버가 운용되고 있다. 가장 기억에 남는 패치로는 인피니트의 무기고라는 패치로, 그 악명높은 헤일로1의 피스톨(두 발이면 죽는..)과 헤일로2 의 반동없는 배틀라이플이 패치되었었다. 지금도 헤일로5 멀티를 뛰고 싶을 정도이다.

이렇게 욕을 먹었으니 다음 헤일로는 괜찮겠지... 싶긴 했는데, 저렇게 수많은 떡밥들을 잔뜩 뿌려놓고 어떻게 회수할지가 아주 걱정이었다. 그래도 이렇게 될 줄은 몰랐었지만.

 

헤일로 워즈2 (2017)

헤일로 워즈의 스파르탄 컷씬을 생각나면 돌려보고 아주 가끔 헤일로 워즈를 새로 플레이하면서 워즈뽕을 채울 무렵, 헤일로 6에 대응하는 스토리로 헤일로 워즈2가 발표되었다.

헤일로 워즈의 약 30여년 이후, 헤일로 5의 1년 이후로 정신차려보니 스피릿 오브 파이어가 아크위에 표류중, 거기에 아크 표면에 구조신호가 잡힌것을 시작으로 브루트 세력인 배니쉬드와의 접점 - 헤일로 가동 -을 주로 다루고 있다. 이후 DLC 추가판까지 더하자면 배니쉬드의 지휘관이 실수(?)로 플러드를 깨우고 이를 저지한다는, 지극히 헤일로 스러운 스토리이다.

 


둥글둥글한 343 인더스트리의 디자인과는 다르게 기존, 그러니까 번지 소프트의 각진 디자인으로 총기와 아머, 차량의 디자인이 변경되었다. 이 사실 하나만으로도 당시 앞으로 나올 헤일로 인피니트까지 모두 기대가 되던 상황.
거기에 공개된 컷씬, 스파르탄이 브루트에게 쳐맞으면서 후퇴하는 모습은 일전의 헤일로 워즈에서 보여준 스파르탄 무쌍과는 전혀 대비되는 와중에, 이 브루트 세력이 헤일로 인피니트에도 나온다고 하니 기대가 안될래야 안될수가 없었다.

 

적을 죽이고, 포인트를 얻어 새로운 유닛을 얻는 블리츠 모드

헤일로 워즈에서도 마찬가지로 블리츠 모드가 아주 재미있었다. 여러명이서 하면 더 재밌지만, 혼자서도 어느정도는 즐길 수 있는 게임모드인데 사생결단과 같이 스테이지별 끝없는 적들을 죽이는 모드라고 보면 된다.
여러모로 시간때우기도 좋고 재미도 있는 모드라서 한 때 이 모드만 엄청나게 즐기기도 했었다.
더 많은 스토리를 DLC로 풀어낼 예정으로 보였으나, 그러지 못해서 매우 아쉬운 작품. 추후 헤일로 워즈3가 나왔으면, 하는 기대감이 아주 크기도하다.

+ 여담으로, 그 많은 물자들은 도대체 어떻게 운용되는건지, 스피릿 오브 파이어가 크지 않아보이는데 불구하고 차량들이나 보병들이 엄청나게 많이 등장하는게 그냥 재밌고 신기할 따름이다.


헤일로 인피니트 (2021)

그리고 말도많고 탈도많고 논란도 많은 헤일로 인피니트가 발매되었다. 발매되기에 앞서, XBOX Series X/S 콘솔 게임기기가 새로나왔으며 훨씬 오래전의 슬립스트림 엔진 테크영상으로 헤일로 인피니트의 내용이 일부 테크데모로 풀리기도 했었다. 과거 헤일로 4, 5와 헤일로 워즈2의 스토리와 어느정도 연계가 되는 만큼, 우주적 존재로 거듭난 코타나와 혼돈/파괴/망가로 혼란스러워진 스토리가 어떻게 정리되는지도 궁금해졌다.

 

우리가 기억하는 주임원사님의 모습 그대로

거기에 공개된 아트워크상으로는 기존의 둥글둥글한 디자인 대신, 각진 디자인으로(클래식 헤일로) 변경되는만큼 팬들의 기대감 또한 높아진데다가, 점점 더 공개되는 정보들에 따르면 오픈월드 헤일로니 클래식 헤일로의 흐름을 따라갔느니 하는 이야기들이 들려왔다.

 

아직도 사고싶은 한정판 에디션이긴 하다.

그러나,
마이크로소프트의 헤일로 인피니트는 대한민국에서 정식 패키지 발매가 이루어지지 않았고, 그와 동시에 해외에서는 엄청나게 빠른 속도로 매진이 된 헤일로 인피니트의 소장 한정판마저 출시되지 않았다. 이로인해 나는 일본 아마존을 통해 헤일로 인피니트 패키지를 구했다.
게임 발매와 동시에 운이 안좋게도(?) 코로나에 걸려 약 10일간 집에만 있어야했고, 그 사이에 헤일로 인피니트의 엔딩을 보아왔다.

 

최강의 마스터치프가 제압당하다니

그러나,
이전에 보여준 헤일로 4, 5편의 이야기는 그저 컷씬 하나와 대사 몇줄로 처리된것이 고작이었다. 비중이 아주 많았던 헤일로 5의 오시리스팀과 로크중령은 사라졌다. UNSC 인피니티호는 그냥 컷씬에서만 등장할 뿐이고 헤일로 역사상 가장 강력한 적이었던 에이트리옥스 또한 초반부 컷씬에 잠깐 등장하더니 죽었다는 한줄로 처리되고만다.
거기에 코타나가 깨운 가디언들은 그냥 또 없어졌다 -_-; 이쯤 되면 대체 이 게임의 스토리는 어떻게 흘러가는것인지 도저히 알 수 없을 정도.

 

풍광을 보는것은 좋으나...

07시설 제타 헤일로에 불시착(?)한 마스터치프가 흩어진 UNSC의 병력을 규합하며 07시설 제타 헤일로를 복구하려는 베니시드를 와해시킨다는것이 큰 스토리로, 중간에 만나는 AI 무기(weapon; 코타나 복사본)와 함께 메인스토리를 이끌게 된다. 알고보니 코타나가 막판에 개과천선해서 07시설 헤일로의 구조 일부를 폭파시켰다는 이야기라거나, 엔딩에서는 선조 엔드리스가 깨어난다거나 하는 이야기들이 있긴 한데... 스토리 DLC가 취소된 마당에 뭐 어떻게 흘러갈지는 이제 아무도 알 수 없게 될듯하다.

 

AI 무기

헤일로 팬으로써 아주아주 화가나고 짜증나는 포인트가 이 편에서 폭발하게 되었는데, 클래식 헤일로 시리즈부터 시작해서 각 편마다 약간의 시간차와 이어지지 않는 서브스토리가 존재하기는 했다. 
헤일로 1-2 사이의 이야기들은 특히 죽은 줄 알았던 사람들이 어떻게 살아있지? 하는 이야기들인데, 이 이야기는 몰라도 다음 헤일로를 즐기는데에 큰 무리가 따르지 않았다.
그런데 헤일로 4-5편, 헤일로 5-인피니트의 간격은 너무나도 말이 안되는것들 투성이였다. 그래, 백번 양보해서 나노입자로 만들었기 때문에 마스터치프의 묠니르 방어구들이 모두 새롭게 업그레이드되고 디자인되었다고 치자, 그놈의 선조는 갑자기 뿅 하고 사라져서 어디론가 사라지질 않나, 정신병걸린 시한부인생 코타나는 전 인류를 말살시키겠다고 설치며 UNSC를 폭격하질 않나, 그러더니 갑자기 나타나서 가디언들을 없애고 헤일로가 가동되는것을 막겠다며 복사본을 만들고, 헤일로를 뽀개더니 저는 죽었어요를 시전한다? 이 무슨 말도 안되는 말들만 지껄이는건지.

스토리를 이해하기 위해서는 소설과 코믹스를 읽어야한다는 것 또한 말이 안되고, 갈팡질팡 중구난방의 스토리는 어째 헤일로4 이후로도 그대로 아니 더 심해졌다. 여기에서 정이 뚝 떨어져버린 것이다.
오픈월드 장르가 요 근래 게임계에서 흥해서인지 아니면 헤일로 1의 오마쥬(실제로 헤일로1을 오마쥬한 포인트가 엄청 많긴 하다)로 이렇게 만든것인지는 모르겠다만, 그 넓은 헤일로에서 할 것이 없다. 보스급 적들을 다 죽이고나면 리스폰도 되지 않기에, 더 할것이 없어지고만다.

 

PC / XBOX 크로스 멀티플레이는 좋았으나,

그래도 멀티플레이는 잘 만들었겠지 하며 한동안 재밌게 멀티플레이를 즐겼는데 거진 반년 동안 제대로 된 업데이트 하나 없는 멀티플레이에 그만 많은 팬들이 실망하고 말았다.
헤일로5에서 많은 사람들이 좋아해준 워존/사생결단 모드가 없어졌고, 수많은 슈퍼웨폰들로 난전을 즐기기 좋았던 빅팀 피에스타모드 또한 헤일로 인피니트에는 없었다. 출시되고 2년, 이제서야 사생결단 모드가 시즌 내에 업데이트가 된다고 할 정도면 대체 무슨 자신감으로 이런 게임을 만들어낸 것이지?
이렇게 헤일로 인피니트는 XBOX를 사게만든 내게 있어 아주 큰 실망감을 안겨준 작품이 되었다.

그리고 이러한 생각이 들었다.
이제는 헤일로를 내 마음에서 놓아줄 때가 된 것 아닐까.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

헤일로 1 - 전쟁의 서막 (2004~2006)

헤일로 하면 역사적이라 생각하는 장면

헤일로 1 전쟁의 서막을 처음 접하게 된 것은 고등학교 2학년 무렵으로 당시 롯데마트의 게임 판매 섹션의 한 구석에 XBOX 콘솔과 헤일로가 시연대로 위치해있었다.
콘솔게임기에 대한 로망이 엄청나던 때라, 체험을 한 번 해보고 너무나도 갖고싶었었다. 당시의 엄청난 그래픽과 컨트롤러로 전해지는 손맛들은 일반적인 PC 게임에서 쉽게 경험할 수 없는 수준이었기 때문이다.

XBOX 콘솔을 사고싶었으나 가격이 가격인만큼 구매할수는 없었는데, 나중에 찾아보니 Windows PC 전용으로도 컨버전 되어서 구매 후 신나게 즐긴 기억이 난다.
대략적인 스토리로는 먼 미래에 코버넌트라는 외계인을 조우하고 엄청난 화력차로 인해 긴급히 피신하다가 헤일로라는 인공 행성에 착륙, 주인공이 헤일로에서 탈출하기까지의 여정을 풀어낸 게임이었다.

 

별거아닌 게임이라고 보았었는데 생각보다도 스토리가 나름 있는 편이었으며 나름 충격과 반전의 스토리라인이 있는 편인지라 아마 지금까지 대충 한 20번 정도 엔딩을 본 기억이 난다.
중간에 플러드가 출몰하는 미션은 분위기도, 소리도 모든 면에서 공포 그 자체였던터라 무서웠다.

 

멀티플레이를 참 많이도 했었다


대학생이 된 2006년에는 자취방에서 헤일로 멀티를 엄청나게 즐겼는데, 당시 PC 멀티는 레더가 있다기보다는 그냥 데스매치 같은 형태로 100킬을 어떤 팀이 먼저 하느냐,를 주로 겨루었는데 이 맵에서 스콜피온이라는 탱크로 학살하기를 아주 좋아했다.
나중에는 유저 커스텀 맵 까지 등장해서 별의별 글리치를 다 쓰기도 했었던 기억이 있다.

멀티플레이의 탈것들은 부서지지 않아서 진짜 운이 좋으면 양학이 가능해서 재밌었던 기억이 난다. 지금도 그 때의 기억이 새록새록할 정도.

이 게임을 계기로 충성스러운 엑전사가 되었...으나, 이는 곧 이어질 헤일로 인피니트 글에서 무참히 짓밟힐 예정이다.

+ 추후 헤일로 1은 발매 10주년 기념 리마스터링이 되었다. 가장 큰 변화로는 기존 구식 모델링의 교체로 인해 조금 더 화려한 효과를 주었다는 점. 거기에 버튼 하나로 클래식 헤일로 1과의 그래픽도 직접 비교가 가능하다는 점에서 좋았었다.

 


헤일로 2 (2013)

 

헤일로 2는 XBOX 전용으로 나온 터라 당시에 출시되자마자 즐길수는 없었다. 추후 헤일로3를 구매한 후에 불법 다운로드판으로 구해서 Windows로 즐기다가, 이후에 XBOX판 헤일로 2를 구매해서 즐긴 케이스.
E3 게임 트레일러가 너무나도 환상적이었던터라 헤일로2를 하지는 못해도 이 영상만은 주기적으로 찾아보면서 헤일로 뽕을 채웠었다. 나중에 구매해서 해보니, E3 트레일러의 장면은 게임 분량의 이유로 삭제가 되었다고.

 

사실 지금봐도 크게 나쁘지는 않은 텍스쳐라 생각하긴 하지만.

트레일러 영상의 그래픽과 게임 그래픽간의 괴리가 너무나도 심해서 현타가 좀 오지게 왔었고 거기에 헤일로 3를 하다가 2를 하게 되어서인지 너프된 그래픽 + 기종의 성능차이로 더더욱 현타가 온 아쉬웠다.
그래도 아비터와 마스터치프간의 교차되는 스토리와 이벤트 컷씬으로 이렇게까지 이야기를 풀어내는 능력에서 아주 놀라웠다. 거기에 헤일로 1에 비해 엄청나게 늘어난 총기들로 더더욱 재밌게 즐긴 편.

기존 헤일로 시리즈들에 비해 게임 볼륨이 엄청 늘어나서 엔딩을 보는데도 FPS 게임 주제에 약 3~40시간이 걸리는 것은 놀라울 따름이었다.

대략적인 스토리로는 헤일로 1의 직후로 헤일로에서 탈출한 주인공 마스터치프와 헤일로를 파괴하는것을 방관했다는 죄목으로 처형을 받게되는 아비터의 시점에서 시작하여 플러드의 지도자인 그레이브 마인드를 통해 헤일로의 진짜 용도르 알게 된다.
이후 헤일로를 발사하려는 코버넌트의 사제단을 배신한 아비터와 마스터치프가 협력하여 헤일로를 또다시 파괴한다는 것이 주된 스토리라인.

진짜 이 그래픽 그대로 실사영화 제대로 만들어줬으면 했는데... 파라마운트 나쁜놈들아

헤일로 1에서는 헤일로(04시설 알파 헤일로) 위의 이야기만을 다룬 반면, 헤일로 2는 헤일로(05시설 델타 헤일로)와 지구를 다루는 편에서 플레이어 입장에서 매우 눈이 즐거웠다.
여담으로, 중간에 ODST 대원과 함께 낙하하는 씬이 있는데 이 씬을 개인적으로 가장 좋아라한다.

+ 추후 헤일로 2는 발매 10주년 기념 리마스터링이 되었다. 비판이 꽤 많았던 헤일로 1 애니버서리와는 달리 실사 컷씬(아주 놀라움)과 헤일로5를 암시하는 컷씬, 보다 원작에 가까운 디테일링 구현 등으로 이질감이 없어져 보기 좋았다.

 


헤일로 3 (2007)


헤일로 3는 내가 군대에 있을 때 출시된 게임이었고, 당시 각종 일간지에서도 비중있게 다뤄질 정도로 인기가 대단했다. 군대에 있을 때까지의 꿈은 게임 개발자였으며 이를 위해 XBOX 360 아케이드를 구매, 100일휴가였나 뭐였나 나와서 헤일로 3만 주구장창 하다 복귀하기까지 했다.

XBOX에 비해 진일보한 그래픽으로 지금 다시 해도 손색없을 정도의 그래픽 품질을 보여주고 있으며 대형 전투씬들이 군데군데 배치되어있어 더더욱 즐겁게 했었다.
아직도 기억에 남는 장면은 여명호(Forward Unto Dawn)가 지상착륙을 하는 장면과 펠리컨 건쉽이 폭격을 하는 장면.

 

지금봐도 크게 나쁘지 않을 그래픽

대략적인 스토리로는 헤일로 2 에서 탐지된 아크의 존재가 알고보니 지구에 존재하고 있다는 내용으로 끝맺게 되는데 이를 위해 모두가 지구로 모이고, 지구에서는 아비터 엘리트 연합과 인간이 손을 잡고 침공한 플러드를 구제하는 와중에 아크를 통해 들어가 제작중인 08시설 헤일로를 파괴한다는 내용.
이후 헤일로 파괴의 후폭풍으로 타고 온 함선인 여명호마저 반쪽이 되며 주인공 마스터치프는 동면중인 상태로 우주에서 떠돌게 되는 운명에 처해진다.

 

어제의 적은 오늘의 아군

가장 좋아하는 무기는 당연히 배틀라이플과 코버넌트 카빈이지만, 중력해머 또한 손맛이 좋아 자주 사용했다.
아쉽게도 헤일로 2, 3에서는 돈이 없는 관계로 라이브 서비스에 미가입, 멀티플레이를 즐겨본 적이 없다는 점이다.
그리고 가장 좋아하는 씬은 아비터와 마스터치프가 한 편이 되어 서로의 등을 내어주던 그 씬이다.

 

헤일로 3 ODST (2009)

 

군대 전역 한 이후, 헤일로 3 ODST라는 게임이 신규로 출시되었다. 
대략적인 스토리로는 헤일로 2의 직후, 뉴 몸바사에서 코버넌트 함선이 슬립 스페이스를 통해 헤일로를 출발하는데, 이 때 여명호가 같이 껴들어간다. UNSC는 딱 이 시점에 지상으로 ODST 대원을 투입하는데 이 임무에 대해서는 극비인 상황.

스파르탄이 등장하지 않는 외전격인 작품인데, 사실 스킨만 ODST 대원일 뿐 큰 틀에서는 스파르탄과 차이가 없다. 그래봤자 쉴드라거나 넘어진 탈것들을 되세울 수 없다는 것 정도?
주인공 루키가 스토리를 진행하면서 옴니버스적인 성격으로 팀원들의 이야기를 듣는 방식인데, 중간중간 남아있는 오디오로그를 모두 모아야 비로소 이 이야기의 전말과 숨겨진 스토리가 무엇인지 제대로 알 수 있었다.

 

설정 이미지일 뿐이지만 개박살난 뉴 몸바사의 음울한 분위기가 게임 내에서 제대로 표현된다.


극 초반부의 ODST 드랍포드 강하씬과 후반부의 스토리는 정말 놀라울 따름이며 기존 헤일로 시리즈와 다르게 조용하고 우울하게 진행되는 게임 내 분위기는 이 분위기대로 잠입액션 하나 만들어주면 좋을텐데, 하는 환상을 갖기 충분했다.
지금도 OST를 듣는 게임 중 하나.

 

여담이지만 헤일로 시리즈의 트레일러 중, 가장 마음에 들었던 트레일러가 헤일로 3 ODST 에서 나오기도 했었다. 이건 뭐 지극히 개인적인 취향이지만.


헤일로 리치 (2010)

 

명실상부 헤일로 시리즈의 팬이라면 하나같이 손꼽는 명작중의 명작. 기존 헤일로 시리즈의 제작자 번지소프트가 만든 마지막 헤일로 시리즈이자, 앞으로 다시는 나오지 않을 헤일로 시리즈의 최고봉.

 


헤일로 1 스토리의 시작점 직전의 이야기로 소설에서나 나온 '리치행성'의 이야기가 주를 이룬다. 인류의 첫 코버넌트 조우를 그린 게임으로 외계인을 만난 후 급박하게 돌아가는 상황과 최후반부의 엔딩씬은 그야말로 남자라면 눈물을 쏟아버리지 않을까 싶을 정도.
컷씬으로만 존재하던 코버넌트 함선의 유리화 공격이라거나 함께 동고동락한 스파르탄 전우들의 전사, 대형 전투씬 등 게임을 진행하는 내내 지루할 틈이 전혀 없는 게임이기도 했다.

 

정말이지 스파르탄 노블팀의 희생이란..


스토리의 완결성 측면에서도 이보다 더 완벽할 수 있을까, 싶은 게임.


아직도 잊을만하면 시작해서 엔딩을 보는 게임이기도 하다. 4K 업그레이드가 된 후에는 눈이 더 호강하느라 재미진 게임. 외계에 대한 공포감을 자극하기 위해 일부러 '코버넌트의 더빙'을 하지 않았다는 점에서 제작진들의 노력이 엿보이기도 했다.


앞으로 343 인더스트리가 만드는 헤일로에서 이정도의 완벽함을 볼 수 있을까... 이젠 그럴일이 없겠지...

블로그 이미지

김생선

세상의 모든것을 어장관리

,

서든어택 (2006)

대학교 입학 후 하숙집에서는 친구들을 잘 만나 다 같이 어울려 놀기를 했었다. 당시에는 손대던 게임이 아주 많았으나, 친구들과 할 때에는 주로 서든어택을 했었다. 웨어하우스라거나 보급창고라거나. 나는 주로 스나이퍼를 도맡아 했었는데 이상하게 서든어택과 같은 PC FPS 게임은 잘 하지를 못하겠으나, 서든어택의 특정 맵에서는 스나이퍼를 참 잘 했었다.
지금은 이름이 기억이 나지 않던, 버스가 있는 다리 위 맵에서는 쐈다 하면 헤드샷이었고 옆에서 이를 보던 친구도 아주 놀라워 할 정도. 오래 한 게임은 아니었으며 이후에는 더 재미난 FPS 게임들(가령 헤일로)이 많아 2006년을 제외하고는 거의 하지를 않았다. 잠깐이지만 재미난 기억이 있던 게임이다.

 

당시에는 이런 플래시게임 같은 그래픽이 뭐가 재밌고 인기가 많았는지 도저히 이해가 가지 않았지만, 나이를 먹고 세상을 보는 시각이 조금 넓어지니 오히려 이러한 라이트한 게임이 인기가 많은것은 당연하다는것을 알게 되기도 했다. 

 

마비노기 영웅전 (2010 ~ 2012)

방패와 방어구 염색한다고 돈을 얼마나 들였는지...

군대 전역 후, 우리나라에도 드디어 콘솔게임같은 PC 게임이 나온다는 이야기로 흥했었다. 몬스터 헌터(당시에는 알지 못했던 게임)와 같은 부위파괴니 재료수급 및 제작이니 하는 말들로 세일포인트를 잡았던 기억이 있었다.
베타테스트에도 참가했고, 극초기부터 플레이를 한 만큼 이후 업데이트를 통한 호불호가 극명하게 갈리던 게임이었다. 게임 초반에는 리얼리티를 강조하겠다며 포션 1개당 4모금으로 나눠마실수 있으며 한 번 마신 포션은 상할 수 있으니 재사용이 불가하다거나 사용한 무기/방어구는 더러워지며 세척하기 전 까지는 깨끗해지지 않는다,와 같은 별 쓸모없는 설정들이 잔뜩 있었다.

데브캣에서 만든 게임이니만큼 적어도 그 당시의 시즌1 에피소드 까지는 스토리라인이 아주 탄탄하여 몰입감이 좋았으나, 시즌2가 업데이트 되면서부터는 도저히 몰입이 되지 않는 스토리로 게임이 망해가기 시작했다.
내가 주로 하던 캐릭터는 피오나 - 검방패, 린 - 창을 주로 했었는데 소형방패의 검오나는 헤비스텐더 스킬 발동시 이펙트와 소리, 밀려나가는 모션까지 너무나도 완벽해서 손맛이 좋았었다. 추후에 업데이트된 엘쿨루스 보스전에서 15인 파티원 중 14명이 전사했을 때 엘쿨루스의 가드불가 패턴을 제외한 나머지 패턴들을 모두 막아내며 파티원들의 환호를 받았던 것은 아직도 기억이 생생했다.

 

저 무기가 그 15강 그 무기 같은데

이후 게임을 접겠다며 10강짜리 주무기를 강화해서 폭발시키려고 계획했으나, 15강까지 업글이 되어버려서 강제로 접지못하고 써버렸던 일도 있었다. 그런데 이 계정은 해킹을 당했고...
친구가 엘쿨루스의 눈물을 먹으면서 돈을 줄테니 복귀하라고 꼬셨고, 새로 시작하면서 린 - 창무기로 새로 시작하게 되었다. 이 때 부터는 키보드 마우스 조합으로 플레이 하지 않고, XBOX 360 게임패드를 매핑해서 플레이를 주로 했었다.

게임 초반에는 위에서 언급한 불합리한 게임 시스템은 많이 개선되었으나, 난이도가 어렵다는 이야기가 많았는지, 보스몬스터들의 난이도들 또한 대폭 하락한 적이 있었다. 놀 치프틴이라거나 고블린 족장이라거나. 창을 통한 부위파괴도 있었지만 캐릭터들의 특수 공격 모션을 통한 부위파괴도 존재했다.
열심히 한 게임에 속하긴 한데, 이상하게 컨트롤이 구려서 그 흔한 콜라곰 버스도 남들 태워줄 실력이 되지 않았다 -_-;

이 게임을 하면서 소름돋았던 부분이 몇 포인트 존재하는데, 다크나이트 업데이트를 통한 다크나이트 변신씬이라거나 에피소드 중 '우리 모두를 죽여도', 마지막 에피소드인 카단의 흑화와 '여신강림' 이 부분이 가장 기억에 많이 남고 좋았던 시나리오 중 하나였다. 그런데 뭐, 지금은 그냥 야겜이 다 되어버린게 참으로 슬프지.


블레이드 앤 소울 (2012)

포화란 캐릭터 디자인은 지금 봐도 촌스럽지 않은 것 같다.

이후에 다 같이 마비노기를 하던 친구들이 건너가 NC의 블레이드 앤 소울을 시작하게 되었다. 당시의 NC는 지금처럼 흑화하기 전의 NC로 블소 또한 월 정액제 컨텐츠로 시작한 게임이었다.


당시 기준으로 그래픽이 매우 화려했고, 우리나라에서 보기 드문 무협 소재의 게임으로 아주 재밌게 했었...으나, TV의 유행어들을 NPC 대사로 고대로 박아넣어서 촌스러움을 떨칠 수 없기도 했었고, 정액요금제의 가격이 상당해서 결국 정식서비스를 시작한 이후에는 친구들 모두 리타이어하게 된 계기가 되었다.
그래도 나름 재밌었고, 핏빛 상어항의 포화란 캐릭터는 참 잘 만들어진 것 같은데, 지금은 어쩌다가 저렇게 게임이 망해버렸는지 참으로 아쉬울 뿐.


포화란 피규어 갖고싶다....

 

 

디아블로 3 (2012)

얼마나 지랄맞았으면 이런 짤도 나왔을까.

디아블로 시리즈의 최신작이 오래간만에 공개되면서 왕십리였나 어디에서 밤새도록 대기 후 구매한다느니, 연예인이 갖고싶다는 글을 쓰니 팬들이 조공을 바쳤네 하는 기사로 온통 들썩였을 때 였다.
원래 디아블로2를 좋아했다가, 공개된 디아블로3의 그래픽이 영 마음에 안들어서 안하려다 블소의 개같이 망함 후에 할 게임이 없어 구매 후 하게 되었다.

남들보다 대충 2주 정도 느리게 시작을 했었는데 리얼한 컷씬들과 디아블로 시리즈 특유의 파밍은 너무나도 재밌었다. 추후 만렙을 찍고나서부터는 본격 파밍에 들어갔었는데, 불합리한 엘리트 몬스터들의 스킬들과 내가 주로 플레이하던 악마사냥꾼의 너프로 인해 오래하지 않고 접었던 게임이기도 했다.
사실 디아블로2 처럼 적당히 어두침침하게 나왔으면 더없이 좋았으련만, 지나치게 밝은 톤으로 화사하게 나와버리니 이게 디아블로가 맞나? 하는 생각은 줄기차게 들긴 했었다. 뭐 시즌업데이트가 계속 진행되면서 많이 나아졌다곤 하지만, 그건 그거고 이건 이거인거지.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

아본의 엘시노 소드 앞에서. 저 엘시노 소드가 참 갖고싶었는데.

 

마비노기는 내 게임 인생 중 가장 오래한 PC 온라인 게임이라고 봐도 무방할 정도이다.

 

 


고2때 TV에서 틀어준 CF를 시작으로 마비노기를 시작했으며, 한창 디씨인사이드를 많이 했었던지라 디씨 마갤에 상주하면서 군대가기 직전 까지, 그리고 군대를 다녀오고 사회인이 되어서까지 오래오래 즐긴 게임이다.
마비노기의 흥망성쇠를 다 알고 있다고 한다면 당연히 거짓이겠지만, 나름 찬란했던 시절과 암흑기로 넘어가던 시절까지 즐긴 편이니 이정도면 상당히 오래한거는 맞다.

 

이 넓은 대륙을 엘로드 들고 걸어다닌 적도 있다;

마비노기를 시작하고 가장 재미있었던 때는 아무래도 새로운 종족인 엘프와 자이언트가 나오기 직전까지였다.
누적레벨과 스킬레벨로 대표되는 초창기의 마비노기는 잦은 환생으로 어빌리티 포인트를 모으고, 스킬을 수련하여 어빌리티 포인트를 소모하여 스킬 레벨업을 이루는 방식으로 되어있으며 장비들을 직접 제작, 숙련도를 통한 개조, 인챈트로 대표되는 장비 시스템과 극초기에만 호황(?)이었던 아르바이트, 나름 체계적인 시나리오 등으로 내 입맛에 쏙 들었었다.

 

축포 한가방 꽉채우는것은 국롤

성당 아르바이트를 하게 되면 축복의 포션을 구할 수 있었고 이 축포를 사용하게 되면 해당 장비의 내구도 소모량이 줄어드는 효과가 있었는데, 장비의 수리확률이 일부를 제외하고는 100%가 아니다보니 축포는 게임 내 필수적인 아이템이나 다름없었다.
쪼렙때는 부캐의 부캐를 돌려가며 축포 노가다를 했었고, 이걸 팔아치우면서 돈을 벌기도 했었다.
디씨 마갤러들을 만나며 장비도 허접하게 맞추기를 시작했고, 군대를 다녀오고나서는 아예 친구가 되었고 이 친구들은 10년이 지난 지금까지도 안부인사를 묻는 관계가 되었다. 게임에서 친구를 실제로 사귀다니, 아주 놀라울 정도.

 

한창 열심히 할 때의 스킬

마비노기는 직업 이라는 개념이 없었으며 (추후에는 재능 뭐시기 업데이트를 통해 직업적인 개념이 정립되긴 했다) 근접 스킬 / 활 스킬 / 마법 스킬 등 어떤것을 우선시하여 스킬레벨을 올리느냐에 따라 직업으로서의 개념이 존재했다.
거기에 스텟을 보정해주는 스킬들로는 생활 스킬이 있었는데 그 중에서 방직 스킬과 제련 스킬은 진짜 토나올 정도로 난이도가 빡세고 노가다도 엄청났던 기억이 난다. 뭐, 요즘은 엄청 쉬워졌다지만.

 

친구들과 아본 던전을 돌 때.

가장 기억에 남는 던전은 이멘마하의 룬다던전으로 몽환적인 BGM이 아주 인상적이었다. 극초기(이리아가 나오기 전)에는 그저 저승에 가서 빨간구슬 던전 노가다를 뛰는것이 최고라곤 했는데 그럴바에야 사람들 틈에 껴서 알비 상급 던전이나 마스 상급 심심하면 페카 던전에 꼽사리 껴서 가는 것이 그렇게나 재밌을수가 없었다.
대학생이 되고 나서는 월정액권을 결제하며 게임을 즐겼지만, 용돈이 그마저도 여의치 않을 때에는 일일 2시간 플레이를 수행한 후, 접속이 끊기기 직전에 던전에 쳐박아두고 아는 사람들과 수다떠는것이 그나마 유일한 낙이었다.
이 당시의 이 행동을 '나과장이 잡으러 온다'는 식으로 밈화 해서 이야기 했던 것도 있었다.

 

이 펫은 1살에 60레벨을 달성했다. 가히 최강의 펫.

이후 이리아가 업데이트 되면서 새로운 종족인 자이언트와 엘프가 새로 생겼고 별의별 스킬과 펫들이 본격적으로 대두되기 시작했다.
엘프는 활 스킬에 이점이 있는 종족이었고, 자이언트는 근접공격에 이점이 있는 종족이었다. 인간의 양손검은 자이언트에게 한손검으로 취급된다거나, 엘프는 걸음걸이가 빠르며 활 공격이 두 발씩 나간다거나 하는 소소한 차이점이 존재했다.

 

반신화

이 즈음부터는 본격적으로 마비노기 유저들에게서 돈을 빨아먹었던 때로, 어마어마하게 넓은 이리아 대륙을 그냥 다니기가 어려우니 날아다니는 펫이나 말 펫들이 엄청나게 출시되었다. 거기에 나중에는 공격력이 상당한 펫들 뿐만 아니라, 소환시 경직 공격을 주는 펫 까지 등장하여 이 펫이 없으면 파티에 안껴줄 정도의 밸런스파괴를 불러일으키기도 했다.
그리고 이리아 업데이트를 시작으로 마비노기의 시나리오는 산으로 가기 시작했고, 결국 나중에는 대체 뭔소릴 씨부리는것인지 도저히 이해하기 어려운 스토리들이 연이어 나오기도 했다. 그래서 브류나크가 어쨌고 반신이 어쨌고... 그래서 세익스피어는 왜 나온거더라? 아직도 그들의 관계는 이해할수가 없네.

초기의 G1~G3의 스토리는 각각의 연결고리와 반전 스토리가 숨어있는 등 치밀하고 탄탄한 스토리가 아주 좋았으나 후반부로 갈 수록 개연성도 떨어지고 설득력도 떨어지는 스토리들로 그냥 보상이나 구하려는 메인 스토리가 된 것이 참으로 아쉽다.

 

초기에는 빨구던전이 있었다면, 내가 접기 직전까지는 탈틴의 정찰하드가 있었다. 탈틴이라는 지역의 퀘스트(?) 중에, 정찰병 구출이라는 몬스터 리젠 퀘스트가 있었는데 여기 하드 난이도가 빠른 시간 내에 끝나고 보상도 상당히 좋은(우아한 건틀렛)편이었다. 허구언날 여기서 주구장창 수다떨며 놀기도 했던 아련한 추억이 있다.

 

그나마 이정도가 내가 가장 잘 꾸민거라거나..

나름 꾸미기가 메인 컨텐츠인만큼 귀엽고 아기자기한 그래픽들 사이에서 여캐 비율이 극도로 높은 편이었으나 나는 그러한 고만고만한 씹덕취향이 너무나도 내 스타일이 아니라서 대놓고 신기하게 생긴(?) 캐릭터들을 주로 만들었다. 또는 예쁜 반짝이 염색약들 보다는 어디서 아무도 쓰지 않는 염색약들을 잔뜩 모아다가 모든 파트에 발라서 나이트 사이키 조명과도 같은 모습으로 다닌다거나. 오히려 이러한 점이 내 마음에 들었을지도 모르겠다.

게임을 접기 직전에는 온갖 추악한 업데이트가 많았는데, 대놓고 파티플을 유도하는 교역이라거나 돈벌어먹을 상술로 대표되는 각종 캐쉬템들이 그러했다.
특히 세공이라는 것이 나왔을 때에는 사회적인 이슈가 될 정도로 문제가 많고 게임 내에서의 밸런스도 상당히 문제였을듯. 이후 게임을 접어서 지인을 통해 마비노기의 근황을 엿듣고는 하는데, 내가 했을 때와는 전혀 다른 게임이 되어버려서 대체 누굴 위한 게임인가, 싶을정도이긴 하다.
그나마 이제는 그 구닥다리 플라나리아 엔진인가 플레이오네 엔진을 언리얼로 바꾼다고 하니, 이제는 좀 더 나은 게임 환경이 되지 않을까 싶긴 하다.

말은 이렇게 했어도 게임 인생 중 가장 재미있게 즐겼던 게임임에는 틀림없다.
길드 정모도 몇 번이나 있었고, 지금도 연락하고 결혼식에 와줄 친구들을 만들었다거나 어디가서 술안주로 게임이야기를 하면 빠질 수 없는 추억을 만들어줬으니까.
지금 생각해보면 저런 게임을 다시는 못하겠지 싶긴 하다. 이 즈음부터, 우리나라의 게임 대세는 MMORPG가 아니라 한두시간 안에 끝날만한 게임들 위주로 대세가 기울기도 했고 말이다.

블로그 이미지

김생선

세상의 모든것을 어장관리

,

개발하는데 java 배치로 Windows Powershell을 파라미터 방식으로 호출할 일이 생겼다. 일단 powershell Script 코드는 다음과 같다.

 

1
2
echo 'TEST-1' $test
echo 'TEST-2' $userid
cs

대충 파라미터 두 개( test/userid)를 받아 echo로 찍어주는건데 기타 하위에는 물론 Azure Portal과의 통신이 있긴 하다. 근데 그게 중요한 것은 아니니까.

아무튼, java에서 파워쉘을 호출하는 소스코드는 다음과 같다.

 

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
//중략
 
final Runtime rt = Runtime.getRuntime();
 
//powershell.exe 명령어를 통해서, 해당 경로의 ps1 파일을 실행함
String commands = String.format("powershell.exe \"F:\\powershell.ps1  ");
 
Process proc = null;
String s = null;
 
// PowerShell 명령 시도 및 메시지 출력
try {
    proc = rt.exec(commands);
 
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream());
    while (( s = stdInput.readLine()) != null ) {
        System.out.println(s);
    }
 
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream());
    while (( s = stdError.readLine()) != null ) {
        System.out.println(s);
    }
 
catch (IOException e) {
    e.printStacTrace();
 
}
 
//생략
cs

요기까지는 잘 했는데, 위의 powershell 코드와 같이 parameter를 넘기는 방법을 구글링해보아도 죄다 제각기 방법이 달라서, 츄라이를 해보니 다음과 같은 소스코드로 성공했다.

 

위의 java 소스에서 commands를 다음과 같은 방법으로 변경해주면 된다.

1
2
3
4
5
6
7
//중략
 
String[] arr = {"test_msg" , "test_user"}
//powershell.exe 명령어를 통해서, 해당 경로의 ps1 파일을 실행함
String commands = String.format("powershell.exe \"F:\\powershell.ps1  " + arr[0+ " " + arr[1]);
 
//생략
cs

PowerShell 코드는 다음과 같이 수정해주면 된다.

1
2
3
4
5
$test = $args[0]
$userid = $args[1]
 
echo 'TEST-1' $test
echo 'TEST-2' $userid
cs

java 에서 공백문자열로 구분된 string 값들이 args로 잘 매핑이 된다.

 

테스트를 해보니 해당 ps1(powershell)을 호출할 때 각 String 형태의 parameter(arguments)들을 넘길 때, 그냥 공백문자열로 구분하는 것으로 보인다. 실제로 여러방법으로 테스트 해보니 잘 되기도 하고. 이로써 java로 powershell script를 parameter 포함하여 execute 하는것에 성공했다. 앞으로 근데, 이러한 플젝을 몇번이나 할 지는 모르겠지만 말이다 =_=;;

 

 

java - how pass string array as a parameters to a powershell 

블로그 이미지

김생선

세상의 모든것을 어장관리

,

한컴오피스의 한글파일(hwp)에서 텍스트 추출할 일이 생겼다.

대충 뒤져보니 대단하신 분 께서 한글문서 파서 라이브러리를 만드셨는데, 아직까지도 일부기능에 대해 개선작업을 진행중이신 것 같다.

뭐 표 라거나 그림파일 등에 대해서는 정상동작하지 않는 듯 하지만 나는 텍스트만 추출할 것이기 때문에 당장은 문제없이 사용가능할것으로 보인다.

 

자세한 지원범위는 이 분의 깃으로 들어가보면 될 듯.

https://github.com/neolord0/hwplib

 

GitHub - neolord0/hwplib: hwp library for java

hwp library for java. Contribute to neolord0/hwplib development by creating an account on GitHub.

github.com

아무튼, 대충 임포트하고 대충 써보기로 한다. 생각보다 텍스트 추출이 아주 잘 되어서 다행이다.

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/kr.dogfoot/hwplib -->
<dependency>
  <groupId>kr.dogfoot</groupId>
  <artifactId>hwplib</artifactId>
  <version>1.0.1</version>
</dependency>
cs

이렇게 잡아주고,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
* hwplib hwp document text extraction example
*/
 
import kr.dogfoot.hwplib.object.HWPFile;
import kr.dogfoot.hwplib.reader.HWPReader;
import kr.dogfoot.hwplib.tool.textextractor.TextExtractMethod;
import kr.dogfoot.hwplib.tool.textextractor.TextExtractor;
 
// 중략
 
HWPFile hwpFile;
String hwpText;
try {
    hwpFile = HWPReader.fromFile("/Users/kimfish/DEV/java_workspace/"+"test.hwp");
    hwpText = TextExtractor.extract(hwpFile, TextExtractMethod.InsertControlTextBetweenParagraphText);
 
    System.out.println("===== hwp text extractor =====");
    System.out.println("hwpText = " + hwpText);
catch (Exception e) {
    e.printStackTrace();
cs

이렇게 쓰면 된다. 개꿀

블로그 이미지

김생선

세상의 모든것을 어장관리

,

일전의 포스트와 마찬가지로 pdf 에서도 텍스트를 추출할 일이 생겼다.

당연하겠지만 해당 pdf는 ocr이 된 pdf를 기준으로만 추출이 가능하다.

 

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>2.0.24</version>
</dependency>
cs

이야 1년쯤 전에는 2.0.18 이었는데 그새 버전업했네. 아무튼 maven repository는 이렇게 잡아주고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* PDFBox library PDF text Extraction Example
*/
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
 
// 중략
 
try {
    File file = new File("/Users/kimfish/DEV/java_workspace/"+"/test.pdf");
    PDDocument document;
    document = PDDocument.load(file);
 
    PDFTextStripper s = new PDFTextStripper();
    String content = s.getText(document);
 
    System.out.println("===== docx text extractor =====");
    System.out.println(content); 
catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
cs

이렇게 하면 정상적으로 OCR 처리된 text가 추출된다.

 

 

 

블로그 이미지

김생선

세상의 모든것을 어장관리

,

아주 심플하게, 회사에서 해당 문서규격(xls/xlsx/doc/docx)에 대해 텍스트를 추출하는것이 필요했다. 일전에는 잠깐 해보았는데, 정리된 적이 없었고 이번을 계기로 좀 알게된 몇가지 사실들이 있기에 간단하게 기록해본다.

 

일단 메이븐에서 다음과 같이 라이브러리를 잡아준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-scratchpad</artifactId>
  <version>5.2.2</version>
</dependency>
 
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.2.2</version>
</dependency>
 
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>5.2.2</version>
</dependency>
 
cs

 

1. 워드 (doc/docx) 텍스트 추출

워드 2003 이전버전인 doc 와 이후 버전인 docx 를 추출하기 위해서는 두 가지만 기억하면 된다.

HWPFDocument 클래스는 Horrible Word Process Format 의 약자라는 점이며, poi 라이브러리만 상속받는것이 아닌 poi-scratchpad 라이브러리를 같이 상속받아야 한다. 즉, poi dependency만 잡아놓으면 HWPFDocument가 import 되지 않는다!

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
/*
* Word 2003 doc File Text Extraction Example
*/
 
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
// 중략
 
try {
    POIFSFileSystem poiFS = new POIFSFileSystem(
        new FileInputStream("/Users/kimfish/DEV/java_workspace/"+"/test.doc"));
    HWPFDocument hwp = new HWPFDocument(poiFS);
    WordExtractor we = new WordExtractor(hwp);
 
    String[] paragraphs = we.getParagraphText();
    System.out.println("===== doc text extractor ======");
    for (int i = 0; i < paragraphs.length; i++) {
        System.out.println(paragraphs[i]);
    }
 
catch (Exception e) {
    System.out.println(e); 
}
cs

 

docx 파일은 XWPFDocument를 import 받으며, docx의 text추출을 위해서는 poi 및 poi-ooxml 라이브러리에 대한 dependency가 필요하다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* Word 2007 docx File Text Extraction Example
*/
 
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
 
// 중략
 
try(
    FileInputStream fis = new FileInputStream
            ("/Users/kimfish/DEV/py_workspace/"+"/test.docx")) {  
    XWPFDocument file   = new XWPFDocument(OPCPackage.open(fis));  
    XWPFWordExtractor ext = new XWPFWordExtractor(file);  
 
    System.out.println("===== docx text extractor ======");
    System.out.println(ext.getText());  
}catch(Exception e) {  
    System.out.println(e);  
}  
cs

 

2. 엑셀 (xls/xlsx) 텍스트 추출

엑셀은 고려할 점이 상당히 많은데 각 셀/로우 별 텍스트 및 쉬트도 있는데다가 수식까지 가지고 있다. 현재는 샘플 토이 프로젝트라 수식이나 셀/로우 구분없이 텍스트만 가져오기를 수행해보았는데 일단 첫 쉬트에서는 잘 가져오고 있는듯. 좀 더 정교한 작업이 필요할 경우엔 공식 document 가 필요할것으로 보인다.

 

엑셀 2003 이전버전인 xls 같은 경우에는 poi Dependency 하나로도 잘 작동한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* Excel 2003 xls File Text Extraction Example
*/
 
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
// 중략
 
try (
    FileInputStream fis = new FileInputStream("/Users/kimfish/DEV/java_workspace/"+"/test.xls")) {  
    
    String result = "";
 
    HSSFWorkbook wb = new HSSFWorkbook(fis);
    ExcelExtractor ee = new ExcelExtractor(wb);
    result = ee.getText();    
 
    System.out.println("===== xls text extractor =====");
    System.out.println(result);    
catch (Exception e) {
    //TODO: handle exception
}
cs

 

하지만 엑셀 2007 버전인 xlsx 같은 경우에는 워드2007과 마찬가지로 poi / poi-ooxml dependency 둘 다 필요하다.

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
/*
* Excel 2007 xlsx File Text Extraction Example
*/
 
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
// 중략
 
try (
    
    FileInputStream fis = new FileInputStream("/Users/kimfish/DEV/py_workspace/"+"/test.xlsx")) {  
                
    // Workbook
    XSSFWorkbook wb = new XSSFWorkbook(fis);
            
    // Text Extraction
    XSSFExcelExtractor extractor = new XSSFExcelExtractor(wb);
    extractor.setFormulasNotResults(true);
    extractor.setIncludeSheetNames(false);
    
    System.out.println("===== xlsx text extractor =====");
    System.out.println( extractor.getText() );
catch (Exception e) {
    //TODO: handle exception
}
cs

 

일단은 이렇게 해서 정상적으로 출력되는것을 확인함. 어휴 poi 하나로 다 해놓든가 의존성을 걸어두던가. 왜 poi / poi-ooxml / poi-scratchpad 이렇게 세 개가 죄다 쪼개져있는지원;;

 

정리

xlsx - poi / poi-ooxml

xls - poi

docx - poi / poi-ooxml

doc - poi / poi-scratchpad

'어장 Develop > 어장 JAVA' 카테고리의 다른 글

[hwplib] hwplib을 이용한 한글파일 텍스트 추출  (1) 2022.07.06
[PDFBox] pdf 텍스트 추출  (0) 2022.07.05
[Tomcat 9.x] JNDI설정  (0) 2022.02.21
[PDFBox] java Image to PDF  (0) 2021.08.24
[xml] RestAPI XML Return (2)  (0) 2021.07.06
블로그 이미지

김생선

세상의 모든것을 어장관리

,

파이썬 개발을 하면서 가장 헷갈리는 개념이 디렉토리 참조법이다. 자바에서는 그냥 대충 import package.directory.fileName; 과 같은 형식으로 지정해주면 바로 가져다 쓸 수 있는데 반해, 파이썬은 그렇지 않은가보다.

 

아무튼 세 가지의 케이스에 대해 정리/적용해보았고 그 내용은 다음과 같다.

 

패키지 구성은 다음과 같은 형식으로 되어있다고 가정한다.

project
⌞ A_folder
   - a_file_1.py
   - a_file_2.py
 B_folder
   - b_file_1.py
   ⌞ C_folder
       - c_file_1.py
   ⌞ D_folder
       - d_file_1.py

1. 동일 경로상의 import

A_folder 내부의 a_file_1.py 에서 a_file_2.py 파일을 import 하기위해서는 다음과 같이 작성한다.

1
from . import a_file_2.py
cs

또는

1
import a_file_2.py
cs

이거는 쉽다.

 

2. 하위 폴더의 import 

B_folder 내부의 b_file_1.py 에서 C_folder 내부의 c_file_1.py를 import 하기 위해서는 다음과 같이 작성한다.

1
from C_folder import c_file_1.py
cs

이정도는 크게 어렵지 않다.

 

3. 상위 폴더의 import

여기서부터 많이 헷갈리게 된다.

C_folder 내부의 c_file_1.py 에서 D_folder 내부의 d_file_1.py를 import 하기 위해서는 꽤 여러가지 방법이 있으나, 일단 내가 해결한 방법을 위주로 작성해본다.

1
2
3
4
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from D_folder import d_file_1.py
cs

여기에서 os.path.dirname(os.path.abspath( 는 한단계 상위를 의미하며, C_folder의 한단계 상위인 B_folder로 이동함을 의미한다. B_folder 내부에 D_folder가 위치해있으므로, from d_folder 을 해주는 것.

 

마찬가지로 c_file_1.py 에서 A_folder 를 참조하기 위해서는 os.path.dirname(os.path.abspath를 두 번 작성해주면 될 것이다.

 

 

java를 하다와서 그런지, from~ 쪽도 잘 이해가 안갔고 __file__과 같은 옵션네이밍(?)의 정의도 익숙하지 않다. 일단은 해결했으니까, 다음 개발로 넘어가야지...

블로그 이미지

김생선

세상의 모든것을 어장관리

,