2 #include "nlib_include.h"
9 static NicoLiveHeartBeatContainer heartBeatContainer;
10 static CRITICAL_SECTION heartBeatCs;
17 #define XMLSPACE L" \t\r\n"
19 #define parseAttr(indexPtr,ans,ane,avs,ave)\
21 (ane) = wcspbrk((ans),XMLSPACE L"=");\
22 (avs) = wcsstr((ane),L"\"") + 1;\
23 (ave) = wcsstr((avs),L"\"");\
24 (indexPtr) = (ave) + 1
26 #define skipXMLSPACE(indexPtr)\
27 for(;(*(indexPtr)) == L' ' || (*(indexPtr)) == '\t' || (*(indexPtr)) == '\r' || (*(indexPtr)) == '\n';indexPtr++)
29 #define partString(ptr,start,end)\
34 #define convertXMLTEXT(buf,basePtr,convPtr,endPtr)\
36 for(;(basePtr) < (endPtr);(basePtr)++,(convPtr)++){\
37 if(wcsncmp((basePtr),L"&",wcslen(L"&")) == 0){\
39 (basePtr) += wcslen(L"&") - 1;\
40 } else if(wcsncmp((basePtr),L"<",wcslen(L"<")) == 0){\
42 (basePtr) += wcslen(L"<") - 1;\
43 } else if(wcsncmp((basePtr),L">",wcslen(L">")) == 0){\
45 (basePtr) += wcslen(L">") - 1;\
46 } else if(wcsncmp((basePtr),L""",wcslen(L""")) == 0){\
47 (convPtr)[0] = L'\"';\
48 (basePtr) += wcslen(L""") - 1;\
49 } else if(wcsncmp((basePtr),L"'",wcslen(L"'")) == 0){\
50 (convPtr)[0] = L'\'';\
51 (basePtr) += wcslen(L"'") - 1;\
53 (convPtr)[0] = (basePtr)[0];\
58 #define getBaseVpos(server_time,base_time) (((server_time) - (base_time)) * 100)
60 #define setMsec(mSec)\
62 (mSec) = timeGetTime();\
65 #define NicoLiveStream_setVpos(nl,attr)\
66 (nl).chatManager.baseVpos = getBaseVpos((wcstoul((attr),NULL,0)),((nl).playerStatus.stream.base_time));\
67 setMsec((nl).chatManager.commentStartTime)
73 //
\83v
\83\89\83C
\83x
\81[
\83g
\8aÖ
\90\94
79 ///
\83v
\83\8c\83C
\83\84\81[
\83X
\83e
\81[
\83^
\83X
\8eæ
\93¾
81 //static INLINE NLIB_RESULT GetPlayerStatus(NicoLivePlayerStatus_P pPlayerStatus,LPCTSTR userSession,HINTERNET hConnect,LPVOID buffer);
82 static INLINE NLIB_RESULT GetPlayerStatus(NicoLivePlayerStatus_P pPlayerStatus,LPCTSTR userSession,HINTERNET hConnect);
85 ///nicoLiveHistory
\8eæ
\93¾
87 static INLINE NLIB_RESULT GetNicoLiveHistory(NicoLiveStream_P self,HINTERNET hConnect);
91 ///
\90¶
\8eå
\8fî
\95ñ
\8eæ
\93¾
93 static INLINE NLIB_RESULT GetPublishStatus(NicoLivePublishStatus_P self,LPCTSTR userSession,HINTERNET hConnect);
104 ///
\83`
\83\83\83b
\83g
\8eó
\90M
\83\8b\81[
\83v
\8aJ
\8en
\8aÖ
\90\94
106 static unsigned int WINAPI NicoLiveRecvChat(void* lpBuffer);
109 ///
\83n
\81[
\83g
\83r
\81[
\83g
\91\97\90M
\83\8b\81[
\83v
\8aÖ
\90\94
111 static unsigned int WINAPI NicoLiveHeartBeatThread(void* lpBuffer);
114 #ifdef USE_NLIB_KEEPALIVE
117 ///
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\91\97\90M
\83\8b\81[
\83v
\8aÖ
\90\94
119 static unsigned int WINAPI NicoLiveKeapALiveThread(void* lpBuffer);
121 #endif //USE_NLIB_KEEPALIVE
127 ///
\83`
\83\83\83b
\83g
\8eó
\90M
\83\8b\81[
\83v
\8aÖ
\90\94
129 static BOOL NicoLiveRecvChatLoop(NicoLiveStream_P self);
134 static unsigned int loopCommon(NicoLiveStream_P self,WSAEVENT sendEvent,WSAEVENT resetEvent ,NicoLiveOnSend nicoLiveOnSend,LPDWORD time);
137 ///
\83R
\83\81\83\93\83g
\89ð
\90Í
\8aÖ
\90\94
139 static VOID NicoLiveParseComment(NicoLiveStream_P self,LPTSTR commentBuf,UINT_PTR endSize,LPTSTR* mailCountBuf,SIZE_T* mailCountBufSize,SIZE_T* commentBufSize);
141 static void NicoLiveError(void *buf);
143 static void NicoLiveSelfDisconnect(void *buf);
145 static VOID OnSendHeartBeat(NicoLiveStream_P self);
147 static VOID OnSendKeepAllive(NicoLiveStream_P self);
149 ///
\83\
\83P
\83b
\83g
\8eæ
\93¾
\8aÖ
\90\94
151 static INLINE SOCKET GetConectedSocket(LPCTSTR nordName,LPCTSTR port,int socktype,int addr_famiry,int protocol);
154 StreamStatus_P NicoLiveStream_getStreamStatus(NicoLiveStream_P self){
156 return &self->playerStatus.stream;
159 BOOL Initialize_NicoLive(){
165 //
\83n
\81[
\83g
\83r
\81[
\83g
\83R
\83\93\83e
\83i
\8f\89\8aú
\89»
166 ZeroMemory(&heartBeatContainer,sizeof(heartBeatContainer));
167 heartBeatContainer.is_restrictSize = sizeof(TCHAR) * LENGTH_1024;
168 heartBeatContainer.is_restrictBuff = (LPTSTR)calloc(1,heartBeatContainer.is_restrictSize);
169 heartBeatContainer.heartBeat.is_restrict = heartBeatContainer.is_restrictBuff;
171 heartBeatContainer.ticketSize = sizeof(TCHAR) * LENGTH_1024;
172 heartBeatContainer.ticketBuff = (LPTSTR)calloc(1,heartBeatContainer.ticketSize);
173 heartBeatContainer.heartBeat.ticket = heartBeatContainer.ticketBuff;
175 InitializeCriticalSection(&heartBeatCs);
185 extern BOOL Finalize_NicoLive(){
188 DeleteCriticalSection(&heartBeatCs);
190 //
\83p
\81[
\83T
\8cã
\8f\88\97\9d
191 free(heartBeatContainer.is_restrictBuff);
192 free(heartBeatContainer.ticketBuff);
206 NicoLiveStream_P NicoLiveStream_new(){
207 //
\90¶
\90¬&
\8f\89\8aú
\89»
208 NicoLiveStream_P self = (NicoLiveStream_P)calloc(1,sizeof(NicoLiveStream));
210 //
\8f\89\8aú
\92l
\82Ì
\90Ý
\92è
211 self->chatManager.onHeartBeatSend = OnSendHeartBeat;
215 InitializeCriticalSection(&self->sessionManager.cs);
217 self->chatManager.heartBeatTime = 60000;
218 self->chatManager.heartBeatFlag = TRUE;
222 self->isConnecting = FALSE;
224 self->chatManager.endEvent = WSACreateEvent();
226 self->chatManager.startEvent = WSACreateEvent();
228 self->chatManager.deleteEvent = WSACreateEvent();
230 self->chatManager.setHeartBeatTimeEvent = WSACreateEvent();
233 #ifdef USE_NLIB_KEEPALIVE
235 self->chatManager.onKeepAlliveSend = OnSendKeepAllive;
237 self->chatManager.keepAliveTime = 900000;
239 self->chatManager.keapALiveFlag = FALSE;
241 self->chatManager.setKeepAliveTimeEvent = WSACreateEvent();
243 self->chatManager.resetEvents[KEEPALLIVERESETEVENT] = WSACreateEvent();
245 #endif //USE_NLIB_KEEPALIVE
247 self->chatManager.resetEvents[0] = WSACreateEvent();
249 self->chatManager.resetEvents[1] = WSACreateEvent();
257 //
\83X
\83\8c\83b
\83h
\82Ì
\8aJ
\8en
258 self->chatManager.hRecvChatHandle = (HANDLE)_beginthreadex(NULL,0,NicoLiveRecvChat,self,0,&self->chatManager.recvChatThreadID);
260 self->chatManager.hHeartBeatHandle = (HANDLE)_beginthreadex(NULL,0,NicoLiveHeartBeatThread,self,0,&self->chatManager.heartBeatThreadID);
262 #ifdef USE_NLIB_KEEPALIVE
263 self->chatManager.hKeapALiveHandle = (HANDLE)_beginthreadex(NULL,0,NicoLiveKeapALiveThread,self,0,&self->chatManager.keapALiveThreadID);
272 //
\83j
\83R
\83j
\83R
\90¶
\95ú
\91\97\8aÖ
\98A
\8aÖ
\90\94
273 ///////////////////////////////////////////////////
275 VOID NicoLiveStream_delete(NicoLiveStream_P* self){
277 NicoLiveStream_disConnect((*self));
279 WSASetEvent((*self)->chatManager.deleteEvent);
281 if(INVALID_HANDLE_VALUE != (*self)->chatManager.hRecvChatHandle){
282 WaitForSingleObject( (*self)->chatManager.hRecvChatHandle, INFINITE );
283 CloseHandle((*self)->chatManager.hRecvChatHandle);
286 if(INVALID_HANDLE_VALUE != (*self)->chatManager.hHeartBeatHandle){
288 WaitForSingleObject((*self)->chatManager.hHeartBeatHandle,INFINITE);
289 CloseHandle((*self)->chatManager.hHeartBeatHandle);
292 if(INVALID_HANDLE_VALUE != (*self)->chatManager.hKeapALiveHandle){
294 WaitForSingleObject((*self)->chatManager.hKeapALiveHandle,INFINITE);
295 CloseHandle((*self)->chatManager.hKeapALiveHandle);
305 //
\8cã
\8f\88\97\9d&
\94j
\8aü
307 DeleteCriticalSection(&(*self)->sessionManager.cs);
309 WSACloseEvent((*self)->chatManager.setHeartBeatTimeEvent);
310 #ifdef USE_NLIB_KEEPALIVE
311 WSACloseEvent((*self)->chatManager.setKeepAliveTimeEvent);
312 WSACloseEvent((*self)->chatManager.resetEvents[KEEPALLIVERESETEVENT]);
314 WSACloseEvent((*self)->chatManager.endEvent);
316 WSACloseEvent((*self)->chatManager.startEvent);
318 WSACloseEvent((*self)->chatManager.deleteEvent);
320 WSACloseEvent((*self)->chatManager.resetEvents[0]);
322 WSACloseEvent((*self)->chatManager.resetEvents[1]);
331 (*self) = (NicoLiveStream_P)NULL;
338 ///
\83n
\81[
\83g
\83r
\81[
\83g
\82Ì
\8aÔ
\8au
\82ð
\90Ý
\92è
\81i
\83~
\83\8a\95b)
340 VOID NicoLiveStream_setHeartBeatMsec(NicoLiveStream_P self,DWORD msec){
343 self->chatManager.heartBeatTime = msec;
344 WSASetEvent(self->chatManager.setHeartBeatTimeEvent);
349 ///
\83n
\81[
\83g
\83r
\81[
\83g
\82Ì
\8aÔ
\8au
\82ð
\8eæ
\93¾(
\83~
\83\8a\95b)
351 DWORD NicoLiveStream_getHeartBeatMsec(NicoLiveStream_P self){
353 return self->chatManager.heartBeatTime;
359 ///
\83n
\81[
\83g
\83r
\81[
\83g
\97L
\8cø
\81E
\96³
\8cø
\90Ý
\92è
361 VOID NicoLiveStream_setHeartBeatFlag(NicoLiveStream_P self,BOOL flag){
363 self->chatManager.heartBeatFlag = flag;
369 ///
\83n
\81[
\83g
\83r
\81[
\83g
\97L
\8cø
\83t
\83\89\83O
\8eæ
\93¾
371 BOOL NicoLiveStream_getHeartBeatFlag(NicoLiveStream_P self){
373 return self->chatManager.heartBeatFlag;
380 ///
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\82Ì
\8aÔ
\8au
\82ð
\90Ý
\92è(
\83~
\83\8a\95b)
382 VOID NicoLiveStream_setKeapALiveMsec(NicoLiveStream_P self,DWORD msec){
384 #ifdef USE_NLIB_KEEPALIVE
385 self->chatManager.keepAliveTime = msec;
386 WSASetEvent(self->chatManager.setKeepAliveTimeEvent);
393 ///
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\82Ì
\8aÔ
\8au
\82ð
\8eæ
\93¾(
\83~
\83\8a\95b)
395 DWORD NicoLiveStream_getKeapALiveMsec(NicoLiveStream_P self){
397 #ifdef USE_NLIB_KEEPALIVE
398 return self->chatManager.keepAliveTime;
407 ///
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\97L
\8cø
\81E
\96³
\8cø
\90Ý
\92è
409 VOID NicoLiveStream_setKeapALiveFlag(NicoLiveStream_P self,BOOL flag){
411 #ifdef USE_NLIB_KEEPALIVE
412 self->chatManager.keapALiveFlag = flag;
418 ///
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\83t
\83\89\83O
\8eæ
\93¾
420 BOOL NicoLiveStream_getKeapALiveFlag(NicoLiveStream_P self){
422 #ifdef USE_NLIB_KEEPALIVE
423 return self->chatManager.keapALiveFlag;
430 VOID NicoLiveStrream_setResFrom(NicoLiveStream_P self,INT_PTR res){
434 self->res_from = (res < 0 || res > 1000) ? 0 : ((-1) * res);
438 INT_PTR NicoLiveStream_getResFrom(NicoLiveStream_P self){
440 return (-1) * self->res_from;
443 NLIB_RESULT NicoLiveStream_connect(NicoLiveStream_P self,NicoVideoAuth_P nicoVideoAuth,LPCTSTR url,NicoRecvCallBack callback,LPVOID option){
445 #define NICOLIVE_CONNECTIONSTREAM_COOKIE_COUNT 1
446 #define LIVENO_LENGTH LENGTH_NICOLIVEID
448 NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
456 //url
\82©
\82ç
\90Ú
\91±
\94Ô
\8d\86\82ð
\92\8a\8fo
457 LPCTSTR pInputLiveNo = url;
458 LPCTSTR psrech = wcsstr(url,L"http://");
459 LPTSTR pInputLiveNoEnd;
460 TCHAR liveNo[LIVENO_LENGTH] = {0};
463 if(self == NULL)goto end;
465 BOOL sleepFlag = self->isConnecting;
467 //
\91O
\82É
\82Â
\82È
\82¢
\82Å
\82¢
\82½
\95ú
\91\97\82ð
\90Ø
\92f
468 NicoLiveStream_disConnect(self);
470 if(sleepFlag == TRUE){
478 for(;psrech != NULL;psrech = wcsstr(psrech +1,L"/")){
480 pInputLiveNo = psrech + 1;
487 _tcstol(pInputLiveNo + 2,&pInputLiveNoEnd,10);
489 if(pInputLiveNo == NULL){
491 rslt = NLIB_LIVENO_IS_NULL;
494 }else if(pInputLiveNoEnd - pInputLiveNo + 2 >= LIVENO_LENGTH - 1){
496 rslt = NLIB_LIVENO_FAILED_TOOBIG;
499 } else if((wcsncmp(pInputLiveNo,TEXT("lv"),2) == 0)||(( wcsncmp(pInputLiveNo,TEXT("co"),2) == 0) || (wcsncmp(pInputLiveNo,TEXT("ch"),2) == 0) )){
502 wcsncpy(liveNo,pInputLiveNo,pInputLiveNoEnd - pInputLiveNo);
505 } else if(_wtoi(pInputLiveNo) != 0){
507 wcscpy(liveNo,L"lv");
508 wcsncat(liveNo,pInputLiveNo,pInputLiveNoEnd - pInputLiveNo);
512 rslt = NLIB_LIVENO_FAILED_UNDEFEINE;
521 wcsncpy(self->userSession,L"Cookie: ",sizeof(self->userSession) / sizeof(self->userSession[0]) - 1);
522 wcsncat(self->userSession,nicoVideoAuth->userSession,sizeof(self->userSession) / sizeof(self->userSession[0]) - 1);
523 self->userSession[sizeof(self->userSession) / sizeof(self->userSession[0]) - 1] = L'\0';
529 TCHAR objectName[LENGTH_256] = {L"api/getplayerstatus?v="};
530 wcsncat(objectName,liveNo,sizeof(objectName) / sizeof(objectName[0]));
535 self->sessionManager.getPlayerStatusSession = WinHttpOpenRequest(hWatchLiveNicoConnect,L"GET",objectName,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
537 if(self->sessionManager.getPlayerStatusSession == NULL){
546 //
\83v
\83\8c\83C
\83\84\81[
\83X
\83e
\81[
\83^
\83X
\8eæ
\93¾
547 EnterCriticalSection(&self->sessionManager.cs);
549 rslt = GetPlayerStatus(&self->playerStatus,self->userSession,self->sessionManager.getPlayerStatusSession);
550 }catch (nlib::Exception &e){
551 LeaveCriticalSection(&self->sessionManager.cs);
555 LeaveCriticalSection(&self->sessionManager.cs);
561 if(rslt != NLIB_ERR_OK){
569 //
\90¶
\95ú
\91\97\83I
\83u
\83W
\83F
\83N
\83g
\82É
\8ae
\88ø
\90\94\82ð
\90Ý
\92è
571 self->callBack = callback;
572 self->option = option;
575 WSASetEvent(self->chatManager.startEvent);
578 if(self->playerStatus.stream.is_owner == TRUE){
580 TCHAR objectName[LENGTH_256] = {L"api/getpublishstatus?v="};
581 wcsncat(objectName,self->playerStatus.stream.id,sizeof(objectName) / sizeof(objectName[0]));
583 self->sessionManager.getPublishStatusSession = WinHttpOpenRequest(hWatchLiveNicoConnect,L"GET",objectName,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
585 if(self->sessionManager.getPublishStatusSession == NULL){
588 EnterCriticalSection(&self->sessionManager.cs);
589 rslt = GetPublishStatus(&self->publishStatus,self->userSession,self->sessionManager.getPublishStatusSession);
590 LeaveCriticalSection(&self->sessionManager.cs);
593 if(rslt != NLIB_ERR_OK){
599 self->isConnecting = TRUE;
612 NicoLiveStream_disConnect(self);
617 NLIB_RESULT NicoLiveStream_sendHeartBeat(NicoLiveStream_P self){
620 NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
622 if(self->isConnecting == FALSE){
623 rslt = NLIB_ERR_NOT_LIVECONNECT;
629 EnterCriticalSection(&self->sessionManager.cs);
632 const UINT_PTR buflen = LENGTH_65536;
633 LPVOID buffer = malloc(buflen * sizeof(TCHAR));
635 LPTSTR objectName = (LPTSTR)buffer;
637 //LPTSTR sendBuffer = (LPTSTR)&objectName[LENGTH_4096];
638 LPSTR recvBuffer = (LPSTR)&objectName[LENGTH_4096];
641 DWORD statusCodeSize = sizeof(statusCode);
643 wcscpy(objectName,L"/api/heartbeat?v=");
644 indexPtr = objectName + wcslen(objectName);
645 wcscpy(indexPtr,self->playerStatus.stream.id);
649 if(self->sessionManager.heartBeatSession == NULL){
650 self->sessionManager.heartBeatSession = WinHttpOpenRequest(hWatchLiveNicoConnect,L"GET",objectName,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
652 if(self->sessionManager.heartBeatSession == NULL){
657 if(WinHttpSendRequest(self->sessionManager.heartBeatSession,self->userSession,-1,WINHTTP_NO_REQUEST_DATA,0,0,0) == FALSE){
659 rslt = NLIB_ERR_FAILED_NETWORK;
664 if(WinHttpReceiveResponse(self->sessionManager.heartBeatSession,NULL) == FALSE){
666 rslt = NLIB_HEARTBEAT_FAILED_CONNECT;
672 if (WinHttpQueryHeaders(self->sessionManager.heartBeatSession,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
673 rslt = NLIB_HEARTBEAT_FAILED_CONNECT;
678 if (HTTP_STATUS_OK != statusCode){
679 rslt = NLIB_HEARTBEAT_FAILED_CONNECT;
684 //recvBuffer = (LPSTR)sendBuffer;
687 if(ReadHttpBody(self->sessionManager.heartBeatSession,(LPBYTE)recvBuffer,buflen,&readSize) == FALSE){
689 rslt = NLIB_HEARTBEAT_FAILED_CONNECT;
697 EnterCriticalSection(&heartBeatCs);
699 XMLParse(&heartBeatContainer,recvBuffer,NicoLiveHeartBeat_ElementStartHandler,NicoLiveHeartBeat_ElementEndHandler,NicoLiveHeartBeat_CharacterDataHandler);
701 self->chatManager.baseVpos = getBaseVpos(heartBeatContainer.heartBeat.time, self->playerStatus.stream.base_time);
702 setMsec(self->chatManager.commentStartTime);
704 self->callBack(NICOLIVE_EVENT_SEND_HEARTBEAT,self,self->option,(NICOLIVE_PARAM)&heartBeatContainer.heartBeat,(NICOLIVE_PARAM)NULL);
706 ZeroMemory(&heartBeatContainer.heartBeat,sizeof(heartBeatContainer.heartBeat));
708 ZeroMemory(heartBeatContainer.is_restrictBuff,heartBeatContainer.is_restrictSize);
710 ZeroMemory(heartBeatContainer.ticketBuff,heartBeatContainer.ticketSize);
712 heartBeatContainer.heartBeat.is_restrict = heartBeatContainer.is_restrictBuff;
714 heartBeatContainer.heartBeat.ticket = heartBeatContainer.ticketBuff;
716 LeaveCriticalSection(&heartBeatCs);
724 //ZeroMemory(self->sessionManager.buffer,sizeof(self->sessionManager.buffer));
725 LeaveCriticalSection(&self->sessionManager.cs);
737 VOID NicoLiveStream_disConnect(NicoLiveStream_P self){
739 if(self == NULL)goto end;
741 DWORD waitRslt = WSA_WAIT_TIMEOUT;
744 while(WSAResetEvent(self->chatManager.startEvent) == FALSE);
745 while(WSASetEvent(self->chatManager.endEvent)== FALSE);
751 waitRslt = WSAWaitForMultipleEvents(sizeof(self->chatManager.resetEvents) / sizeof(self->chatManager.resetEvents[0]),self->chatManager.resetEvents,TRUE,3000,FALSE);
752 } while(waitRslt == WSA_WAIT_TIMEOUT);
755 //nicoLiveStream_Initialize(*self);
756 ZeroMemory(&self->playerStatus,sizeof(self->playerStatus));
757 WSAResetEvent(self->chatManager.endEvent);
759 WinHttpCloseHandle(self->sessionManager.getPlayerStatusSession);
760 self->sessionManager.getPlayerStatusSession = NULL;
761 WinHttpCloseHandle(self->sessionManager.heartBeatSession);
762 self->sessionManager.heartBeatSession = NULL;
763 WinHttpCloseHandle(self->sessionManager.getPublishStatusSession);
764 self->sessionManager.getPublishStatusSession = NULL;
767 self->isConnecting = FALSE;
780 #define NICOLIVE_SENDCHATBUFLEN LENGTH_4096
781 #define NICOLIVE_SENDFORMAT "<chat thread=\"%d\" ticket=\"%S\" postkey=\"%s\" user_id=\"%S\" premium=\"%d\" locale=\"%S\" vpos=\"%ld\"%s>%S</chat>"
783 NLIB_RESULT NicoLiveStream_sendChat(NicoLiveStream_P self,LPCTSTR chatbuf,LPCTSTR *mail,LPCTSTR *extends){
785 NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
786 EnterCriticalSection(&self->sessionManager.cs);
789 const UINT_PTR buflen = LENGTH_65536 * 4;
790 //LPVOID chunk = self->sessionManager.buffer;
791 LPVOID chunk = malloc(buflen *sizeof(TCHAR));
793 LPSTR postKeyBuf = (LPSTR)chunk;
794 LPTSTR postKeyReqBuf = (LPTSTR)&postKeyBuf[NICOLIVE_SENDCHATBUFLEN];
795 LPTSTR cookieBuf = &postKeyReqBuf[NICOLIVE_SENDCHATBUFLEN];
797 DWORD statusCodeSize = sizeof(statusCode);
800 //HINTERNET hWatchLiveNicoVideo = NULL;
801 HINTERNET hGetPostKeySession = NULL;
804 if(self->isConnecting == FALSE){
805 rslt = NLIB_ERR_NOT_LIVECONNECT;
808 if(chatbuf == NULL || wcslen(chatbuf) >= LENGTH_1024){
810 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
817 _swprintf(postKeyReqBuf,L"api/getpostkey?thread=%u&block_no=%u",self->playerStatus.ms.thread,self->chatManager.chatNo / 100);
819 //hWatchLiveNicoVideo = WinHttpConnect(hHttpSession,WTEXT(WATCH_LIVE_NICO_VIDEO_DOMEINNAME),INTERNET_DEFAULT_HTTP_PORT,0);
820 hGetPostKeySession = WinHttpOpenRequest(hWatchLiveNicoConnect,L"GET",postKeyReqBuf,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
823 //_swprintf(cookieBuf,L"Cookie: %s; %s",self->userSession,self->nicoLiveHistory);
824 _swprintf(cookieBuf,L"Cookie: %s",self->userSession);
826 if(WinHttpSendRequest(hGetPostKeySession,self->userSession,-1,WINHTTP_NO_REQUEST_DATA,0,0,0) == FALSE){
828 rslt = NLIB_ERR_LIVE_GETPOSTKEY_FAILED;
834 if(WinHttpReceiveResponse(hGetPostKeySession,NULL) == FALSE){
836 rslt = NLIB_ERR_LIVE_GETPOSTKEY_FAILED;
842 if (WinHttpQueryHeaders(hGetPostKeySession,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
843 rslt = NLIB_ERR_LIVE_GETPOSTKEY_FAILED;
848 if (HTTP_STATUS_OK != statusCode){
849 rslt = NLIB_ERR_LIVE_GETPOSTKEY_FAILED;
857 if(ReadHttpBody(hGetPostKeySession,(LPBYTE)postKeyBuf,buflen,&readSize) == FALSE){
859 rslt = NLIB_ERR_LIVE_GETPOSTKEY_FAILED;
863 postKeyBuf[readSize] = '\0';
864 postKey = strstr(postKeyBuf,"=") + 1;
868 LPSTR buffer = (LPSTR)&cookieBuf[NICOLIVE_SENDCHATBUFLEN];
873 //mail
\83R
\83}
\83\93\83h
\8dì
\90¬
874 if(mail == NULL || mail[0] == NULL){
880 mailBuf = (LPSTR)postKeyReqBuf;
882 strcpy(indexPtr,"mail=\"");
883 indexPtr += strlen(indexPtr);
885 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - mailBuf) - 1;
886 if(GetLenToMB(CP_UTF8,mail[0]) >= len){
887 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
893 WideToMB(CP_UTF8,mail[0],indexPtr,len);
894 indexPtr += strlen(indexPtr);
897 for(mail++;mail[0] != NULL;mail++){
902 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - mailBuf) - 1;
904 if(GetLenToMB(CP_UTF8,mail[0]) >= len){
905 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
910 WideToMB(CP_UTF8,mail[0],indexPtr,len);
911 indexPtr += strlen(indexPtr);
915 strcpy(indexPtr,"\"");
922 //
\8ag
\92£
\91®
\90«
\8dì
\90¬
923 if(extends == NULL || extends[0] == NULL){
929 extendBuf =(LPSTR)cookieBuf;
930 indexPtr = extendBuf;
933 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - extendBuf) - 1;
935 if(GetLenToMB(CP_UTF8,extends[0]) >= len){
936 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
940 WideToMB(CP_UTF8,extends[0],indexPtr,len);
942 indexPtr += strlen(indexPtr);
944 strcpy(indexPtr,"=\"");
945 indexPtr += strlen(indexPtr);
948 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - extendBuf) - 1;
950 if(GetLenToMB(CP_UTF8,extends[1]) >= len){
951 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
955 WideToMB(CP_UTF8,extends[1],indexPtr,len);
958 for(extends+= 2;extends[0] != NULL;extends+=2){
963 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - extendBuf) - 1;
965 if(GetLenToMB(CP_UTF8,extends[0]) >= len){
966 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
970 WideToMB(CP_UTF8,extends[0],indexPtr,len);
972 indexPtr += strlen(indexPtr);
978 len = NICOLIVE_SENDCHATBUFLEN - (indexPtr - extendBuf) - 1;
980 if(GetLenToMB(CP_UTF8,extends[1]) >= len){
981 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
985 WideToMB(CP_UTF8,extends[1],indexPtr,len);
990 indexPtr += strlen(indexPtr);
991 strcpy(indexPtr,"\"");
997 //
\83`
\83\83\83b
\83g
\91\97\90M
\83R
\83\81\83\93\83g
\8dì
\90¬
1000 //
\96{
\93\96\82Í
\82±
\82¤
\82µ
\82½
\82¢:"<chat thread=\"%d\" ticket=\"%S\" postkey=\"%s\" user_id=\"%S\" premium=\"%d\" locale=\"%S\" vpos=\"%ld\"%s>%S</chat>"
1001 strcpy(indexPtr,"<chat thread=\"");
1002 indexPtr += strlen(indexPtr);
1003 sprintf(indexPtr,"%u",self->playerStatus.ms.thread);
1004 indexPtr += strlen(indexPtr);
1005 strcpy(indexPtr,"\" ticket=\"");
1006 indexPtr += strlen(indexPtr);
1007 WideToMB(CP_UTF8,self->ticket,indexPtr,NICOLIVE_SENDCHATBUFLEN - (indexPtr - buffer) - 1);
1008 indexPtr += strlen(indexPtr);
1009 strcpy(indexPtr,"\" postkey=\"");
1010 indexPtr += strlen(indexPtr);
1011 strcpy(indexPtr,postKey);
1012 indexPtr += strlen(indexPtr);
1013 strcpy(indexPtr,"\" user_id=\"");
1014 indexPtr += strlen(indexPtr);
1015 WideToMB(CP_UTF8,self->playerStatus.user.user_id,indexPtr,NICOLIVE_SENDCHATBUFLEN - (indexPtr - buffer) - 1);
1016 indexPtr += strlen(indexPtr);
1017 strcpy(indexPtr,"\" premium=\"");
1018 indexPtr += strlen(indexPtr);
1019 sprintf(indexPtr,"%u",self->playerStatus.user.is_premium);
1020 indexPtr += strlen(indexPtr);
1021 strcpy(indexPtr,"\" locale=\"");
1022 indexPtr += strlen(indexPtr);
1023 WideToMB(CP_UTF8,self->playerStatus.user.userDomain,indexPtr,NICOLIVE_SENDCHATBUFLEN - (indexPtr - buffer) - 1);
1024 indexPtr += strlen(indexPtr);
1025 strcpy(indexPtr,"\" vpos=\"");
1026 indexPtr += strlen(indexPtr);
1030 sprintf(indexPtr,"%u",(self->chatManager.baseVpos + ((timeGetTime() - self->chatManager.commentStartTime) / 10)));
1033 indexPtr += strlen(indexPtr);
1034 strcpy(indexPtr,"\"");
1035 indexPtr += strlen(indexPtr);
1037 if(strlen(mailBuf) > 0 && strlen(extendBuf) > 0){
1041 strcpy(indexPtr,mailBuf);
1042 indexPtr += strlen(indexPtr);
1047 strcpy(indexPtr,extendBuf);
1048 indexPtr += strlen(indexPtr);
1051 } else if(strlen(mailBuf) > 0){
1054 strcpy(indexPtr,mailBuf);
1055 indexPtr += strlen(indexPtr);
1057 } else if(strlen(extendBuf) > 0){
1060 strcpy(indexPtr,extendBuf);
1061 indexPtr += strlen(indexPtr);
1063 strcpy(indexPtr,">");
1064 indexPtr += strlen(indexPtr);
1066 LPTSTR sendBuf = (LPTSTR)&buffer[NICOLIVE_SENDCHATBUFLEN * 4];
1067 LPTSTR sendPtr = sendBuf;
1068 LPCTSTR endPtr= chatbuf + wcslen(chatbuf);
1071 //convertTEXT(indexPtr,chatbuf,indexPtr,endPtr);
1073 for(;(chatbuf) <= (endPtr);(chatbuf)++){
1076 wcscpy((sendBuf),L"&");
1077 (sendBuf) += wcslen(sendBuf);
1080 wcscpy((sendBuf),L"<");
1081 (sendBuf) += wcslen(sendBuf);
1084 wcscpy((sendBuf),L">");
1085 (sendBuf) += wcslen(sendBuf);
1088 wcscpy((sendBuf),L""");
1089 (sendBuf) += wcslen(sendBuf);
1092 wcscpy((sendBuf),L"'");
1093 (sendBuf) += wcslen(sendBuf);
1096 sendBuf[0] = chatbuf[0];
1103 WideToMB(CP_UTF8,sendPtr,indexPtr,NICOLIVE_SENDCHATBUFLEN * 4 - (indexPtr - buffer) - 1);
1104 indexPtr += strlen(indexPtr);
1107 strcpy(indexPtr,"</chat>");
1108 indexPtr[strlen(indexPtr)] = '\0';
1113 INT_PTR sendLen = 0;
1114 INT_PTR sentLen = 0;
1115 INT_PTR max = strlen(buffer) + 1;
1118 sendLen = send(self->chatManager.sock,buffer,max - sentLen,0);
1120 } while(sendLen > 0);
1130 WinHttpCloseHandle(hGetPostKeySession);
1132 //ZeroMemory(self->sessionManager.buffer,sizeof(self->sessionManager.buffer));
1133 LeaveCriticalSection(&self->sessionManager.cs);
1142 NLIB_RESULT NicoLiveStream_sendOwnerChat(NicoLiveStream_P self,LPCTSTR chatbuf,LPCTSTR *mail,LPCTSTR *extends){
1144 static const LPCTSTR OWNERCHAT_REQUEST = TEXT("api/broadcast/%s?body=%s%s&token=%s%s");
1145 NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
1146 LPVOID buffer = malloc(LENGTH_65536 * sizeof(TCHAR));
1147 LPTSTR requestBuffer = (LPTSTR)buffer;
1148 const UINT_PTR buflen = LENGTH_8192;
1149 LPTSTR mailBuf = (LPTSTR)&requestBuffer[buflen];
1150 LPTSTR extendsBuf = (LPTSTR)&mailBuf[buflen];
1151 LPSTR recvBuffer = (LPSTR)&extendsBuf[buflen];
1155 DWORD statusCodeSize = sizeof(statusCode);
1156 UINT_PTR reqLength = _tcslen(chatbuf);
1157 HINTERNET hRequest = NULL;
1165 if(self->playerStatus.stream.is_owner == FALSE){
1171 for(LPCTSTR *mailStart = mail;mailStart[0] != NULL;++mailStart){
1173 reqLength += _tcslen(mailStart[0]);
1177 LPCTSTR *extendsArrayIndex = extends;
1178 for(;extendsArrayIndex[0] != NULL;extendsArrayIndex+=2){
1180 reqLength += _tcslen(extendsArrayIndex[0]);
1181 reqLength += _tcslen(extendsArrayIndex[1]);
1184 if(reqLength > buflen / 2){
1189 LPTSTR mailIndexPtr = mailBuf;
1190 if(mail[0] == NULL){
1191 _tcscpy(mailIndexPtr,TEXT(""));
1195 _tcscpy(mailIndexPtr,TEXT("&mail="));
1196 mailIndexPtr += _tcslen(mailIndexPtr);
1199 for(LPCTSTR *mailArrayIndex = mail;mailArrayIndex[0] != NULL;++mailArrayIndex){
1201 _tcscpy(mailIndexPtr,mailArrayIndex[0]);
1202 mailIndexPtr += _tcslen(mailIndexPtr);
1204 if(mailArrayIndex[1] != NULL){
1206 mailIndexPtr[0] = TEXT(' ');
1213 LPTSTR extendsIndexPtr = extendsBuf;
1214 _tcscpy(extendsIndexPtr,TEXT(""));
1215 for(LPCTSTR *extendsArrayIndex2 = extends;extendsArrayIndex2[0] != NULL;extendsArrayIndex2+=2){
1218 extendsIndexPtr[0] = TEXT('&');
1222 _tcscpy(extendsIndexPtr,extendsArrayIndex2[0]);
1223 extendsIndexPtr += _tcslen(extendsIndexPtr);
1224 extendsIndexPtr[0] = TEXT('=');
1226 _tcscpy(extendsIndexPtr,extendsArrayIndex2[1]);
1227 extendsIndexPtr += _tcslen(extendsIndexPtr);
1232 _stprintf(requestBuffer,OWNERCHAT_REQUEST,self->playerStatus.stream.id,chatbuf,mailBuf,self->publishStatus.token,extendsBuf);
1234 ::EnterCriticalSection(&self->sessionManager.cs);
1235 hRequest = WinHttpOpenRequest(hWatchLiveNicoConnect,L"GET",requestBuffer,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
1237 if(WinHttpSendRequest(hRequest,self->userSession,-1,WINHTTP_NO_REQUEST_DATA,0,0,0) == FALSE){
1243 if(WinHttpReceiveResponse(hRequest,NULL) == FALSE){
1249 if (WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
1254 if (HTTP_STATUS_OK != statusCode){
1259 //recvBuffer = (LPSTR)sendBuffer;
1262 if(ReadHttpBody(hRequest,(LPBYTE)recvBuffer,buflen,&readSize) == FALSE){
1272 WinHttpCloseHandle(hRequest);
1273 ::LeaveCriticalSection(&self->sessionManager.cs);
1279 rslt = NLIB_FAILED_CONNECT;
1285 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
1290 rslt = NLIB_ERR_STREAM_IS_NULL;
1294 rslt = NLIB_ERR_YOUARE_NOTOWNER;
1303 //
\83C
\83\93\83\89\83C
\83\93\8aÖ
\90\94
1308 //NLIB_RESULT GetPlayerStatus(NicoLivePlayerStatus_P self,LPCTSTR userSession,HINTERNET hConnect,LPVOID buffer){
1309 NLIB_RESULT GetPlayerStatus(NicoLivePlayerStatus_P self,LPCTSTR userSession,HINTERNET hConnect){
1312 return HttpXMLParse(self,userSession,hConnect,NPlayerStatus_ElementStartHandler,NPlayerStatus_ElementEndHandler,NPlayerStatus_CharacterDataHandler);
1316 static INLINE NLIB_RESULT GetPublishStatus(NicoLivePublishStatus_P self,LPCTSTR userSession,HINTERNET hConnect){
1319 return HttpXMLParse(self,userSession,hConnect,NPublishStatus_ElementStartHandler,NPublishStatus_ElementEndHandler,NPublishStatus_CharacterDataHandler);
1324 #define GETNICOLIVEHIS_OBJNAMELENGTH LENGTH_256
1325 #define GETNICOLIVEHIS_COOKIELENGTH LENGTH_512
1327 #ifdef USE_NLIB_LIVEHISTORY
1329 static INLINE NLIB_RESULT GetNicoLiveHistory(NicoLiveStream_P self,HINTERNET hConnect){
1331 NLIB_RESULT rslt = NLIB_ERR_OK;
1333 EnterCriticalSection(&self->sessionManager.cs);
1336 HINTERNET hStreamBrowse = NULL;
1339 TCHAR objectName[GETNICOLIVEHIS_OBJNAMELENGTH] = {L"/watch/"};
1340 TCHAR cookie[GETNICOLIVEHIS_COOKIELENGTH] = {L"Cookie: "};
1342 DWORD statusCodeSize = sizeof(statusCode);
1343 DWORD chunkSize = LENGTH_65536;
1344 LPVOID chunkMemory =self->sessionManager.buffer;
1348 LPTSTR buffer = (LPTSTR)chunkMemory;
1352 if((GETNICOLIVEHIS_OBJNAMELENGTH - wcslen(objectName) <= wcslen(self->playerStatus.stream.id)) || GETNICOLIVEHIS_COOKIELENGTH - wcslen(cookie) <= wcslen(self->userSession)){
1354 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
1358 wcscat(objectName,self->playerStatus.stream.id);
1359 wcscat(cookie,self->userSession);
1365 hStreamBrowse = WinHttpOpenRequest(hNicoVideoConnect,L"GET",objectName,L"1.1",(LPCTSTR)WINHTTP_NO_REFERER,(LPCTSTR*)WINHTTP_DEFAULT_ACCEPT_TYPES,0);
1370 if(WinHttpSendRequest(hStreamBrowse,cookie,-1,WINHTTP_NO_REQUEST_DATA,0,0,0) == FALSE){
1372 rslt = NLIB_FAILED_CONNECT;
1377 if(WinHttpReceiveResponse(hStreamBrowse,NULL) == FALSE){
1379 rslt = NLIB_FAILED_CONNECT;
1384 if (WinHttpQueryHeaders(hStreamBrowse,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
1385 rslt = NLIB_FAILED_CONNECT;
1390 if (HTTP_STATUS_OK != statusCode){
1391 rslt = NLIB_FAILED_CONNECT;
1397 if (WinHttpQueryHeaders(hStreamBrowse,WINHTTP_QUERY_SET_COOKIE,WINHTTP_HEADER_NAME_BY_INDEX,buffer,&chunkSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
1398 rslt = NLIB_FAILED_CONNECT;
1403 LPTSTR start =wcsstr(buffer,L"nicolivehistory=");
1405 LPTSTR end = wcsstr(start,L";");
1407 UINT_PTR length = end - start;
1409 if(length >= sizeof(self->nicoLiveHistory)){
1410 rslt = NLIB_ERR_BUFFER_TOOLITTLE;
1415 wcsncpy(self->nicoLiveHistory,start,length);
1416 self->nicoLiveHistory[length] = L'\0';
1421 WinHttpCloseHandle(hStreamBrowse);
1424 ZeroMemory(self->sessionManager.buffer,sizeof(self->sessionManager.buffer));
1425 LeaveCriticalSection(&self->sessionManager.cs);
1441 #ifdef USE_NLIB_KEEPALIVE
1442 static unsigned int WINAPI NicoLiveKeapALiveThread(void* lpBuffer){
1444 unsigned int rslt = 0;
1446 NicoLiveStream_P self = (NicoLiveStream_P)lpBuffer;
1448 rslt = loopCommon(self,self->chatManager.setKeepAliveTimeEvent,self->chatManager.resetEvents[KEEPALLIVERESETEVENT],self->chatManager.onKeepAlliveSend,&self->chatManager.keepAliveTime);
1454 #endif //USE_NLIB_KEEPALIVE
1456 static unsigned int WINAPI NicoLiveHeartBeatThread(void* lpBuffer){
1458 unsigned int rslt = 0;
1460 NicoLiveStream_P self = (NicoLiveStream_P)lpBuffer;
1463 rslt = loopCommon(self,self->chatManager.setHeartBeatTimeEvent,self->chatManager.resetEvents[1],self->chatManager.onHeartBeatSend,&self->chatManager.heartBeatTime);
1471 static unsigned int loopCommon(NicoLiveStream_P self,WSAEVENT sendEvent,WSAEVENT resetEvent ,NicoLiveOnSend nicoLiveOnSend,LPDWORD time){
1473 unsigned int rslt = 0;
1474 WSAEVENT events[3] = {self->chatManager.deleteEvent,self->chatManager.startEvent,self->chatManager.endEvent}; //
\83C
\83x
\83\93\83g
\94z
\97ñ
1475 WSAEVENT streamEvent[2] = {self->chatManager.endEvent,sendEvent};
1476 DWORD dwResult; //
\83C
\83x
\83\93\83g
\8eó
\90M
\8c\8b\89Ê
1481 WSASetEvent(resetEvent);
1483 dwResult = WSAWaitForMultipleEvents(sizeof(events) / sizeof(events[0]),events,FALSE,WSA_INFINITE,FALSE);
1486 //
\83G
\83\89\81[
\82Ì
\8fê
\8d\87
1487 if(dwResult == WSA_WAIT_FAILED){
1493 switch(dwResult - WSA_WAIT_EVENT_0){
1500 WSAResetEvent(resetEvent);
1514 WSAResetEvent(sendEvent);
1515 endResult = WSAWaitForMultipleEvents(sizeof(streamEvent) / sizeof(streamEvent[0]),streamEvent,FALSE,*time,FALSE);
1517 if(endResult == WSA_WAIT_TIMEOUT){
1519 nicoLiveOnSend(self);
1520 //dumpln(TEXT("onSend"));
1524 switch(endResult - WSA_WAIT_EVENT_0){
1547 _beginthread(NicoLiveError,0,self);
1552 static VOID OnSendHeartBeat(NicoLiveStream_P self){
1554 if(self->chatManager.heartBeatFlag){
1555 NicoLiveStream_sendHeartBeat(self);
1559 #ifdef USE_NLIB_KEEPALIVE
1560 static VOID OnSendKeepAllive(NicoLiveStream_P self){
1563 if(self->chatManager.keapALiveFlag && self->playerStatus.stream.is_owner == TRUE){
1564 LPCTSTR mail[2] = {L"184",NULL};
1565 NicoLiveStream_sendChat(self,L"/keapalive",mail,NULL);
1572 #define NICOLIVE_RECEVE_CHAT_LENGTH LENGTH_2048
1573 #define NICOLIVE_REQUEST_CHAT_LENGTH LENGTH_256
1574 static unsigned int WINAPI NicoLiveRecvChat(void* lpBuffer){
1577 unsigned int rslt = 0;
1579 //LPTSTR user_id = NULL;
1580 //LPTSTR name = NULL;
1581 //LPTSTR chatBuf = NULL;
1585 CHAR requestChat[NICOLIVE_REQUEST_CHAT_LENGTH]; //
\91\97\90M
\93d
\95¶
\97p
\83o
\83b
\83t
\83@
1586 LPCSTR sendFormat = "<thread thread=\"%u\" res_from=\"%d\" version=\"20061206\" />"; //
\91\97\90M
\93d
\95¶
\83t
\83H
\81[
\83}
\83b
\83g
1587 NicoLiveStream_P self = (NicoLiveStream_P)lpBuffer; //
\83j
\83R
\90¶
\95ú
\91\97\83I
\83u
\83W
\83F
\83N
\83g
1588 INT_PTR sendLen; //
\91\97\90M
\97p
\95¶
\8e\9a\90\94
1589 INT_PTR sentLen; //
\91\97\90M
\8dÏ
\82Ý
\95¶
\8e\9a\90\94
1590 WSAEVENT events[3] = {self->chatManager.deleteEvent,self->chatManager.startEvent,self->chatManager.endEvent}; //
\83C
\83x
\83\93\83g
\94z
\97ñ
1591 DWORD dwResult; //
\83C
\83x
\83\93\83g
\8eó
\90M
\8c\8b\89Ê
1597 WSASetEvent(self->chatManager.resetEvents[0]);
1599 dwResult = WSAWaitForMultipleEvents(sizeof(events) / sizeof(events[0]),events,FALSE,WSA_INFINITE,FALSE);
1602 //
\83G
\83\89\81[
\82Ì
\8fê
\8d\87
1603 if(dwResult == WSA_WAIT_FAILED){
1609 switch(dwResult - WSA_WAIT_EVENT_0){
1616 WSAResetEvent(self->chatManager.resetEvents[0]);
1632 //
\83\
\83P
\83b
\83g
\82Ì
\90Ý
\92è
1633 self->chatManager.sock = GetConectedSocket(self->playerStatus.ms.addr,self->playerStatus.ms.port,SOCK_STREAM,AF_INET,IPPROTO_TCP);
1636 //
\83R
\83\81\83\93\83g
\8eó
\90M
\8aJ
\8en
\82Ì
\89º
\8f\80\94õ
1637 if(self->chatManager.sock == INVALID_SOCKET){
1638 self->error = NLIB_ERR_FAILED_NETWORK;
1647 if(NICOLIVE_REQUEST_CHAT_LENGTH <= _scprintf(sendFormat,self->playerStatus.ms.thread,self->res_from)){
1649 self->error = NLIB_ERR_BUFFER_TOOLITTLE;
1656 sprintf(requestChat,sendFormat,self->playerStatus.ms.thread,self->res_from);
1660 //
\83R
\83\81\83\93\83g
\8eó
\90M
\97v
\8b\81\91\97\90M
\8f\88\97\9d
1664 sendLen = strlen(requestChat) + 1;
1666 len = send(self->chatManager.sock,requestChat,sendLen,0);
1667 if(len == SOCKET_ERROR){
1668 self->error = NLIB_ERR_FAILED_NETWORK;
1676 }while(sentLen < sendLen);
1680 if(NicoLiveRecvChatLoop(self) == FALSE){
1692 _beginthread(NicoLiveError,0,self);
1698 closesocket(self->chatManager.sock);
1713 static BOOL NicoLiveRecvChatLoop(NicoLiveStream_P self){
1717 //
\83R
\83\81\83\93\83g
\8eó
\90M
\8f\88\97\9d
1719 BOOL rslt = TRUE; //
\8c\8b\89Ê
1720 LPTSTR commentBuf = NULL; //
\83R
\83\81\83\93\83g
\83o
\83b
\83t
\83@
1721 LPTSTR* mailCountBuf = NULL; //
\83\81\81[
\83\8b\83|
\83C
\83\93\83^
\83o
\83b
\83t
\83@
1722 INT_PTR recevedLen; //
\8eó
\90M
\95¶
\8e\9a\97ñ
\92·
1723 INT_PTR messageBufLen; //
\83o
\83b
\83t
\83@
\92·
1727 WSAEVENT hEventArray[2]; //
\8eó
\90M
\81E
\90Ø
\92f
\82ð
\8c\9f\92m
\82·
\82é
\83C
\83x
\83\93\83g
\83I
\83u
\83W
\83F
\83N
\83g
\82Ì
\94z
\97ñ
1728 WSANETWORKEVENTS netEvents; //
\83l
\83b
\83g
\83\8f\81[
\83N
\83C
\83x
\83\93\83g
1729 DWORD dwResult; //
\83C
\83x
\83\93\83g
\82ª
\83E
\83F
\83C
\83g
\8aÖ
\90\94\82Ì
\8c\8b\89Ê
\82ð
\8ai
\94[
\82·
\82é
\95Ï
\90\94
1732 SIZE_T commentBufSize = sizeof(TCHAR) * LENGTH_2048; //
\83R
\83\81\83\93\83g
\83o
\83b
\83t
\83@
\92·
1733 SIZE_T mailCountBufSize = sizeof(LPTSTR) * LENGTH_256; //
\83\81\81[
\83\8b\82Ì
\83|
\83C
\83\93\83^
\97p
\83o
\83b
\83t
\83@
\92·
1736 WSAEVENT hRecvEvent = NULL;
1738 //
\8eó
\90M
\8f\80\94õ
\8f\88\97\9d
1739 self->chatManager.commentCountSum = 0;
1740 hRecvEvent = WSACreateEvent();
1741 self->chatManager.recvBuf[0] = '\0';
1742 WSAEventSelect(self->chatManager.sock, hRecvEvent, FD_READ | FD_CLOSE);
1743 hEventArray[0] = hRecvEvent;
1744 hEventArray[1] = self->chatManager.endEvent;
1746 commentBuf = (LPTSTR)malloc(commentBufSize * sizeof(TCHAR));
1747 mailCountBuf = (LPTSTR*)malloc(mailCountBufSize * sizeof(TCHAR));
1749 //
\90Ø
\92f
\82³
\82ê
\82é
\82Ü
\82Å
\83\8b\81[
\83v
1754 //
\91O
\82Ì
\83R
\83\81\83\93\83g
\8eó
\90M
\8e\9e\82É
\97]
\82Á
\82½
\95¶
\8e\9a\97ñ
\82Ì
\92·
\82³
\82ð
\92²
\82×
\82é
1755 messageBufLen = strlen(self->chatManager.recvBuf);
1757 //
\8eó
\90M
\82©
\8fI
\97¹
\83C
\83x
\83\93\83g
\82ð
\8c\9f\92m
\82·
\82é
\82Ü
\82Å
\91Ò
\8b@
1758 dwResult = WSAWaitForMultipleEvents(sizeof(hEventArray) / sizeof(hEventArray[0]),hEventArray,FALSE,WSA_INFINITE,FALSE);
1760 //
\83G
\83\89\81[
\82Ì
\8fê
\8d\87
1761 if(dwResult == WSA_WAIT_FAILED){
1768 //
\83R
\83\81\83\93\83g
\8eó
\90M
\83C
\83x
\83\93\83g
\82ª
\83V
\83O
\83i
\83\8b\82É
\82È
\82Á
\82½
\8fê
\8d\87
1769 if(dwResult - WSA_WAIT_EVENT_0 == 0){
1771 WSAEnumNetworkEvents(self->chatManager.sock,hRecvEvent,&netEvents);
1773 //
\93Ç
\8eæ
\83C
\83x
\83\93\83g
\82Ì
\8fê
\8d\87\83R
\83\81\83\93\83g
\82ð
\8eó
\90M
\82·
\82é
1774 if(netEvents.lNetworkEvents & FD_READ){
1777 recevedLen = recv(self->chatManager.sock,&self->chatManager.recvBuf[messageBufLen],(sizeof(self->chatManager.recvBuf) - 1) - messageBufLen ,0);
1779 if(recevedLen == SOCKET_ERROR){
1780 self->error = NLIB_ERR_FAILED_NETWORK;
1785 self->chatManager.recvBuf[messageBufLen + recevedLen] = '\0';
1792 NicoLiveParseComment(self,commentBuf,messageBufLen + recevedLen,mailCountBuf,&mailCountBufSize,&commentBufSize);
1798 } else if(netEvents.lNetworkEvents && FD_CLOSE){
1802 }//if(netEvents.lNetworkEvents & FD_READ)
1804 } else if(dwResult - WSA_WAIT_EVENT_0 == 1){
1808 }//if(dwResult - WSA_WAIT_EVENT_0 == 0)
1817 self->callBack(NICOLIVE_EVENT_DISCONNECT,self,self->option,(NICOLIVE_PARAM)NULL,(NICOLIVE_PARAM)NULL);
1821 WSACloseEvent(hRecvEvent);
1829 static VOID NicoLiveParseComment(NicoLiveStream_P self,LPTSTR commentBuf,UINT_PTR endSize,LPTSTR* mailCountBuf,SIZE_T* mailCountBufSize,SIZE_T* commentBufSize){
1831 LPTSTR indexPtr; //
\89ð
\90Í
\8e\9e\82Ì
\8ew
\95W
\83|
\83C
\83\93\83^
1832 NicoLiveChat nicoLiveChat; //
\83`
\83\83\83b
\83g
\83R
\83\81\83\93\83g
\8ai
\94[
\97p
\8d\
\91¢
\91Ì
1833 NicoLiveThreadComment nicoLiveThreadComment; //
\90Ú
\91±
\89\9e\93\9a\83R
\83\81\83\93\83g
\8ai
\94[
\97p
\8d\
\91¢
\91Ì
1834 NicoLiveSendResultComment nicoLiveSendResultComment; //
\91\97\90M
\89\9e\93\9a\83R
\83\81\83\93\83g
\8ai
\94[
\97p
\8d\
\91¢
\91Ì
1835 NicoLiveChat nicoLiveChatBase; //
\83`
\83\83\83b
\83g
\83R
\83\81\83\93\83g
\8aî
\92ê
\8d\
\91¢
\91Ì
1836 NicoLiveThreadComment nicoLiveThreadCommentBase; //
\90Ú
\91±
\89\9e\93\9a\83R
\83\81\83\93\83g
\8aî
\92ê
\8d\
\91¢
\91Ì
1837 NicoLiveSendResultComment nicoLiveSendResultCommentBase;//
\91\97\90M
\89\9e\93\9a\83R
\83\81\83\93\83g
\8aî
\92ê
\8d\
\91¢
\91Ì
1838 LPTSTR attrNameStart; //
\91®
\90«
\96¼
\8aJ
\8en
\83|
\83C
\83\93\83^
1839 LPTSTR attrNameEnd; //
\91®
\90«
\96¼
\8fI
\97¹
\83|
\83C
\83\93\83^
1840 LPTSTR attrValueStart; //
\91®
\90«
\92l
\8aJ
\8en
\83|
\83C
\83\93\83^
1841 LPTSTR attrValueEnd; //
\91®
\90«
\92l
\8fI
\97¹
\83|
\83C
\83\93\83^
1842 INT_PTR nameLen; //
\91®
\90«
\82Ì
\96¼
\91O
\82Ì
\92·
\82³
1843 LPTSTR mailIndexPtr; //
\83\81\81[
\83\8b\91®
\90«
\92l
\89ð
\90Í
\97p
\8ew
\95W
\83|
\83C
\83\93\83^
1844 LPTSTR xmlTextPtr; //xml
\83e
\83L
\83X
\83g
\8c`
\8e®
\82Ì
\83f
\81[
\83^
\89ð
\90Í
\8e\9e\82É
\8eg
\97p
\82·
\82é
\83|
\83C
\83\93\83^
1845 LPTSTR xmlTextEnd; //xml
\83e
\83L
\83X
\83g
\8fI
\97¹
\83|
\83C
\83\93\83^
1846 LPTSTR* mailIndex; //
\83\81\81[
\83\8b\83R
\83}
\83\93\83h
\83\8a\83X
\83g
\83|
\83C
\83\93\83^
1847 BOOL isReceveChat = FALSE; //
\83`
\83\83\83b
\83g
\8eó
\90M
\83t
\83\89\83O
1848 SIZE_T commentSizeCh; //
\8eó
\90M
\82µ
\82½
\83R
\83\81\83\93\83g
\82ð
\83\86\83j
\83R
\81[
\83h
\82É
\95Ï
\8a·
\82·
\82é
\82Æ
\82«
\82Ì
\92·
\82³
1849 LPSTR recvBufTmp; //
\8eó
\90M
\95¶
\8e\9a\97ñ
\91\80\8dì
\97p
\83|
\83C
\83\93\83^
1850 LPSTR recvEndPoint; //
\8eó
\90M
\95¶
\8e\9a\97ñ
\8fI
\92[
\83|
\83C
\83\93\83^
1854 recvBufTmp = &self->chatManager.recvBuf[0];
1855 recvEndPoint = &self->chatManager.recvBuf[endSize];
1858 //
\83R
\83\81\83\93\83g
\8aî
\92ê
\8d\
\91¢
\91Ì
\8f\89\8aú
\89»
1859 nicoLiveChatBase.anonymity = L"";
1860 nicoLiveChatBase.chatBuf = L"";
1861 nicoLiveChatBase.date = L"";
1862 nicoLiveChatBase.locale = L"";
1863 nicoLiveChatBase.mail = mailCountBuf;
1864 nicoLiveChatBase.name = L"";
1865 nicoLiveChatBase.no = L"";
1866 nicoLiveChatBase.premium = L"";
1867 nicoLiveChatBase.thread = L"";
1868 nicoLiveChatBase.user_id = L"";
1869 nicoLiveChatBase.vpos = L"";
1870 nicoLiveChatBase.mailCount = 0;
1874 nicoLiveThreadCommentBase.last_res = L"";
1875 nicoLiveThreadCommentBase.thread = L"";
1876 nicoLiveThreadCommentBase.ticket = L"";
1879 nicoLiveSendResultCommentBase.no = L"";
1880 nicoLiveSendResultCommentBase.status = L"";
1881 nicoLiveSendResultCommentBase.thread = L"";
1884 //
\8eó
\90M
\82µ
\82½
\83R
\83\81\83\93\83g
\82ð
\82Ð
\82Æ
\82Â
\82Ìxml
\83m
\81[
\83h
\82²
\82Æ
\82É
\89ð
\90Í
\82·
\82é
1885 for (;recvBufTmp + strlen(recvBufTmp) < recvEndPoint;recvBufTmp += strlen(recvBufTmp) + 1){
1888 commentSizeCh = sizeof(TCHAR) * GetLenToWide(CP_UTF8,recvBufTmp);
1889 extendMalloc(commentBuf,LPTSTR,*commentBufSize,commentSizeCh);
1890 MBToWide(CP_UTF8,recvBufTmp,commentBuf,*commentBufSize);
1892 traceln(TEXT("comment:\r\n%s"),commentBuf);
1893 //thread
\83m
\81[
\83h
\82Ì
\8fê
\8d\87
1894 if((indexPtr = wcsstr(commentBuf,L"<thread ")) != NULL){
1896 indexPtr += wcslen(L"<thread ");
1897 skipXMLSPACE(indexPtr);
1902 nicoLiveThreadComment = nicoLiveThreadCommentBase;
1904 while(wcsncmp(indexPtr,L"/>",wcslen(L"/>")) != 0){
1905 parseAttr(indexPtr,attrNameStart,attrNameEnd,attrValueStart,attrValueEnd);
1908 nameLen = attrNameEnd - attrNameStart;
1909 if(wcsncmp(attrNameStart,L"ticket",nameLen) == 0){
1912 partString(nicoLiveThreadComment.ticket,attrValueStart,attrValueEnd);
1913 wcscpy(self->ticket,nicoLiveThreadComment.ticket);
1915 } else if(wcsncmp(attrNameStart,L"last_res",nameLen) == 0){
1917 partString(nicoLiveThreadComment.last_res,attrValueStart,attrValueEnd);
1920 } else if(wcsncmp(attrNameStart,L"thread",nameLen) == 0){
1922 partString(nicoLiveThreadComment.thread,attrValueStart,attrValueEnd);
1923 } else if(wcsncmp(attrNameStart,L"server_time",nameLen) == 0){
1925 NicoLiveStream_setVpos((*self),attrValueStart);
1927 nicoLiveThreadComment.server_time = wcstoul(attrValueStart,NULL,10);
1928 //partString(nicoLiveThreadComment.server_time,attrValueStart,attrValueEnd);
1931 skipXMLSPACE(indexPtr);
1936 self->callBack(NICOLIVE_EVENT_RECEVE_CONNECTRESULT,self,self->option,(NICOLIVE_PARAM)&nicoLiveThreadComment,self->chatManager.chatNo);
1938 //chat
\83m
\81[
\83h
\82Ì
\8fê
\8d\87
1939 } else if((indexPtr = wcsstr(commentBuf,L"<chat ")) != NULL){
1941 indexPtr += wcslen(L"<chat ");
1942 skipXMLSPACE(indexPtr);
1947 nicoLiveChat = nicoLiveChatBase;
1949 while(wcsncmp(indexPtr,L">",wcslen(L">"))){
1951 parseAttr(indexPtr,attrNameStart,attrNameEnd,attrValueStart,attrValueEnd);
1953 nameLen = attrNameEnd - attrNameStart;
1956 if(wcsncmp(attrNameStart,L"no",nameLen) == 0){
1958 partString(nicoLiveChat.no,attrValueStart,attrValueEnd);
1960 } else if(wcsncmp(attrNameStart,L"date",nameLen) == 0){
1962 NicoLiveStream_setVpos((*self),attrValueStart);
1964 partString(nicoLiveChat.date,attrValueStart,attrValueEnd);
1966 } else if(wcsncmp(attrNameStart,L"thread",nameLen) == 0){
1968 partString(nicoLiveChat.thread,attrValueStart,attrValueEnd);
1970 } else if(wcsncmp(attrNameStart,L"premium",nameLen) == 0){
1972 partString(nicoLiveChat.premium,attrValueStart,attrValueEnd);
1974 } else if(wcsncmp(attrNameStart,L"anonymity",nameLen) == 0){
1976 partString(nicoLiveChat.anonymity,attrValueStart,attrValueEnd);
1979 } else if(wcsncmp(attrNameStart,L"locale",nameLen) == 0){
1981 partString(nicoLiveChat.locale,attrValueStart,attrValueEnd);
1983 } else if(wcsncmp(attrNameStart,L"vpos",nameLen) == 0){
1985 partString(nicoLiveChat.vpos,attrValueStart,attrValueEnd);
1987 } else if(wcsncmp(attrNameStart,L"user_id",nameLen) == 0){
1989 partString(nicoLiveChat.user_id,attrValueStart,attrValueEnd);
1991 } else if(wcsncmp(attrNameStart,L"name",nameLen) == 0){
1993 partString(nicoLiveChat.name,attrNameStart,attrValueEnd);
1995 } else if(wcsncmp(attrNameStart,L"mail",nameLen) == 0){
1997 nicoLiveChat.mailCount = 1;
2000 for(mailIndexPtr = attrValueStart;mailIndexPtr <= attrValueEnd;mailIndexPtr++){
2002 if(mailIndexPtr[0] == L' '){
2004 nicoLiveChat.mailCount++;
2010 extendMalloc(mailCountBuf,LPTSTR*,*mailCountBufSize,nicoLiveChat.mailCount);
2012 nicoLiveChat.mail = mailCountBuf;
2013 mailCountBuf[0] = NULL;
2015 for(mailIndex = mailCountBuf,mailIndexPtr = attrValueStart,mailIndex[0] = mailIndexPtr;mailIndexPtr < attrValueEnd;mailIndexPtr++){
2018 if(mailIndexPtr[0] == L' '){
2020 mailIndex[0] = mailIndexPtr + 1;
2021 mailIndexPtr[0] = L'\0';
2028 mailIndexPtr[0] = L'\0';
2032 skipXMLSPACE(indexPtr);
2036 xmlTextPtr = indexPtr;
2037 xmlTextEnd = wcsstr(indexPtr,L"<");
2038 convertXMLTEXT(nicoLiveChat.chatBuf,indexPtr,xmlTextPtr,xmlTextEnd);
2042 self->chatManager.chatNo = wcstoul(nicoLiveChat.no,NULL,10);
2046 self->chatManager.commentCountSum++;
2047 isReceveChat = TRUE;
2049 check((_heapchk() == _HEAPOK),TEXT("
\83q
\81[
\83v
\83G
\83\89\81[
\82Å
\82·"));
2051 if((wcscmp(nicoLiveChat.chatBuf,L"/disconnect") == 0 && wcscmp(nicoLiveChat.premium,L"2") == 0)){
2054 _beginthread(NicoLiveSelfDisconnect,0,self);
2056 self->callBack(NICOLIVE_EVENT_RECEVE_CHAT,self,self->option,(NICOLIVE_PARAM)&nicoLiveChat,self->chatManager.commentCountSum);
2059 //chat_result
\83m
\81[
\83h
\82Ì
\8fê
\8d\87
2060 } else if((indexPtr = wcsstr(commentBuf,L"<chat_result ")) != NULL){
2062 indexPtr += wcslen(L"<chat_result ");
2064 nicoLiveSendResultComment = nicoLiveSendResultCommentBase;
2066 while(wcsncmp(indexPtr,L"/>",wcslen(L"/>")) != 0){
2067 parseAttr(indexPtr,attrNameStart,attrNameEnd,attrValueStart,attrValueEnd);
2070 nameLen = attrNameEnd - attrNameStart;
2071 if(wcsncmp(attrNameStart,L"no",nameLen) == 0){
2074 partString(nicoLiveSendResultComment.no,attrValueStart,attrValueEnd);
2076 } else if(wcsncmp(attrNameStart,L"status",nameLen) == 0){
2078 partString(nicoLiveSendResultComment.status,attrValueStart,attrValueEnd);
2081 } else if(wcsncmp(attrNameStart,L"thread",nameLen) == 0){
2083 partString(nicoLiveSendResultComment.thread,attrValueStart,attrValueEnd);
2086 skipXMLSPACE(indexPtr);
2089 #ifdef USE_NLIB_KEEPALIVE
2090 //
\83L
\81[
\83v
\83A
\83\89\83C
\83u
\83\8a\83Z
\83b
\83g
2091 WSASetEvent(self->chatManager.setKeepAliveTimeEvent);
2092 #endif //USE_NLIB_KEEPALIVE
2094 self->callBack(NICOLIVE_EVENT_RECEVE_CHATSENDRESULT,self,self->option,(NICOLIVE_PARAM)&nicoLiveSendResultComment,(NICOLIVE_PARAM)NULL);
2100 if(recvBufTmp == recvEndPoint && isReceveChat){
2101 self->callBack(NICOLIVE_EVENT_RECEVE_CHATSETTLE,self,self->option,self->chatManager.chatNo,self->chatManager.commentCountSum);
2107 strcpy(&self->chatManager.recvBuf[0],recvBufTmp);
2124 static void NicoLiveError(void *buf){
2126 NicoLiveStream_P nl = (NicoLiveStream_P)buf;
2128 nl->callBack(NICOLIVE_EVENT_ERR_CONNECT,nl,nl->option,(NICOLIVE_PARAM)NULL,(NICOLIVE_PARAM)NULL);
2130 NicoLiveStream_disConnect(nl);
2138 static void NicoLiveSelfDisconnect(void *buf){
2140 NicoLiveStream_P nl = (NicoLiveStream_P)buf;
2142 dumpln(TEXT("selfdisconnect"),);
2144 NicoLiveStream_disConnect(nl);
2154 static INLINE SOCKET GetConectedSocket(LPCTSTR nordName,LPCTSTR port,int socktype,int addr_famiry,int protocol){
2157 SOCKET rslt = INVALID_SOCKET;
2160 PADDRINFOW res,res0;
2162 ZeroMemory(&hints,sizeof(hints));
2163 hints.ai_socktype = socktype;
2164 hints.ai_family = addr_famiry;
2165 hints.ai_protocol = protocol;
2166 GetAddrInfoW(nordName,port,&hints,&res0);
2169 for(res = res0; res != NULL;res = res->ai_next){
2174 rslt = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
2175 if(rslt == INVALID_SOCKET){
2188 if(connect(rslt,res->ai_addr,(int)res->ai_addrlen) == SOCKET_ERROR){
2203 rslt = INVALID_SOCKET;
2207 //res
\8d\
\91¢
\91Ì
\89ð
\95ú
2217 //
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\8aÖ
\98A
2221 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82ÌID
\82ð
\8eæ
\93¾
2223 NLIB_DECLSPEC LPCTSTR NicoLiveStream_getId(NicoLiveStream_P self){
2225 return self->playerStatus.stream.id;
2230 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\83R
\83~
\83\85\83j
\83e
\83B
\94Ô
\8d\86\82ð
\8eæ
\93¾
2232 NLIB_DECLSPEC LPCTSTR NicoLiveStream_getDefaultCommunity(NicoLiveStream_P self){
2234 return self->playerStatus.stream.default_community;
2239 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\83v
\83\8d\83o
\83C
\83_
\83^
\83C
\83v
\82ð
\8eæ
\93¾
2241 PROVIDERTYPE NicoLiveStream_getProviderType(NicoLiveStream_P self){
2243 return self->playerStatus.stream.provider_type;
2248 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\83I
\81[
\83i
\81[
\83t
\83\89\83O
\82ð
\8eæ
\93¾
2250 BOOL NicoLiveStream_isOwner(NicoLiveStream_P self){
2252 return self->playerStatus.stream.is_owner;
2256 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\8aJ
\8en
\8e\9e\8d\8f\82ð
\8eæ
\93¾
2258 time_t NicoLiveStream_getStartTime(NicoLiveStream_P self){
2260 return self->playerStatus.stream.start_time;
2264 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\8fI
\97¹
\8e\9e\8d\8f\82ð
\8eæ
\93¾
2266 time_t NicoLiveStream_getEndTime(NicoLiveStream_P self){
2268 return self->playerStatus.stream.end_time;
2272 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\8aJ
\8fê
\8e\9e\8d\8f\82ð
\8eæ
\93¾
2274 time_t NicoLiveStream_getOpenTime(NicoLiveStream_P self){
2276 return self->playerStatus.stream.open_time;
2281 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\83x
\81[
\83X
\8e\9e\8d\8f\82ð
\8eæ
\93¾
2283 time_t NicoLiveStream_getBaseTime(NicoLiveStream_P self){
2285 return self->playerStatus.stream.base_time;
2290 ///
\83X
\83g
\83\8a\81[
\83\80\83X
\83e
\81[
\83^
\83X
\82Ì
\83^
\83C
\83g
\83\8b\8eæ
\93¾
2292 LPCTSTR NicoLiveStream_getTitle(NicoLiveStream_P self){
2293 #ifdef PLAYERSTATUS_GET_TITLE
2294 return self->playerStatus.stream.title;
2296 static const LPCTSTR rslt = TEXT("");
2301 BOOL NicoLiveStream_isPremium(NicoLiveStream_P self){
2303 return self->playerStatus.user.is_premium;