28 바닐라ui버전입니다. 참고용으로만쓰세요 ^^ [3] 나뭇잎총운영자 2010-08-07 19
27 최근 올라온 얼라이브팩 [3] 바니서버 2010-08-07 32
26 소스 비공개된 뽕데스 [천상팩] 바니서버 2010-08-07 11
25 에바팩 놀자수정 바니서버 2010-08-07 14
24 써니팩 수정본 바니서버 2010-08-07 7
23 혼몽ui2차[파티창까지] 바니서버 2010-08-07 5
22 블레스팩 점프팩 바니서버 2010-08-07 4
21 에바팩 메티스 수정본 Ver1.0 [1] 바니서버 2010-08-07 7
20 로우섭 팩 바니서버 2010-08-07 6
19 에바 쫄법사되는팩 [5] 풉서버메티스 2010-08-06 16
18 전직 및 뽕데스팩. [1] 슬픔 2010-08-06 12
17 3.0 • 쪼꼬 Pack Version 0.1 [3] 슬픔 2010-08-06 13
16 에바팩 메티스님 수정판입니다. [1] 슬픔 2010-08-06 10
15 그리스팩!! GM타임 2010-08-06 12
14 폭스팩!! GM타임 2010-08-06 12
13 에바팩! GM타임 2010-08-06 11
12 서니팩 풉서버메티스 2010-08-05 11
11 에바팩기반 메티스님이 손보신팩 [1] 풉서버메티스 2010-08-05 20
10 옵코적용태희업글~ [1] 미소사랑 2010-08-05 12
9 포더 구버전 팩 [3]
http://sofree.co.kr 에 더 많은 자료가 있습니다.
2010년 8월 11일 수요일
세금추가
특화상점, 깃털상점등에 세금이 적용되어서 세금 제외부분 추가 소스코드 올라오는것을 본적이 있으실겁니다.
아시다시피 세금은 해당 NPC의 지역(기란마을, 하이네마을등), 성의 세율에 따라서 계산이 됩니다.
그런데 무조건 npc를 기란마을에 세워놓는다고 무조건 기란성의 세금을 따라갈까요?
답은 no 입니다. 그렇다면 궁금한것은 각 성의 세금은 어떤 상점에 적용이 되느냐 인데요.
l1j.server.server.model.L1TownLocation.java에서 각 npcid별로 해당되는 지역을 돌려주고, 이 지역정보를 토대로 l1j.server.server.model.L1CastleLocation.java에서 위치하고 있는 성을 얻어냅니다.
npcid별로 해당되는 지역을 돌려주게 되는데, npcid가 source에 딱 정해져 있습니다. 임의로 생성한 상점은 어떠한 지역에도, 성에도 귀속되지 않습니다.
임의로 생성한 상점은 L1TownLocation.java에 해당 지역에 추가하지 않는한 어떠한 지역, 성에도 귀속되지 않는다고 말씀 드렸는데요. 그렇담 왜 세금이 추가가 될까요? 답은 세금계산 클래스인 l1j.server.server.model.L1TaxCalculator.java 에서 얻을 수 있습니다.
세금은 전쟁세금, 지역세금, 디아드세금, 국세, 성세금 로 구성이 됩니다.
지역세는 down table의 tax_rate + 2.
국세는 성세금의 10%
전쟁세는 15%
디아드세금은 10%
기본적으로 모든 상점의 경우 성세금, 전쟁세금, 국세, 지역세금을 추가하게 되어 있습니다.
그런데 어떤 성에도 마을에도 귀속되지 않는 상점에는 왜 세금이 붙을까요?
성세금이 0%니까 지역세도 당연히 0%입니다. 지역세또한 0%고요. 그러나 전쟁세는 15%입니다.
그러므로 전쟁세 15%를 정하는 WAR_TAX_RATES = 15; 부분을 WAR_TAX_RATES = 0;으로 변경하면 전쟁세가 0%가 되어서 성에도, 마을에도 귀속되지 않는 상점에 세금이 붙지 않게 됩니다.
정리하자면..
1. 임의로 생성한 상점(특화상점등)은 성, 지역의 세금이 붙지 않습니다.
2. 모든 상점에는 무조건 전생세가 붙게 됩니다.
3. 상점을 특정 성, 지역의 세금을 붙게 하려면 L1TownLocation.java의 해당 지역에 npcid를 추가해야 합니다.
4. L1TownLocation.java에 있지 않아서 어떠한 성에도, 마을에도 귀속되지 않는 상점은 세금도 적용받지않고, 성의 세금수입에도 영향을 주지 않습니다.
5. L1TaxCalculator.java의 전쟁세를 0으로 한다면 어떠한 성, 마을에 귀속되지 않는 상점의 세금은 0%이 됩니다.
제가 리니지 게임의 내용 이해가 적어서 그런데, 전쟁세 15는 어떤 용도인가요?
본섭에서는 어떠한 용도로 사용 되는지 궁금 합니다. 만약 전쟁세 15%가 무조건 적용되어야 한다면 전쟁세를 0으로 하고 지역세금에 전쟁세금을 추가하는 방법도 있겠네요.
http://sofree.co.kr/ 에 더 많은 자료가 있습니다.
아시다시피 세금은 해당 NPC의 지역(기란마을, 하이네마을등), 성의 세율에 따라서 계산이 됩니다.
그런데 무조건 npc를 기란마을에 세워놓는다고 무조건 기란성의 세금을 따라갈까요?
답은 no 입니다. 그렇다면 궁금한것은 각 성의 세금은 어떤 상점에 적용이 되느냐 인데요.
l1j.server.server.model.L1TownLocation.java에서 각 npcid별로 해당되는 지역을 돌려주고, 이 지역정보를 토대로 l1j.server.server.model.L1CastleLocation.java에서 위치하고 있는 성을 얻어냅니다.
npcid별로 해당되는 지역을 돌려주게 되는데, npcid가 source에 딱 정해져 있습니다. 임의로 생성한 상점은 어떠한 지역에도, 성에도 귀속되지 않습니다.
임의로 생성한 상점은 L1TownLocation.java에 해당 지역에 추가하지 않는한 어떠한 지역, 성에도 귀속되지 않는다고 말씀 드렸는데요. 그렇담 왜 세금이 추가가 될까요? 답은 세금계산 클래스인 l1j.server.server.model.L1TaxCalculator.java 에서 얻을 수 있습니다.
세금은 전쟁세금, 지역세금, 디아드세금, 국세, 성세금 로 구성이 됩니다.
지역세는 down table의 tax_rate + 2.
국세는 성세금의 10%
전쟁세는 15%
디아드세금은 10%
기본적으로 모든 상점의 경우 성세금, 전쟁세금, 국세, 지역세금을 추가하게 되어 있습니다.
그런데 어떤 성에도 마을에도 귀속되지 않는 상점에는 왜 세금이 붙을까요?
성세금이 0%니까 지역세도 당연히 0%입니다. 지역세또한 0%고요. 그러나 전쟁세는 15%입니다.
그러므로 전쟁세 15%를 정하는 WAR_TAX_RATES = 15; 부분을 WAR_TAX_RATES = 0;으로 변경하면 전쟁세가 0%가 되어서 성에도, 마을에도 귀속되지 않는 상점에 세금이 붙지 않게 됩니다.
정리하자면..
1. 임의로 생성한 상점(특화상점등)은 성, 지역의 세금이 붙지 않습니다.
2. 모든 상점에는 무조건 전생세가 붙게 됩니다.
3. 상점을 특정 성, 지역의 세금을 붙게 하려면 L1TownLocation.java의 해당 지역에 npcid를 추가해야 합니다.
4. L1TownLocation.java에 있지 않아서 어떠한 성에도, 마을에도 귀속되지 않는 상점은 세금도 적용받지않고, 성의 세금수입에도 영향을 주지 않습니다.
5. L1TaxCalculator.java의 전쟁세를 0으로 한다면 어떠한 성, 마을에 귀속되지 않는 상점의 세금은 0%이 됩니다.
제가 리니지 게임의 내용 이해가 적어서 그런데, 전쟁세 15는 어떤 용도인가요?
본섭에서는 어떠한 용도로 사용 되는지 궁금 합니다. 만약 전쟁세 15%가 무조건 적용되어야 한다면 전쟁세를 0으로 하고 지역세금에 전쟁세금을 추가하는 방법도 있겠네요.
http://sofree.co.kr/ 에 더 많은 자료가 있습니다.
60렙이하 무혈 임시혈 피케불가
소스자료 팩자료 구축자료 묻고 답하기 운영 노하우 지식공유
글 수 60Classic StyleZine StyleGallery Style60렙 무혈 임시혈 피케불가조회 수 3 추천 수 0 2010.08.11 21:28:33 건이다아아앙 http://sofree.co.kr/xe/2155
자~ 먼저 조건부를 말씀드릴께요~
레벨60이상인 노혈인캐릭터, 레벨60이상인 임시혈맹(클랜번호가999로 가정해봤어요) 일경우 다른유저를 치지 못하게 했습니다.
예를들어 노혈레벨1인캐릭터와 노혈 레벨60인캐릭터가 싸운다치면 레벨1짜리는 60캐릭터를 때릴수있지만 레벨 60캐릭터는 레벨 1캐릭터를 때릴수 없겠죠~제가 직접 실험해봤으니 안되면 본인이 잘못하고있는것임!!!
먼저 소스는 L1attack입니다.
이 구문을 넣는 위치는 명중판정부분 중
// ●●●● 플레이어로부터 플레이어에의 명중 판정 ●●●● 이곳에 들어갈 소스입니다.
원리는 명중율 즉 hitrate를 0으로 되게하여 계속 빗방이 나게해서 공격을 못하게하는것 입니다.
소스의 구체적 위치는 이렇습니다. 붉은색은 소스추가하실 것입니다.
if (_targetPc.hasSkillEffect(FREEZING_BLIZZARD)) {
_hitRate = 0; // 프리징블리자드 추가
}
if(_pc.getClanid() == 999 && _pc.getLevel() >=60 ){
_hitRate = 0;
}
if(_pc.getClanid() == 0 && _pc.getLevel() >=60){
_hitRate = 0;
}
if (_targetPc.hasSkillEffect(120) == true){ //아바타
return false;
대충 저런곳에 넣어놓으시면 소스를 한번 읽어보도록 하겠습니다. 클랜아이디가999이며레벨이60이상이면 공격성공율(hitrate)이0이되어서 공격을 해도 박히지않습니다. 클랜아이디가0(노혈)이며 레벨이 60이상이면 공격성공율(hitrate)가 0이 되어서 공격을해도 박히지 않습니다. 이렇게 해석이 되겠습니다. 자~ 제가 직접만들어서 실험까지 다해보고 올려드리는 소스이니 부디 안된다하지마시길.. 혹시나 안되시는분들은
import l1j.server.server.storage.mysql.MySqlCharacterStorage;
import l1j.server.server.model.L1Character;
요거 2개 임포트 매겨보세요~ 이상 잡초근성 이었습니다. 글구 지금 제가 소스토론방에서 보고 그냥 만든소스이지만 그래도 제가 만든소스이니 다른곳에 올리실때는 꼭 출처 써주시고요~(자랑할라는게 아니라 출처는 항상 확실히!) 이 글을 보시고 본인서버에 적용하실분들은 꼭 리플다세요! 리플을 생활화 합시다..뭐 카페가 자선사업하는곳도 아니구.. 리플한개씩은 꼭!꼭! 달도록 합시당~ 밤에는 쌀쌀한데 다들 감기조심하시구요 하시는일 모두 잘되시길 바랄께요~ have a good time!
-이상 초간단소스만 올리는 잡초근성 이었습니다.-
ps.마법쪽도 들어가는 소스는 같습니다~이소스보셧으니 마법쪽은 다들 알아서 하실수있을꺼라 생각해용~
글 수 60Classic StyleZine StyleGallery Style60렙 무혈 임시혈 피케불가조회 수 3 추천 수 0 2010.08.11 21:28:33 건이다아아앙 http://sofree.co.kr/xe/2155
자~ 먼저 조건부를 말씀드릴께요~
레벨60이상인 노혈인캐릭터, 레벨60이상인 임시혈맹(클랜번호가999로 가정해봤어요) 일경우 다른유저를 치지 못하게 했습니다.
예를들어 노혈레벨1인캐릭터와 노혈 레벨60인캐릭터가 싸운다치면 레벨1짜리는 60캐릭터를 때릴수있지만 레벨 60캐릭터는 레벨 1캐릭터를 때릴수 없겠죠~제가 직접 실험해봤으니 안되면 본인이 잘못하고있는것임!!!
먼저 소스는 L1attack입니다.
이 구문을 넣는 위치는 명중판정부분 중
// ●●●● 플레이어로부터 플레이어에의 명중 판정 ●●●● 이곳에 들어갈 소스입니다.
원리는 명중율 즉 hitrate를 0으로 되게하여 계속 빗방이 나게해서 공격을 못하게하는것 입니다.
소스의 구체적 위치는 이렇습니다. 붉은색은 소스추가하실 것입니다.
if (_targetPc.hasSkillEffect(FREEZING_BLIZZARD)) {
_hitRate = 0; // 프리징블리자드 추가
}
if(_pc.getClanid() == 999 && _pc.getLevel() >=60 ){
_hitRate = 0;
}
if(_pc.getClanid() == 0 && _pc.getLevel() >=60){
_hitRate = 0;
}
if (_targetPc.hasSkillEffect(120) == true){ //아바타
return false;
대충 저런곳에 넣어놓으시면 소스를 한번 읽어보도록 하겠습니다. 클랜아이디가999이며레벨이60이상이면 공격성공율(hitrate)이0이되어서 공격을 해도 박히지않습니다. 클랜아이디가0(노혈)이며 레벨이 60이상이면 공격성공율(hitrate)가 0이 되어서 공격을해도 박히지 않습니다. 이렇게 해석이 되겠습니다. 자~ 제가 직접만들어서 실험까지 다해보고 올려드리는 소스이니 부디 안된다하지마시길.. 혹시나 안되시는분들은
import l1j.server.server.storage.mysql.MySqlCharacterStorage;
import l1j.server.server.model.L1Character;
요거 2개 임포트 매겨보세요~ 이상 잡초근성 이었습니다. 글구 지금 제가 소스토론방에서 보고 그냥 만든소스이지만 그래도 제가 만든소스이니 다른곳에 올리실때는 꼭 출처 써주시고요~(자랑할라는게 아니라 출처는 항상 확실히!) 이 글을 보시고 본인서버에 적용하실분들은 꼭 리플다세요! 리플을 생활화 합시다..뭐 카페가 자선사업하는곳도 아니구.. 리플한개씩은 꼭!꼭! 달도록 합시당~ 밤에는 쌀쌀한데 다들 감기조심하시구요 하시는일 모두 잘되시길 바랄께요~ have a good time!
-이상 초간단소스만 올리는 잡초근성 이었습니다.-
ps.마법쪽도 들어가는 소스는 같습니다~이소스보셧으니 마법쪽은 다들 알아서 하실수있을꺼라 생각해용~
2010년 8월 1일 일요일
http://www.uami.co.kr/ 에서
서버 연동 홍보기를 무료 배포 한다고 합니다.
조건은 2차 이상 오픈 한 서버라고 하네요
*우아미 서버 연동기는
1. db 계정을 가르쳐 주지 않으셔도 됩니다.
2. 웹페이지가 필요가 없습니다.
- url에 계정 넣고 클릭하면 깃털 지급 되고.. 그런것 없습니다~
3. 팝린이 막혀도 5분안에 뚫습니다.
4. 재배포가 필요 없습니다.
5. 글관리가 매우 쉽습니다.
- 글을 적어놓고 선택만 하면 됩니다~
6. 적용하기가 매우 쉽습니다.
- 소스 5줄이면 서버 연동이 됩니다~
http://www.uami.co.kr/ 가입후 운영자에게로 글을 남겨 주시거나
uami777@gmail.com 으로 신청 하시면 되네요~
서버 연동 홍보기를 무료 배포 한다고 합니다.
조건은 2차 이상 오픈 한 서버라고 하네요
*우아미 서버 연동기는
1. db 계정을 가르쳐 주지 않으셔도 됩니다.
2. 웹페이지가 필요가 없습니다.
- url에 계정 넣고 클릭하면 깃털 지급 되고.. 그런것 없습니다~
3. 팝린이 막혀도 5분안에 뚫습니다.
4. 재배포가 필요 없습니다.
5. 글관리가 매우 쉽습니다.
- 글을 적어놓고 선택만 하면 됩니다~
6. 적용하기가 매우 쉽습니다.
- 소스 5줄이면 서버 연동이 됩니다~
http://www.uami.co.kr/ 가입후 운영자에게로 글을 남겨 주시거나
uami777@gmail.com 으로 신청 하시면 되네요~
리니지 쓰레드 정리(튜닝)
더많은 자료는 http://www.sofree.co.kr/
Client가 패킷을 보내면 ClientThread에서 패킷을 받아서 HCPacket에게 전달 합니다.
HCPacket은 전달받은 패킷을 PacketHandler를 이용하여 처리 합니다.
그런데 HCPacket은 ClientThread에서 패킷이 올때만 동작하면 되는데 현재는 ClientThread에서 패킷이 왔는지를 1초에 100번씩 체크 합니다. 이것만 줄여줘도 부하가 많이 해결될 것 같습니다.
ClientThread.java
파란 부분을 찾아서 빨간부분을 추가 합니다.
public void requestWork(byte data[]) {
_queue.offer(data);
// 처리할 데이터가 왔으므로 대기모드인 스레드에게 신호를 준다.
synchronized (_queue) {
_queue.notify();
}
}
ClientThread.java
HCPacket의 run() 메소드 내부의 모든 내용을 지우고 아래 내용을 넣습니다.
@Override
public void run() {
byte[] data;
while (_csocket != null) {
// 처리할 데이터가 없다면 대기모드로 전환
if (_queue.isEmpty()) {
try {
synchronized (_queue) {
_queue.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 처리할 데이터를 모두 처리할 때 까지 반복
while (!_queue.isEmpty()) {
// 처리할 데이터 얻기
data = _queue.poll();
if (data == null) {
break;
}
// 데이터 처리
try {
_handler.handlePacket(data, _activeChar);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
ClientThread.java
파란 부분을 찾아서 빨간부분을 추가 합니다.
_csocket = null;
hcPacket.requestWork(null);
movePacket.requestWork(null);
더많은 자료는 http://www.sofree.co.kr
Client가 패킷을 보내면 ClientThread에서 패킷을 받아서 HCPacket에게 전달 합니다.
HCPacket은 전달받은 패킷을 PacketHandler를 이용하여 처리 합니다.
그런데 HCPacket은 ClientThread에서 패킷이 올때만 동작하면 되는데 현재는 ClientThread에서 패킷이 왔는지를 1초에 100번씩 체크 합니다. 이것만 줄여줘도 부하가 많이 해결될 것 같습니다.
ClientThread.java
파란 부분을 찾아서 빨간부분을 추가 합니다.
public void requestWork(byte data[]) {
_queue.offer(data);
// 처리할 데이터가 왔으므로 대기모드인 스레드에게 신호를 준다.
synchronized (_queue) {
_queue.notify();
}
}
ClientThread.java
HCPacket의 run() 메소드 내부의 모든 내용을 지우고 아래 내용을 넣습니다.
@Override
public void run() {
byte[] data;
while (_csocket != null) {
// 처리할 데이터가 없다면 대기모드로 전환
if (_queue.isEmpty()) {
try {
synchronized (_queue) {
_queue.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 처리할 데이터를 모두 처리할 때 까지 반복
while (!_queue.isEmpty()) {
// 처리할 데이터 얻기
data = _queue.poll();
if (data == null) {
break;
}
// 데이터 처리
try {
_handler.handlePacket(data, _activeChar);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
ClientThread.java
파란 부분을 찾아서 빨간부분을 추가 합니다.
_csocket = null;
hcPacket.requestWork(null);
movePacket.requestWork(null);
더많은 자료는 http://www.sofree.co.kr
리니지 실시간 파티원 위치 변경 소스
더 많은 자료는 http://www.sofree.co.kr/
c_무브CHAR
적당한곳에추가
if(target.isInParty){
pc.sendPackets(new S_PacketBox(S_PacketBox.110,getKarma()));//추가
}
이동할때마다 파티상태를 갱신을 해줍니다. (이방식도 패킷낭비의 가능성이 있으므로
약간 실시간이 아니더라도 보완을 해주는것이 나을수 있음)
그렇기 때문에 미니맵에 파티원들의 상태가 실시간으로 갱신되게 됩니다.
다른방식으로 파티원들이 이동할때 본인에게 패킷을 쏴주는것도 괜찮습니다만
그 경우에는 굉장한 패킷낭비가 있을것으로 판단되므로
이 방식을 써주는것이 낫다고 생각합니다.
다른 유명 온라인 게임도 실시간으로 파티원 위치가 변하지는 않음.
더 많은 자료는 http://www.sofree.co.kr
c_무브CHAR
적당한곳에추가
if(target.isInParty){
pc.sendPackets(new S_PacketBox(S_PacketBox.110,getKarma()));//추가
}
이동할때마다 파티상태를 갱신을 해줍니다. (이방식도 패킷낭비의 가능성이 있으므로
약간 실시간이 아니더라도 보완을 해주는것이 나을수 있음)
그렇기 때문에 미니맵에 파티원들의 상태가 실시간으로 갱신되게 됩니다.
다른방식으로 파티원들이 이동할때 본인에게 패킷을 쏴주는것도 괜찮습니다만
그 경우에는 굉장한 패킷낭비가 있을것으로 판단되므로
이 방식을 써주는것이 낫다고 생각합니다.
다른 유명 온라인 게임도 실시간으로 파티원 위치가 변하지는 않음.
더 많은 자료는 http://www.sofree.co.kr
리니지 자동낚시 구현
더 많은 자료는 http://www.sofree.co.kr/
*반짝이는비늘과 진귀한거북이 획득시 자동낚시 종료!
*반짝이는비늘과 상자물고기는 자신의팩에맞게 번호수정!
*깨진아이템들 주석처리했습니다.
*상자물고기를만드신후 트려져박스에 상자물고기에서 물에젖은아이템
나오게 하면됩니다.
*인벤이미지:반짝이는 비늘(3863)
물고기 상자(3611)
물에 젖은 후드(3610)
물에 젖은 모자(3609)
Opcodes.java
public static final int C_OPCODE_FISHCLICK = 30; // 낚시 입질 클릭
C_Fight.java
(내용통으로)
package l1j.server.server.clientpackets;
import java.util.logging.Level;
import java.util.logging.Logger;
import l1j.server.Config;
import l1j.server.server.ClientThread;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_Message_YN;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.utils.FaceToFace;
// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket
public class C_Fight extends ClientBasePacket {
private static final String C_FIGHT = "[C] C_Fight";
private static Logger _log = Logger.getLogger(C_Fight.class.getName());
public C_Fight(byte abyte0[], ClientThread client)
throws Exception {
super(abyte0);
L1PcInstance pc = client.getActiveChar();
if (pc.isGhost()) {
return;
}
L1PcInstance target = FaceToFace.faceToFace(pc);
if (target != null) {
if (!target.isParalyzed()) {
if (pc.getFightId() != 0) {
pc.sendPackets(new S_ServerMessage(633)); // \f1당신은 벌써 다른 사람과 결투중입니다.
return;
} else if (target.getFightId() != 0) {
target.sendPackets(new S_ServerMessage(634)); // \f1 벌써 다른 사람과 결투중입니다.
return;
}
pc.setFightId(target.getId());
target.setFightId(pc.getId());
target.sendPackets(new S_Message_YN(630, pc.getName())); // %0%s가 당신과 결투를 바라고 있습니다.응합니까? (Y/N)
}
}
}
@Override
public String getType() {
return C_FIGHT;
}
}
C_FishClick.java
(내용통으로)
package l1j.server.server.clientpackets;
import java.util.logging.Logger;
import java.util.Random;
import l1j.server.server.ClientThread;
import l1j.server.server.FishingTimeController;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.L1World;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.model.L1Inventory;
// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket
public class C_FishClick extends ClientBasePacket {
private static final String C_FISHCLICK = "[C] C_FishClick";
private static Logger _log = Logger.getLogger(C_FishClick.class.getName());
private static Random _random = new Random();
public C_FishClick(byte abyte0[], ClientThread clientthread) throws Exception {
super(abyte0);
L1PcInstance pc = clientthread.getActiveChar();
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
pc.broadcastPacket(new S_CharVisualUpdate(pc));
FishingTimeController.getInstance().removeMember(pc);
}
@Override
public String getType() {
return C_FISHCLICK;
}
}
FishingTimeController.java
(내용통으로)
package l1j.server.server;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.Broadcaster;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_PacketBox;
import l1j.server.server.serverpackets.S_ServerMessage;
public class FishingTimeController implements Runnable {
private static FishingTimeController _instance;
private final List _fishingList =
new ArrayList();
private static Random _random = new Random(System.nanoTime());
public static FishingTimeController getInstance() {
if (_instance == null) {
_instance = new FishingTimeController();
}
return _instance;
}
@Override
public void run() {
try {
while (true) {
Thread.sleep(300);
fishing();
}
} catch (Exception e1) {
}
}
public void addMember(L1PcInstance pc) {
if (pc == null
_fishingList.contains(pc)) {
return;
}
_fishingList.add(pc);
}
public void removeMember(L1PcInstance pc) {
if (pc == null
!_fishingList.contains(pc)) {
return;
}
_fishingList.remove(pc);
}
private void fishing() {
if (_fishingList.size() > 0) {
long currentTime = System.currentTimeMillis();
L1PcInstance pc = null;
for (int i = 0; i < _fishingList.size(); i++) {
pc = _fishingList.get(i);
if (pc.isFishing()) {
long time = pc.getFishingTime();
if (currentTime <= (time + 1000)
&& currentTime >= (time - 1000)
&& !pc.isFishingReady()) {
pc.setFishingReady(true);
// pc.sendPackets(new S_Fishing());
pc.sendPackets(new S_PacketBox(S_PacketBox.FISHING));
} else if ( currentTime > (time + 100)
){
int chance = _random.nextInt(200) + 1;
if (chance < 50) {
successFishing(pc, 41298, "$5256"); // 25%어린 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2); //낚시시간 될려주기
} else if (chance < 65) {
successFishing(pc, 41300, "$5258"); // 7.5% 강한 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 80) {
successFishing(pc, 41299, "$5257"); // 7.5%재빠른 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 90) {
successFishing(pc, 41296, "$5249"); // 5%붕어
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 100) {
successFishing(pc, 41297, "$5250"); // 5%잉어
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 105) {
successFishing(pc, 41301, "$5259"); // 2.5%붉은 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 110) {
successFishing(pc, 41302, "$5260"); // 2.5%초록 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 115) {
successFishing(pc, 41303, "$5261"); // 2.5%파란 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 120) {
successFishing(pc, 41304, "$5262"); // 2.5%흰 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
/* } else if (chance < 123) {
successFishing(pc, 41306, "$5263"); // 1.5%깨진 반지
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 126) {
successFishing(pc, 41307, "$5265"); // 1.5%깨진 목걸이
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 129) {
successFishing(pc, 41305, "$5264"); // 1.5%깨진 귀걸이
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 134) {
successFishing(pc, 21051, "$5269"); // 2.5%물에 젖은 투구
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 139) {
successFishing(pc, 21052, "$5270"); // 2.5%물에 젖은 망토
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 144) {
successFishing(pc, 21053, "$5271"); // 2.5%물에 젖은 갑옷
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 159) {
successFishing(pc, 21054, "$5272"); // 2.5%물에 젖은 장갑
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);*/
} else if (chance < 161) {
successFishing(pc, 41252, " 진귀한 거북이 (1) 개"); // 1%
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 163) {
successFishing(pc, 555129, "상자 물고기 (1) 개"); // 1% //아이템번호
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 164) {
successFishing(pc, 555128, "반짝이는 비늘 (1) 개"); //0.5% //아이템번호
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2); //낚시시간 될려주기
} else if (chance < 172) { //4퍼 비늘나오게
successFishing(pc, 555128, "반짝이는 비늘 (1) 개"); // 1.0% //아이템번호
successFishing(pc, 41252, " 진귀한 거북이 (1) 개"); // 1%
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
Broadcaster.broadcastPacket(pc, new S_CharVisualUpdate(pc));
pc.sendPackets(new S_ServerMessage(1163, "")); // 낚시가 종료했습니다.
removeMember(pc);
}else {
pc.sendPackets(new S_ServerMessage(1136, "")); // 낚시해에 실패했습니다.
pc.getInventory().consumeItem(41295, 1); //실패시 삭제
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
}
}
}
}
}
}
private void successFishing(L1PcInstance pc, int itemId, String message) {
L1ItemInstance item = ItemTable.getInstance().createItem(itemId);
item.startItemOwnerTimer(pc);
pc.getInventory().storeItem(item);
pc.getInventory().consumeItem(41295, 1); //먹이
pc.sendPackets(new S_ServerMessage(1185, message));//낚시에 성공했습니다.
if (!pc.getInventory().checkItem(41295)) { //먹이
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
Broadcaster.broadcastPacket(pc, new S_CharVisualUpdate(pc));
pc.sendPackets(new S_ServerMessage(1137)); //낚시를하기 위해선 먹이가 필요합니다.
removeMember(pc);
}
}
}
C_ItemUSe.java
private void startFishing(L1PcInstance pc, int itemId, int fishX, int fishY) { //검색추가
if (pc.getMapId() != 5302
fishX <= 32704
fishX >= 32831
fishY <= 32768
fishY >= 32895) {
// 여기에 낚싯대를 던질 수 없습니다.
pc.sendPackets(new S_ServerMessage(1138));
return;
}
더 많은 자료는 http://www.sofree.co.kr
*반짝이는비늘과 진귀한거북이 획득시 자동낚시 종료!
*반짝이는비늘과 상자물고기는 자신의팩에맞게 번호수정!
*깨진아이템들 주석처리했습니다.
*상자물고기를만드신후 트려져박스에 상자물고기에서 물에젖은아이템
나오게 하면됩니다.
*인벤이미지:반짝이는 비늘(3863)
물고기 상자(3611)
물에 젖은 후드(3610)
물에 젖은 모자(3609)
Opcodes.java
public static final int C_OPCODE_FISHCLICK = 30; // 낚시 입질 클릭
C_Fight.java
(내용통으로)
package l1j.server.server.clientpackets;
import java.util.logging.Level;
import java.util.logging.Logger;
import l1j.server.Config;
import l1j.server.server.ClientThread;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_Message_YN;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.utils.FaceToFace;
// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket
public class C_Fight extends ClientBasePacket {
private static final String C_FIGHT = "[C] C_Fight";
private static Logger _log = Logger.getLogger(C_Fight.class.getName());
public C_Fight(byte abyte0[], ClientThread client)
throws Exception {
super(abyte0);
L1PcInstance pc = client.getActiveChar();
if (pc.isGhost()) {
return;
}
L1PcInstance target = FaceToFace.faceToFace(pc);
if (target != null) {
if (!target.isParalyzed()) {
if (pc.getFightId() != 0) {
pc.sendPackets(new S_ServerMessage(633)); // \f1당신은 벌써 다른 사람과 결투중입니다.
return;
} else if (target.getFightId() != 0) {
target.sendPackets(new S_ServerMessage(634)); // \f1 벌써 다른 사람과 결투중입니다.
return;
}
pc.setFightId(target.getId());
target.setFightId(pc.getId());
target.sendPackets(new S_Message_YN(630, pc.getName())); // %0%s가 당신과 결투를 바라고 있습니다.응합니까? (Y/N)
}
}
}
@Override
public String getType() {
return C_FIGHT;
}
}
C_FishClick.java
(내용통으로)
package l1j.server.server.clientpackets;
import java.util.logging.Logger;
import java.util.Random;
import l1j.server.server.ClientThread;
import l1j.server.server.FishingTimeController;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.L1World;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.model.L1Inventory;
// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket
public class C_FishClick extends ClientBasePacket {
private static final String C_FISHCLICK = "[C] C_FishClick";
private static Logger _log = Logger.getLogger(C_FishClick.class.getName());
private static Random _random = new Random();
public C_FishClick(byte abyte0[], ClientThread clientthread) throws Exception {
super(abyte0);
L1PcInstance pc = clientthread.getActiveChar();
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
pc.broadcastPacket(new S_CharVisualUpdate(pc));
FishingTimeController.getInstance().removeMember(pc);
}
@Override
public String getType() {
return C_FISHCLICK;
}
}
FishingTimeController.java
(내용통으로)
package l1j.server.server;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.Broadcaster;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_PacketBox;
import l1j.server.server.serverpackets.S_ServerMessage;
public class FishingTimeController implements Runnable {
private static FishingTimeController _instance;
private final List
new ArrayList
private static Random _random = new Random(System.nanoTime());
public static FishingTimeController getInstance() {
if (_instance == null) {
_instance = new FishingTimeController();
}
return _instance;
}
@Override
public void run() {
try {
while (true) {
Thread.sleep(300);
fishing();
}
} catch (Exception e1) {
}
}
public void addMember(L1PcInstance pc) {
if (pc == null
_fishingList.contains(pc)) {
return;
}
_fishingList.add(pc);
}
public void removeMember(L1PcInstance pc) {
if (pc == null
!_fishingList.contains(pc)) {
return;
}
_fishingList.remove(pc);
}
private void fishing() {
if (_fishingList.size() > 0) {
long currentTime = System.currentTimeMillis();
L1PcInstance pc = null;
for (int i = 0; i < _fishingList.size(); i++) {
pc = _fishingList.get(i);
if (pc.isFishing()) {
long time = pc.getFishingTime();
if (currentTime <= (time + 1000)
&& currentTime >= (time - 1000)
&& !pc.isFishingReady()) {
pc.setFishingReady(true);
// pc.sendPackets(new S_Fishing());
pc.sendPackets(new S_PacketBox(S_PacketBox.FISHING));
} else if ( currentTime > (time + 100)
){
int chance = _random.nextInt(200) + 1;
if (chance < 50) {
successFishing(pc, 41298, "$5256"); // 25%어린 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2); //낚시시간 될려주기
} else if (chance < 65) {
successFishing(pc, 41300, "$5258"); // 7.5% 강한 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 80) {
successFishing(pc, 41299, "$5257"); // 7.5%재빠른 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 90) {
successFishing(pc, 41296, "$5249"); // 5%붕어
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 100) {
successFishing(pc, 41297, "$5250"); // 5%잉어
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 105) {
successFishing(pc, 41301, "$5259"); // 2.5%붉은 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 110) {
successFishing(pc, 41302, "$5260"); // 2.5%초록 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 115) {
successFishing(pc, 41303, "$5261"); // 2.5%파란 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 120) {
successFishing(pc, 41304, "$5262"); // 2.5%흰 빛 나는 물고기
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
/* } else if (chance < 123) {
successFishing(pc, 41306, "$5263"); // 1.5%깨진 반지
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 126) {
successFishing(pc, 41307, "$5265"); // 1.5%깨진 목걸이
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 129) {
successFishing(pc, 41305, "$5264"); // 1.5%깨진 귀걸이
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 134) {
successFishing(pc, 21051, "$5269"); // 2.5%물에 젖은 투구
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 139) {
successFishing(pc, 21052, "$5270"); // 2.5%물에 젖은 망토
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 144) {
successFishing(pc, 21053, "$5271"); // 2.5%물에 젖은 갑옷
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 159) {
successFishing(pc, 21054, "$5272"); // 2.5%물에 젖은 장갑
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);*/
} else if (chance < 161) {
successFishing(pc, 41252, " 진귀한 거북이 (1) 개"); // 1%
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 163) {
successFishing(pc, 555129, "상자 물고기 (1) 개"); // 1% //아이템번호
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
} else if (chance < 164) {
successFishing(pc, 555128, "반짝이는 비늘 (1) 개"); //0.5% //아이템번호
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2); //낚시시간 될려주기
} else if (chance < 172) { //4퍼 비늘나오게
successFishing(pc, 555128, "반짝이는 비늘 (1) 개"); // 1.0% //아이템번호
successFishing(pc, 41252, " 진귀한 거북이 (1) 개"); // 1%
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
Broadcaster.broadcastPacket(pc, new S_CharVisualUpdate(pc));
pc.sendPackets(new S_ServerMessage(1163, "")); // 낚시가 종료했습니다.
removeMember(pc);
}else {
pc.sendPackets(new S_ServerMessage(1136, "")); // 낚시해에 실패했습니다.
pc.getInventory().consumeItem(41295, 1); //실패시 삭제
long time2 = System.currentTimeMillis() + 10000 + _random.nextInt(6) * 1000;
pc.setFishingTime(time2);
}
}
}
}
}
}
private void successFishing(L1PcInstance pc, int itemId, String message) {
L1ItemInstance item = ItemTable.getInstance().createItem(itemId);
item.startItemOwnerTimer(pc);
pc.getInventory().storeItem(item);
pc.getInventory().consumeItem(41295, 1); //먹이
pc.sendPackets(new S_ServerMessage(1185, message));//낚시에 성공했습니다.
if (!pc.getInventory().checkItem(41295)) { //먹이
pc.setFishingTime(0);
pc.setFishingReady(false);
pc.setFishing(false);
pc.sendPackets(new S_CharVisualUpdate(pc));
Broadcaster.broadcastPacket(pc, new S_CharVisualUpdate(pc));
pc.sendPackets(new S_ServerMessage(1137)); //낚시를하기 위해선 먹이가 필요합니다.
removeMember(pc);
}
}
}
C_ItemUSe.java
private void startFishing(L1PcInstance pc, int itemId, int fishX, int fishY) { //검색추가
if (pc.getMapId() != 5302
fishX <= 32704
fishX >= 32831
fishY <= 32768
fishY >= 32895) {
// 여기에 낚싯대를 던질 수 없습니다.
pc.sendPackets(new S_ServerMessage(1138));
return;
}
더 많은 자료는 http://www.sofree.co.kr
피드 구독하기:
글 (Atom)